diff --git a/Templates/Empty/DeleteCachedDTSs.bat b/Templates/Empty/DeleteCachedDTSs.bat new file mode 100644 index 000000000..8f0dc258e --- /dev/null +++ b/Templates/Empty/DeleteCachedDTSs.bat @@ -0,0 +1 @@ +for /R %%a IN (*.dae) do IF EXIST "%%~pna.cached.dts" del "%%~pna.cached.dts" diff --git a/Templates/Empty/DeleteCachedDTSs.command b/Templates/Empty/DeleteCachedDTSs.command new file mode 100644 index 000000000..f497316e0 --- /dev/null +++ b/Templates/Empty/DeleteCachedDTSs.command @@ -0,0 +1,15 @@ +#!/bin/sh + +cd "`dirname "$0"`" + +for i in $(find . -type f \( -iname "*.dae" \)) +do + len=$((${#i} - 4)) + file=${i:0:$len}.cached.dts + if [ -e $file ] + then + echo "Removing ${file}" + rm $file + fi +done + diff --git a/Templates/Empty/DeleteDSOs.bat b/Templates/Empty/DeleteDSOs.bat new file mode 100644 index 000000000..42228e4b3 --- /dev/null +++ b/Templates/Empty/DeleteDSOs.bat @@ -0,0 +1,6 @@ +for /R %%a IN (*.cs) do IF EXIST "%%a.dso" del "%%a.dso" +for /R %%a IN (*.cs) do IF EXIST "%%a.edso" del "%%a.edso" +for /R %%a IN (*.gui) do IF EXIST "%%a.dso" del "%%a.dso" +for /R %%a IN (*.gui) do IF EXIST "%%a.edso" del "%%a.edso" +for /R %%a IN (*.ts) do IF EXIST "%%a.dso" del "%%a.dso" +for /R %%a IN (*.ts) do IF EXIST "%%a.edso" del "%%a.edso" diff --git a/Templates/Empty/DeleteDSOs.command b/Templates/Empty/DeleteDSOs.command new file mode 100644 index 000000000..f6e805a31 --- /dev/null +++ b/Templates/Empty/DeleteDSOs.command @@ -0,0 +1,19 @@ +#!/bin/sh + +cd "`dirname "$0"`" + +for i in $(find . -type f \( -iname "*.cs" \)) +do + file=${i}.dso + if [ -e $file ] + then + echo "Removing ${file}" + rm $file + fi + file=${i}.edso + if [ -e $file ] + then + echo "Removing ${file}" + rm $file + fi +done diff --git a/Templates/Empty/DeletePrefs.bat b/Templates/Empty/DeletePrefs.bat new file mode 100644 index 000000000..e61988210 --- /dev/null +++ b/Templates/Empty/DeletePrefs.bat @@ -0,0 +1,6 @@ +del /s prefs.cs +del /s config.cs +del /s banlist.cs +del /s config.cs.dso +del /s prefs.cs.dso +del /s banlist.cs.dso diff --git a/Templates/Empty/DeletePrefs.command b/Templates/Empty/DeletePrefs.command new file mode 100644 index 000000000..43961562f --- /dev/null +++ b/Templates/Empty/DeletePrefs.command @@ -0,0 +1,3 @@ +#!/bin/sh + +find "`dirname "$0"`" -type f \( -name "prefs.cs" -or -name "config.cs" -or -name "banlist.cs" -or -name "prefs.cs.dso" -or -name "config.cs.dso" -or -name "banlist.cs.dso" \) -exec rm {} \; diff --git a/Templates/Empty/buildFiles/VisualStudio 2008/projects/Torque.rc b/Templates/Empty/buildFiles/VisualStudio 2008/projects/Torque.rc new file mode 100644 index 000000000..cf88543da --- /dev/null +++ b/Templates/Empty/buildFiles/VisualStudio 2008/projects/Torque.rc @@ -0,0 +1,85 @@ +//Microsoft Developer Studio generated resource script. +// +#define IDI_ICON1 103 +#define IDI_ICON2 107 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 108 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "windows.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON1 ICON DISCARDABLE "torque.ico" +IDI_ICON2 ICON DISCARDABLE "torque.ico" + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""windows.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Templates/Empty/buildFiles/VisualStudio 2008/projects/torque.ico b/Templates/Empty/buildFiles/VisualStudio 2008/projects/torque.ico new file mode 100644 index 000000000..22ac1a3d1 Binary files /dev/null and b/Templates/Empty/buildFiles/VisualStudio 2008/projects/torque.ico differ diff --git a/Templates/Empty/buildFiles/VisualStudio 2010/projects/Torque.Cpp.Win32.user.props b/Templates/Empty/buildFiles/VisualStudio 2010/projects/Torque.Cpp.Win32.user.props new file mode 100644 index 000000000..d659420b0 --- /dev/null +++ b/Templates/Empty/buildFiles/VisualStudio 2010/projects/Torque.Cpp.Win32.user.props @@ -0,0 +1,11 @@ + + + + $(DXSDK_DIR)\Utilities\bin\x86;$(ExecutablePath) + $(DXSDK_DIR)\Include;$(IncludePath) + $(ReferencePath) + $(DXSDK_DIR)\Lib\x86;$(LibraryPath) + $(SourcePath) + $(ExcludePath) + + \ No newline at end of file diff --git a/Templates/Empty/buildFiles/VisualStudio 2010/projects/Torque.Cpp.x64.user.props b/Templates/Empty/buildFiles/VisualStudio 2010/projects/Torque.Cpp.x64.user.props new file mode 100644 index 000000000..12488dc9b --- /dev/null +++ b/Templates/Empty/buildFiles/VisualStudio 2010/projects/Torque.Cpp.x64.user.props @@ -0,0 +1,11 @@ + + + + $(DXSDK_DIR)\Utilities\bin\x64;$(ExecutablePath) + $(DXSDK_DIR)\Include;$(IncludePath) + $(ReferencePath) + $(DXSDK_DIR)\Lib\x64;$(LibraryPath) + $(SourcePath) + $(ExcludePath) + + \ No newline at end of file diff --git a/Templates/Empty/buildFiles/VisualStudio 2010/projects/Torque.rc b/Templates/Empty/buildFiles/VisualStudio 2010/projects/Torque.rc new file mode 100644 index 000000000..cf88543da --- /dev/null +++ b/Templates/Empty/buildFiles/VisualStudio 2010/projects/Torque.rc @@ -0,0 +1,85 @@ +//Microsoft Developer Studio generated resource script. +// +#define IDI_ICON1 103 +#define IDI_ICON2 107 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 108 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "windows.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON1 ICON DISCARDABLE "torque.ico" +IDI_ICON2 ICON DISCARDABLE "torque.ico" + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""windows.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Templates/Empty/buildFiles/VisualStudio 2010/projects/torque.ico b/Templates/Empty/buildFiles/VisualStudio 2010/projects/torque.ico new file mode 100644 index 000000000..22ac1a3d1 Binary files /dev/null and b/Templates/Empty/buildFiles/VisualStudio 2010/projects/torque.ico differ diff --git a/Templates/Empty/buildFiles/Xcode/Info.plist b/Templates/Empty/buildFiles/Xcode/Info.plist new file mode 100644 index 000000000..135c1d94f --- /dev/null +++ b/Templates/Empty/buildFiles/Xcode/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + torqueDemo + CFBundleIdentifier + com.garagegames.${EXECUTABLE_NAME} + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + GG3d + CFBundleVersion + 1.0 + NSMainNibFile + mainMenu + NSPrincipalClass + macApplication + + diff --git a/Templates/Empty/buildFiles/Xcode/torqueDemo.icns b/Templates/Empty/buildFiles/Xcode/torqueDemo.icns new file mode 100644 index 000000000..6695aaf34 Binary files /dev/null and b/Templates/Empty/buildFiles/Xcode/torqueDemo.icns differ diff --git a/Templates/Empty/buildFiles/compile.bat b/Templates/Empty/buildFiles/compile.bat new file mode 100644 index 000000000..3ca519151 --- /dev/null +++ b/Templates/Empty/buildFiles/compile.bat @@ -0,0 +1,67 @@ +@echo off +SETLOCAL + +REM Handle our optional parameters +SET COMPILER=%1 +SET CONFIG=%2 + +IF NOT DEFINED COMPILER SET COMPILER=VS2008 +IF NOT DEFINED CONFIG SET CONFIG=Release + +REM Setting up some variables + +REM Detecting the correct Program Files +IF DEFINED PROGRAMFILES(X86) SET PROGRAMROOT=%ProgramFiles(x86)% +IF NOT DEFINED PROGRAMROOT SET PROGRAMROOT=%ProgramFiles% + +REM First the defaults (set up for VS2008 by default) +SET ENVVAR="%PROGRAMROOT%\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" +SET BUILDCMD=devenv.com +SET OPTIONS=/useenv /build "%CONFIG%|Win32" +SET BUILDDIR="VisualStudio 2008" + +REM Handle the non-defaults +IF %COMPILER% == VS2010 SET ENVVAR="%PROGRAMROOT%\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" + +IF EXIST "%PROGRAMROOT%\Xoreax\IncrediBuild\BuildConsole.exe" SET BUILDCMD="%PROGRAMROOT%\Xoreax\IncrediBuild\BuildConsole.exe" +IF EXIST "%PROGRAMROOT%\Xoreax\IncrediBuild\BuildConsole.exe" SET OPTIONS=/build "%CONFIG%|Win32" + +IF %COMPILER% == VS2010 SET BUILDDIR="VisualStudio 2010" + + +echo Building all solutions under %COMPILER% with the %CONFIG% configuration + +echo Initializing %COMPILER% environment variables... +call %ENVVAR% + +echo Initializing the DirectX SDK environment variables... + +IF "%DXSDK_DIR%" == "" goto error_no_DXSDK_DIR +call "%DXSDK_DIR%Utilities\Bin\dx_setenv.cmd" x86 + +echo Moving to our build directory +cd %BUILDDIR% + +echo - Building +for %%a in (*.sln) do %BUILDCMD% "%%a" %OPTIONS% & IF ERRORLEVEL 1 goto error_compile + +REM It is just polite for a batch file to leave you in the same dir you started in +cd .. + +REM We were successful in everything so go to the end +goto :end + +:error_no_DXSDK_DIR +@echo ERROR: DXSDK_DIR variable is not set. Make sure the DirectX SDK is installed properly. +@goto end_error + +:error_compile +@echo ERROR: There was an error compiling a solution in %CD% +@goto end_error + +:end_error +ENDLOCAL +EXIT /B 1 + +:end +ENDLOCAL diff --git a/Templates/Empty/buildFiles/config/project.conf b/Templates/Empty/buildFiles/config/project.conf new file mode 100644 index 000000000..a03a244d8 --- /dev/null +++ b/Templates/Empty/buildFiles/config/project.conf @@ -0,0 +1,20 @@ + diff --git a/Templates/Empty/buildFiles/config/project.mac.conf b/Templates/Empty/buildFiles/config/project.mac.conf new file mode 100644 index 000000000..e5fe3e501 --- /dev/null +++ b/Templates/Empty/buildFiles/config/project.mac.conf @@ -0,0 +1,16 @@ + diff --git a/Templates/Empty/buildFiles/config/projectCode.conf b/Templates/Empty/buildFiles/config/projectCode.conf new file mode 100644 index 000000000..57348ea8e --- /dev/null +++ b/Templates/Empty/buildFiles/config/projectCode.conf @@ -0,0 +1,12 @@ + \ No newline at end of file diff --git a/Templates/Empty/buildFiles/config/webDeploy.conf b/Templates/Empty/buildFiles/config/webDeploy.conf new file mode 100644 index 000000000..d542271cf --- /dev/null +++ b/Templates/Empty/buildFiles/config/webDeploy.conf @@ -0,0 +1,41 @@ + diff --git a/Templates/Empty/buildFiles/config/webDeploy.mac.conf b/Templates/Empty/buildFiles/config/webDeploy.mac.conf new file mode 100644 index 000000000..f466879e3 --- /dev/null +++ b/Templates/Empty/buildFiles/config/webDeploy.mac.conf @@ -0,0 +1,20 @@ + diff --git a/Templates/Empty/cleanShaders.bat b/Templates/Empty/cleanShaders.bat new file mode 100644 index 000000000..047b30d21 --- /dev/null +++ b/Templates/Empty/cleanShaders.bat @@ -0,0 +1,7 @@ +REM Delete procedural shaders + +del /q /a:-R game\shaders\procedural\*.* + +REM Delete dumped shader disassembly files + +del /q /s /a:-R *_dis.txt \ No newline at end of file diff --git a/Templates/Empty/cleanShaders.command b/Templates/Empty/cleanShaders.command new file mode 100644 index 000000000..93cebdcea --- /dev/null +++ b/Templates/Empty/cleanShaders.command @@ -0,0 +1,4 @@ +#!/bin/sh + +cd "`dirname "$0"`" +rm -rf game/shaders/procedural/*.* diff --git a/Templates/Empty/game/Empty.dll b/Templates/Empty/game/Empty.dll new file mode 100644 index 000000000..64f18b49b Binary files /dev/null and b/Templates/Empty/game/Empty.dll differ diff --git a/Templates/Empty/game/Empty.exe b/Templates/Empty/game/Empty.exe new file mode 100644 index 000000000..c4add5ef0 Binary files /dev/null and b/Templates/Empty/game/Empty.exe differ diff --git a/Templates/Empty/game/Empty.torsion b/Templates/Empty/game/Empty.torsion new file mode 100644 index 000000000..49bb1b7b5 --- /dev/null +++ b/Templates/Empty/game/Empty.torsion @@ -0,0 +1,39 @@ + +Empty + +main.cs +dbgSetParameters( #port#, "#password#", true ); + +core +scripts +art +levels +shaders +tools + +cs; gui + + +Release +Empty.exe + +true +true +true +false + + +Debug +Empty_DEBUG.exe + +false +false +true +false + + + +Empty +HEAD +true + diff --git a/Templates/Empty/game/IE Empty Plugin.dll b/Templates/Empty/game/IE Empty Plugin.dll new file mode 100644 index 000000000..1ce1de44b Binary files /dev/null and b/Templates/Empty/game/IE Empty Plugin.dll differ diff --git a/Templates/Empty/game/NP Empty Plugin.dll b/Templates/Empty/game/NP Empty Plugin.dll new file mode 100644 index 000000000..ac0394092 Binary files /dev/null and b/Templates/Empty/game/NP Empty Plugin.dll differ diff --git a/Templates/Empty/game/art/datablocks/datablockExec.cs b/Templates/Empty/game/art/datablocks/datablockExec.cs new file mode 100644 index 000000000..cbafc7e73 --- /dev/null +++ b/Templates/Empty/game/art/datablocks/datablockExec.cs @@ -0,0 +1,24 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Load up all datablocks. This function is called when +// a server is constructed. diff --git a/Templates/Empty/game/art/datablocks/managedDatablocks.cs b/Templates/Empty/game/art/datablocks/managedDatablocks.cs new file mode 100644 index 000000000..c935f068a --- /dev/null +++ b/Templates/Empty/game/art/datablocks/managedDatablocks.cs @@ -0,0 +1,24 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// This is the default save location for any Datablocks created in the +// Datablock Editor (this script is executed from onServerCreated()) \ No newline at end of file diff --git a/Templates/Empty/game/art/decals/managedDecalData.cs b/Templates/Empty/game/art/decals/managedDecalData.cs new file mode 100644 index 000000000..0f5501c61 --- /dev/null +++ b/Templates/Empty/game/art/decals/managedDecalData.cs @@ -0,0 +1,25 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// This is the default save location for any Decal datablocks created in the +// Decal Editor (this script is executed from onServerCreated()) + diff --git a/Templates/Empty/game/art/gui/StartupGui.gui b/Templates/Empty/game/art/gui/StartupGui.gui new file mode 100644 index 000000000..ad7afcf63 --- /dev/null +++ b/Templates/Empty/game/art/gui/StartupGui.gui @@ -0,0 +1,79 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiFadeinBitmapCtrl(StartupGui) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiInputCtrlProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = ""; + wrap = "0"; + fadeinTime = "1000"; + waitTime = "4000"; + fadeoutTime = "1000"; + done = "1"; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "1"; + internalName = "StartupLogo"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "399 302"; + Extent = "253 253"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = ""; + wrap = "0"; + command = "StartupGui.click();"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "1"; + internalName = "StartupLogoSecondary"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "top"; + position = "275 440"; + Extent = "530 171"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = ""; + wrap = "0"; + command = "StartupGui.click();"; + }; +}; +//--- OBJECT WRITE END --- +//--- OBJECT WRITE BEGIN --- +new GuiFadeinBitmapCtrl(BlankGui) { + profile = "GuiInputCtrlProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "800 600"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + bitmap = ""; + wrap = "0"; + fadeinTime = "100"; + waitTime = "2000"; + fadeoutTime = "100"; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/art/gui/Torque-3D-logo-w.png b/Templates/Empty/game/art/gui/Torque-3D-logo-w.png new file mode 100644 index 000000000..ec197dda3 Binary files /dev/null and b/Templates/Empty/game/art/gui/Torque-3D-logo-w.png differ diff --git a/Templates/Empty/game/art/gui/Torque-3D-logo.png b/Templates/Empty/game/art/gui/Torque-3D-logo.png new file mode 100644 index 000000000..2b8d32e43 Binary files /dev/null and b/Templates/Empty/game/art/gui/Torque-3D-logo.png differ diff --git a/Templates/Empty/game/art/gui/Torque-3D-logo_alt.png b/Templates/Empty/game/art/gui/Torque-3D-logo_alt.png new file mode 100644 index 000000000..3836f1e7f Binary files /dev/null and b/Templates/Empty/game/art/gui/Torque-3D-logo_alt.png differ diff --git a/Templates/Empty/game/art/gui/background.png b/Templates/Empty/game/art/gui/background.png new file mode 100644 index 000000000..9444659f3 Binary files /dev/null and b/Templates/Empty/game/art/gui/background.png differ diff --git a/Templates/Empty/game/art/gui/gameProfiles.cs b/Templates/Empty/game/art/gui/gameProfiles.cs new file mode 100644 index 000000000..02fd14721 --- /dev/null +++ b/Templates/Empty/game/art/gui/gameProfiles.cs @@ -0,0 +1,25 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Game specific profiles are located here +//----------------------------------------------------------------------------- \ No newline at end of file diff --git a/Templates/Empty/game/art/gui/hudfill.png b/Templates/Empty/game/art/gui/hudfill.png new file mode 100644 index 000000000..e435854d2 Binary files /dev/null and b/Templates/Empty/game/art/gui/hudfill.png differ diff --git a/Templates/Empty/game/art/gui/mainMenuGui.gui b/Templates/Empty/game/art/gui/mainMenuGui.gui new file mode 100644 index 000000000..a0e3c7e13 --- /dev/null +++ b/Templates/Empty/game/art/gui/mainMenuGui.gui @@ -0,0 +1,130 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiChunkedBitmapCtrl(MainMenuGui) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiContentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = "art/gui/background"; + useVariable = "0"; + tile = "0"; + + new GuiBitmapCtrl(MainMenuAppLogo) { + canSaveDynamicFields = "1"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "540 30"; + Extent = "443 139"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = "art/gui/Torque-3D-logo.png"; + wrap = "0"; + }; + new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "center"; + VertSizing = "center"; + Position = "359 171"; + Extent = "306 425"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiMenuButtonProfile"; + HorizSizing = "relative"; + VertSizing = "bottom"; + Position = "9 114"; + Extent = "289 75"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "Canvas.pushDialog(ChooseLevelDlg);"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Play"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiMenuButtonProfile"; + HorizSizing = "relative"; + VertSizing = "bottom"; + Position = "9 190"; + Extent = "289 75"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "Canvas.pushDialog(optionsDlg);"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Options"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + internalName = "ExitButton"; + isContainer = "0"; + Profile = "GuiMenuButtonProfile"; + HorizSizing = "relative"; + VertSizing = "bottom"; + Position = "9 267"; + Extent = "289 75"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "quit();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Exit"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + +function MainMenuGui::onWake(%this) +{ + if (isFunction("getWebDeployment") && + getWebDeployment() && + isObject(%this-->ExitButton)) + %this-->ExitButton.setVisible(false); +} \ No newline at end of file diff --git a/Templates/Empty/game/art/gui/playGui.gui b/Templates/Empty/game/art/gui/playGui.gui new file mode 100644 index 000000000..42238996d --- /dev/null +++ b/Templates/Empty/game/art/gui/playGui.gui @@ -0,0 +1,98 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GameTSCtrl(PlayGui) { + canSaveDynamicFields = "1"; + isContainer = "1"; + Profile = "GuiContentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + cameraZRot = "0"; + forceFOV = "0"; + Enabled = "1"; + helpTag = "0"; + noCursor = "1"; + + new GuiBitmapCtrl(CenterPrintDlg) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "CenterPrintProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "237 375"; + Extent = "550 20"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = "art/gui/hudfill.png"; + wrap = "0"; + + new GuiMLTextCtrl(CenterPrintText) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "CenterPrintTextProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "0 0"; + Extent = "546 12"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + }; + }; + new GuiBitmapCtrl(BottomPrintDlg) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "CenterPrintProfile"; + HorizSizing = "center"; + VertSizing = "top"; + position = "237 719"; + Extent = "550 20"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = "art/gui/hudfill.png"; + wrap = "0"; + + new GuiMLTextCtrl(BottomPrintText) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "CenterPrintTextProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "0 0"; + Extent = "546 12"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/art/gui/splash.bmp b/Templates/Empty/game/art/gui/splash.bmp new file mode 100644 index 000000000..47cb47f97 Binary files /dev/null and b/Templates/Empty/game/art/gui/splash.bmp differ diff --git a/Templates/Empty/game/art/main.cs b/Templates/Empty/game/art/main.cs new file mode 100644 index 000000000..509b0f0c0 --- /dev/null +++ b/Templates/Empty/game/art/main.cs @@ -0,0 +1,21 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- diff --git a/Templates/Empty/game/art/shapes/particles/managedParticleData.cs b/Templates/Empty/game/art/shapes/particles/managedParticleData.cs new file mode 100644 index 000000000..10ecb64a9 --- /dev/null +++ b/Templates/Empty/game/art/shapes/particles/managedParticleData.cs @@ -0,0 +1,24 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// This is the default save location for any Particle datablocks created in the +// Particle Editor (this script is executed from onServerCreated()) diff --git a/Templates/Empty/game/art/shapes/particles/managedParticleEmitterData.cs b/Templates/Empty/game/art/shapes/particles/managedParticleEmitterData.cs new file mode 100644 index 000000000..68ac4104a --- /dev/null +++ b/Templates/Empty/game/art/shapes/particles/managedParticleEmitterData.cs @@ -0,0 +1,24 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// This is the default save location for any Particle Emitter datablocks created in the +// Particle Editor (this script is executed from onServerCreated()) diff --git a/Templates/Empty/game/art/skies/.gitignore b/Templates/Empty/game/art/skies/.gitignore new file mode 100644 index 000000000..1bc0e838a --- /dev/null +++ b/Templates/Empty/game/art/skies/.gitignore @@ -0,0 +1 @@ +# Keep directory in git repo diff --git a/Templates/Empty/game/art/terrains/materials.cs b/Templates/Empty/game/art/terrains/materials.cs new file mode 100644 index 000000000..e99d2e537 --- /dev/null +++ b/Templates/Empty/game/art/terrains/materials.cs @@ -0,0 +1,22 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + diff --git a/Templates/Empty/game/core/art/datablocks/camera.cs b/Templates/Empty/game/core/art/datablocks/camera.cs new file mode 100644 index 000000000..06da4391e --- /dev/null +++ b/Templates/Empty/game/core/art/datablocks/camera.cs @@ -0,0 +1,30 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Define a datablock class to use for our observer camera +//----------------------------------------------------------------------------- + +datablock CameraData(Observer) +{ + mode = "Observer"; +}; \ No newline at end of file diff --git a/Templates/Empty/game/core/art/datablocks/datablockExec.cs b/Templates/Empty/game/core/art/datablocks/datablockExec.cs new file mode 100644 index 000000000..da4a98989 --- /dev/null +++ b/Templates/Empty/game/core/art/datablocks/datablockExec.cs @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Load up all datablocks. This function is called when +// a server is constructed. + +// Set up the Camera's +exec("./camera.cs"); + +// Common Marker's +exec("./markers.cs"); + +exec("./defaultparticle.cs"); + +// LightFlareData and LightAnimData(s) +exec("./lights.cs"); \ No newline at end of file diff --git a/Templates/Empty/game/core/art/datablocks/defaultparticle.cs b/Templates/Empty/game/core/art/datablocks/defaultparticle.cs new file mode 100644 index 000000000..017d30648 --- /dev/null +++ b/Templates/Empty/game/core/art/datablocks/defaultparticle.cs @@ -0,0 +1,66 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +datablock ParticleData(DefaultParticle) +{ + textureName = "core/art/defaultParticle"; + dragCoefficient = 0.498534; + gravityCoefficient = 0; + inheritedVelFactor = 0.499022; + constantAcceleration = 0.0; + lifetimeMS = 1313; + lifetimeVarianceMS = 500; + useInvAlpha = true; + spinRandomMin = -360; + spinRandomMax = 360; + spinSpeed = 1; + + colors[0] = "0.992126 0.00787402 0.0314961 1"; + colors[1] = "1 0.834646 0 0.645669"; + colors[2] = "1 0.299213 0 0.330709"; + colors[3] = "0.732283 1 0 0"; + + sizes[0] = 0; + sizes[1] = 0.497467; + sizes[2] = 0.73857; + sizes[3] = 0.997986; + + times[0] = 0.0; + times[1] = 0.247059; + times[2] = 0.494118; + times[3] = 1; + + animTexName = "core/art/defaultParticle"; +}; + +datablock ParticleEmitterData(DefaultEmitter) +{ + ejectionPeriodMS = "50"; + ejectionVelocity = "1"; + velocityVariance = "0"; + ejectionOffset = "0.2"; + thetaMax = "40"; + particles = "DefaultParticle"; + blendStyle = "ADDITIVE"; + softParticles = "0"; + softnessDistance = "1000"; +}; diff --git a/Templates/Empty/game/core/art/datablocks/lights.cs b/Templates/Empty/game/core/art/datablocks/lights.cs new file mode 100644 index 000000000..005aec0ca --- /dev/null +++ b/Templates/Empty/game/core/art/datablocks/lights.cs @@ -0,0 +1,608 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +//------------------------------------------------------------------------------ +// LightAnimData +//------------------------------------------------------------------------------ + +datablock LightAnimData( NullLightAnim ) +{ + animEnabled = false; +}; + +datablock LightAnimData( PulseLightAnim ) +{ + brightnessA = 0; + brightnessZ = 1; + brightnessPeriod = 1; + brightnessKeys = "aza"; + brightnessSmooth = true; +}; + +datablock LightAnimData( SubtlePulseLightAnim ) +{ + brightnessA = 0.5; + brightnessZ = 1; + brightnessPeriod = 1; + brightnessKeys = "aza"; + brightnessSmooth = true; +}; + +datablock LightAnimData( FlickerLightAnim ) +{ + brightnessA = 1; + brightnessZ = 0; + brightnessPeriod = 5; + brightnessKeys = "aaazaaaaaazaaazaaazaaaaazaaaazzaaaazaaaaaazaaaazaaaza"; + brightnessSmooth = false; +}; + +datablock LightAnimData( BlinkLightAnim ) +{ + brightnessA = 0; + brightnessZ = 1; + brightnessPeriod = 5; + brightnessKeys = "azaaaazazaaaaaazaaaazaaaazzaaaaaazaazaaazaaaaaaa"; + brightnessSmooth = false; +}; + +datablock LightAnimData( FireLightAnim ) +{ + brightnessA = 0.75; + brightnessZ = 1; + brightnessPeriod = 0.7; + brightnessKeys = "annzzznnnzzzaznzzzz"; + brightnessSmooth = 0; + offsetA[0] = "-0.05"; + offsetA[1] = "-0.05"; + offsetA[2] = "-0.05"; + offsetZ[0] = "0.05"; + offsetZ[1] = "0.05"; + offsetZ[2] = "0.05"; + offsetPeriod[0] = "1.25"; + offsetPeriod[1] = "1.25"; + offsetPeriod[2] = "1.25"; + offsetKeys[0] = "ahahaazahakayajza"; + offsetKeys[1] = "ahahaazahakayajza"; + offsetKeys[2] = "ahahaazahakayajza"; + rotKeys[0] = ""; + rotKeys[1] = ""; + rotKeys[2] = ""; + colorKeys[0] = ""; + colorKeys[1] = ""; + colorKeys[2] = ""; +}; + +datablock LightAnimData( SpinLightAnim ) +{ + rotA[2] = "0"; + rotZ[2] = "360"; + rotPeriod[2] = "1"; + rotKeys[2] = "az"; + rotSmooth[2] = true; +}; + + +//------------------------------------------------------------------------------ +// LightFlareData +//------------------------------------------------------------------------------ + +datablock LightFlareData( NullLightFlare ) +{ + flareEnabled = false; +}; + +datablock LightFlareData( SunFlareExample ) +{ + overallScale = 4.0; + flareEnabled = true; + renderReflectPass = false; + flareTexture = "./../special/lensFlareSheet0"; + + elementRect[0] = "512 0 512 512"; + elementDist[0] = 0.0; + elementScale[0] = 2.0; + elementTint[0] = "0.6 0.6 0.6"; + elementRotate[0] = true; + elementUseLightColor[0] = true; + + elementRect[1] = "1152 0 128 128"; + elementDist[1] = 0.3; + elementScale[1] = 0.7; + elementTint[1] = "1.0 1.0 1.0"; + elementRotate[1] = true; + elementUseLightColor[1] = true; + + elementRect[2] = "1024 0 128 128"; + elementDist[2] = 0.5; + elementScale[2] = 0.25; + elementTint[2] = "1.0 1.0 1.0"; + elementRotate[2] = true; + elementUseLightColor[2] = true; + + elementRect[3] = "1024 128 128 128"; + elementDist[3] = 0.8; + elementScale[3] = 0.7; + elementTint[3] = "1.0 1.0 1.0"; + elementRotate[3] = true; + elementUseLightColor[3] = true; + + elementRect[4] = "1024 0 128 128"; + elementDist[4] = 1.18; + elementScale[4] = 0.5; + elementTint[4] = "1.0 1.0 1.0"; + elementRotate[4] = true; + elementUseLightColor[4] = true; + + elementRect[5] = "1152 128 128 128"; + elementDist[5] = 1.25; + elementScale[5] = 0.25; + elementTint[5] = "1.0 1.0 1.0"; + elementRotate[5] = true; + elementUseLightColor[5] = true; + + elementRect[6] = "1024 0 128 128"; + elementDist[6] = 2.0; + elementScale[6] = 0.25; + elementTint[6] = "1.0 1.0 1.0"; + elementRotate[6] = true; + elementUseLightColor[6] = true; + occlusionRadius = "0.25"; +}; + +datablock LightFlareData( SunFlareExample2 ) +{ + overallScale = 2.0; + flareEnabled = true; + renderReflectPass = false; + flareTexture = "./../special/lensFlareSheet0"; + + elementRect[0] = "1024 0 128 128"; + elementDist[0] = 0.5; + elementScale[0] = 0.25; + elementTint[0] = "1.0 1.0 1.0"; + elementRotate[0] = true; + elementUseLightColor[0] = true; + + elementRect[1] = "1024 128 128 128"; + elementDist[1] = 0.8; + elementScale[1] = 0.7; + elementTint[1] = "1.0 1.0 1.0"; + elementRotate[1] = true; + elementUseLightColor[1] = true; + + elementRect[2] = "1024 0 128 128"; + elementDist[2] = 1.18; + elementScale[2] = 0.5; + elementTint[2] = "1.0 1.0 1.0"; + elementRotate[2] = true; + elementUseLightColor[2] = true; + + elementRect[3] = "1152 128 128 128"; + elementDist[3] = 1.25; + elementScale[3] = 0.25; + elementTint[3] = "1.0 1.0 1.0"; + elementRotate[3] = true; + elementUseLightColor[3] = true; + + elementRect[4] = "1024 0 128 128"; + elementDist[4] = 2.0; + elementScale[4] = 0.25; + elementTint[4] = "0.7 0.7 0.7"; + elementRotate[4] = true; + elementUseLightColor[4] = true; + occlusionRadius = "0.25"; +}; + +datablock LightFlareData(SunFlareExample3) +{ + overallScale = 2.0; + flareEnabled = true; + renderReflectPass = false; + flareTexture = "core/art/special/lensflareSheet3.png"; + + elementRect[0] = "0 256 256 256"; + elementDist[0] = "-0.6"; + elementScale[0] = "3.5"; + elementTint[0] = "0.537255 0.537255 0.537255 1"; + elementRotate[0] = true; + elementUseLightColor[0] = true; + + elementRect[1] = "128 128 128 128"; + elementDist[1] = "0.1"; + elementScale[1] = "1.5"; + elementTint[1] = "0.996078 0.976471 0.721569 1"; + elementRotate[1] = true; + elementUseLightColor[1] = true; + + elementRect[2] = "0 0 64 64"; + elementDist[2] = "0.4"; + elementScale[2] = "0.25"; + elementTint[2] = "0 0 1 1"; + elementRotate[2] = true; + elementUseLightColor[2] = true; + + elementRect[3] = "0 0 64 64"; + elementDist[3] = "0.45"; + elementScale[3] = 0.25; + elementTint[3] = "0 1 0 1"; + elementRotate[3] = true; + elementUseLightColor[3] = true; + + elementRect[4] = "0 0 64 64"; + elementDist[4] = "0.5"; + elementScale[4] = 0.25; + elementTint[4] = "1 0 0 1"; + elementRotate[4] = true; + elementUseLightColor[4] = true; + elementRect[9] = "256 0 256 256"; + elementDist[3] = "0.45"; + elementScale[3] = "0.25"; + elementScale[9] = "2"; + elementRect[4] = "0 0 64 64"; + elementRect[5] = "128 0 128 128"; + elementDist[4] = "0.5"; + elementDist[5] = "1.2"; + elementScale[1] = "1.5"; + elementScale[4] = "0.25"; + elementScale[5] = "0.5"; + elementTint[1] = "0.996078 0.976471 0.721569 1"; + elementTint[2] = "0 0 1 1"; + elementTint[5] = "0.721569 0 1 1"; + elementRotate[5] = "0"; + elementUseLightColor[5] = "1"; + elementRect[0] = "0 256 256 256"; + elementRect[1] = "128 128 128 128"; + elementRect[2] = "0 0 64 64"; + elementRect[3] = "0 0 64 64"; + elementDist[0] = "-0.6"; + elementDist[1] = "0.1"; + elementDist[2] = "0.4"; + elementScale[0] = "3.5"; + elementScale[2] = "0.25"; + elementTint[0] = "0.537255 0.537255 0.537255 1"; + elementTint[3] = "0 1 0 1"; + elementTint[4] = "1 0 0 1"; + elementRect[6] = "64 64 64 64"; + elementDist[6] = "0.9"; + elementScale[6] = "4"; + elementTint[6] = "0.00392157 0.721569 0.00392157 1"; + elementRotate[6] = "0"; + elementUseLightColor[6] = "1"; + elementRect[7] = "64 64 64 64"; + elementRect[8] = "64 64 64 64"; + elementDist[7] = "0.25"; + elementDist[8] = "0.18"; + elementDist[9] = "0"; + elementScale[7] = "2"; + elementScale[8] = "0.5"; + elementTint[7] = "0.6 0.0117647 0.741176 1"; + elementTint[8] = "0.027451 0.690196 0.0117647 1"; + elementTint[9] = "0.647059 0.647059 0.647059 1"; + elementRotate[9] = "0"; + elementUseLightColor[7] = "1"; + elementUseLightColor[8] = "1"; + elementRect[10] = "256 256 256 256"; + elementRect[11] = "0 64 64 64"; + elementRect[12] = "0 64 64 64"; + elementRect[13] = "64 0 64 64"; + elementDist[10] = "0"; + elementDist[11] = "-0.3"; + elementDist[12] = "-0.32"; + elementDist[13] = "1"; + elementScale[10] = "10"; + elementScale[11] = "2.5"; + elementScale[12] = "0.3"; + elementScale[13] = "0.4"; + elementTint[10] = "0.321569 0.321569 0.321569 1"; + elementTint[11] = "0.443137 0.0431373 0.00784314 1"; + elementTint[12] = "0.00784314 0.996078 0.0313726 1"; + elementTint[13] = "0.996078 0.94902 0.00784314 1"; + elementUseLightColor[10] = "1"; + elementUseLightColor[11] = "1"; + elementUseLightColor[13] = "1"; + elementRect[14] = "0 0 64 64"; + elementDist[14] = "0.15"; + elementScale[14] = "0.8"; + elementTint[14] = "0.505882 0.0470588 0.00784314 1"; + elementRotate[14] = "1"; + elementUseLightColor[9] = "1"; + elementUseLightColor[14] = "1"; + elementRect[15] = "64 64 64 64"; + elementRect[16] = "0 64 64 64"; + elementRect[17] = "0 0 64 64"; + elementRect[18] = "0 64 64 64"; + elementRect[19] = "256 0 256 256"; + elementDist[15] = "0.8"; + elementDist[16] = "0.7"; + elementDist[17] = "1.4"; + elementDist[18] = "-0.5"; + elementDist[19] = "-1.5"; + elementScale[15] = "3"; + elementScale[16] = "0.3"; + elementScale[17] = "0.2"; + elementScale[18] = "1"; + elementScale[19] = "35"; + elementTint[15] = "0.00784314 0.00784314 0.996078 1"; + elementTint[16] = "0.992157 0.992157 0.992157 1"; + elementTint[17] = "0.996078 0.603922 0.00784314 1"; + elementTint[18] = "0.2 0.00392157 0.47451 1"; + elementTint[19] = "0.607843 0.607843 0.607843 1"; + elementUseLightColor[15] = "1"; + elementUseLightColor[18] = "1"; + elementUseLightColor[19] = "1"; + occlusionRadius = "0.25"; +}; + + + +datablock LightFlareData(SunFlarePacificIsland) +{ + overallScale = 2.0; + flareEnabled = true; + renderReflectPass = false; + flareTexture = "art/special/lensflareSheet3.png"; + + elementRect[0] = "0 256 256 256"; + elementDist[0] = "-0.6"; + elementScale[0] = "3.5"; + elementTint[0] = "0.537255 0.537255 0.537255 1"; + elementRotate[0] = true; + elementUseLightColor[0] = true; + + elementRect[1] = "128 128 128 128"; + elementDist[1] = "0.1"; + elementScale[1] = "1.5"; + elementTint[1] = "0.996078 0.976471 0.721569 1"; + elementRotate[1] = true; + elementUseLightColor[1] = true; + + elementRect[2] = "0 0 64 64"; + elementDist[2] = "0.4"; + elementScale[2] = "0.25"; + elementTint[2] = "0 0 1 1"; + elementRotate[2] = true; + elementUseLightColor[2] = true; + + elementRect[3] = "0 0 64 64"; + elementDist[3] = "0.45"; + elementScale[3] = 0.25; + elementTint[3] = "0 1 0 1"; + elementRotate[3] = true; + elementUseLightColor[3] = true; + + elementRect[4] = "0 0 64 64"; + elementDist[4] = "0.5"; + elementScale[4] = 0.25; + elementTint[4] = "1 0 0 1"; + elementRotate[4] = true; + elementUseLightColor[4] = true; + elementRect[9] = "256 0 256 256"; + elementDist[3] = "0.45"; + elementScale[3] = "0.25"; + elementScale[9] = "2"; + elementRect[4] = "0 0 64 64"; + elementRect[5] = "128 0 128 128"; + elementDist[4] = "0.5"; + elementDist[5] = "1.2"; + elementScale[1] = "1.5"; + elementScale[4] = "0.25"; + elementScale[5] = "0.5"; + elementTint[1] = "0.996078 0.976471 0.721569 1"; + elementTint[2] = "0 0 1 1"; + elementTint[5] = "0.721569 0 1 1"; + elementRotate[5] = "0"; + elementUseLightColor[5] = "1"; + elementRect[0] = "0 256 256 256"; + elementRect[1] = "128 128 128 128"; + elementRect[2] = "0 0 64 64"; + elementRect[3] = "0 0 64 64"; + elementDist[0] = "-0.6"; + elementDist[1] = "0.1"; + elementDist[2] = "0.4"; + elementScale[0] = "3.5"; + elementScale[2] = "0.25"; + elementTint[0] = "0.537255 0.537255 0.537255 1"; + elementTint[3] = "0 1 0 1"; + elementTint[4] = "1 0 0 1"; + elementRect[6] = "64 64 64 64"; + elementDist[6] = "0.9"; + elementScale[6] = "4"; + elementTint[6] = "0.00392157 0.721569 0.00392157 1"; + elementRotate[6] = "0"; + elementUseLightColor[6] = "1"; + elementRect[7] = "64 64 64 64"; + elementRect[8] = "64 64 64 64"; + elementDist[7] = "0.25"; + elementDist[8] = "0.18"; + elementDist[9] = "0"; + elementScale[7] = "2"; + elementScale[8] = "0.5"; + elementTint[7] = "0.6 0.0117647 0.741176 1"; + elementTint[8] = "0.027451 0.690196 0.0117647 1"; + elementTint[9] = "0.647059 0.647059 0.647059 1"; + elementRotate[9] = "0"; + elementUseLightColor[7] = "1"; + elementUseLightColor[8] = "1"; + elementRect[10] = "256 256 256 256"; + elementRect[11] = "0 64 64 64"; + elementRect[12] = "0 64 64 64"; + elementRect[13] = "64 0 64 64"; + elementDist[10] = "0"; + elementDist[11] = "-0.3"; + elementDist[12] = "-0.32"; + elementDist[13] = "1"; + elementScale[10] = "10"; + elementScale[11] = "2.5"; + elementScale[12] = "0.3"; + elementScale[13] = "0.4"; + elementTint[10] = "0.321569 0.321569 0.321569 1"; + elementTint[11] = "0.443137 0.0431373 0.00784314 1"; + elementTint[12] = "0.00784314 0.996078 0.0313726 1"; + elementTint[13] = "0.996078 0.94902 0.00784314 1"; + elementUseLightColor[10] = "1"; + elementUseLightColor[11] = "1"; + elementUseLightColor[13] = "1"; + elementRect[14] = "0 0 64 64"; + elementDist[14] = "0.15"; + elementScale[14] = "0.8"; + elementTint[14] = "0.505882 0.0470588 0.00784314 1"; + elementRotate[14] = "1"; + elementUseLightColor[9] = "1"; + elementUseLightColor[14] = "1"; + elementRect[15] = "64 64 64 64"; + elementRect[16] = "0 64 64 64"; + elementRect[17] = "0 0 64 64"; + elementRect[18] = "0 64 64 64"; + elementRect[19] = "256 0 256 256"; + elementDist[15] = "0.8"; + elementDist[16] = "0.7"; + elementDist[17] = "1.4"; + elementDist[18] = "-0.5"; + elementDist[19] = "-1.5"; + elementScale[15] = "3"; + elementScale[16] = "0.3"; + elementScale[17] = "0.2"; + elementScale[18] = "1"; + elementScale[19] = "35"; + elementTint[15] = "0.00784314 0.00784314 0.996078 1"; + elementTint[16] = "0.992157 0.992157 0.992157 1"; + elementTint[17] = "0.996078 0.603922 0.00784314 1"; + elementTint[18] = "0.2 0.00392157 0.47451 1"; + elementTint[19] = "0.607843 0.607843 0.607843 1"; + elementUseLightColor[15] = "1"; + elementUseLightColor[18] = "1"; + elementUseLightColor[19] = "1"; +}; + + + +datablock LightFlareData( LightFlareExample0 ) +{ + overallScale = 2.0; + flareEnabled = true; + renderReflectPass = true; + flareTexture = "./../special/lensFlareSheet1"; + + elementRect[0] = "0 512 512 512"; + elementDist[0] = 0.0; + elementScale[0] = 0.5; + elementTint[0] = "1.0 1.0 1.0"; + elementRotate[0] = false; + elementUseLightColor[0] = false; + + elementRect[1] = "512 0 512 512"; + elementDist[1] = 0.0; + elementScale[1] = 2.0; + elementTint[1] = "0.5 0.5 0.5"; + elementRotate[1] = false; + elementUseLightColor[1] = false; + occlusionRadius = "0.25"; +}; + +datablock LightFlareData( LightFlareExample1 ) +{ + overallScale = 2.0; + flareEnabled = true; + renderReflectPass = true; + flareTexture = "./../special/lensFlareSheet1"; + + elementRect[0] = "512 512 512 512"; + elementDist[0] = 0.0; + elementScale[0] = 0.5; + elementTint[0] = "1.0 1.0 1.0"; + elementRotate[0] = false; + elementUseLightColor[0] = false; + + elementRect[1] = "512 0 512 512"; + elementDist[1] = 0.0; + elementScale[1] = 2.0; + elementTint[1] = "0.5 0.5 0.5"; + elementRotate[1] = false; + elementUseLightColor[1] = false; + occlusionRadius = "0.25"; +}; + +datablock LightFlareData( LightFlareExample2 ) +{ + overallScale = 2.0; + flareEnabled = true; + renderReflectPass = true; + flareTexture = "./../special/lensFlareSheet0"; + + elementRect[0] = "512 512 512 512"; + elementDist[0] = 0.0; + elementScale[0] = 0.5; + elementTint[0] = "1.0 1.0 1.0"; + elementRotate[0] = true; + elementUseLightColor[0] = true; + + elementRect[1] = "512 0 512 512"; + elementDist[1] = 0.0; + elementScale[1] = 2.0; + elementTint[1] = "0.7 0.7 0.7"; + elementRotate[1] = true; + elementUseLightColor[1] = true; + + elementRect[2] = "1152 0 128 128"; + elementDist[2] = 0.3; + elementScale[2] = 0.5; + elementTint[2] = "1.0 1.0 1.0"; + elementRotate[2] = true; + elementUseLightColor[2] = true; + + elementRect[3] = "1024 0 128 128"; + elementDist[3] = 0.5; + elementScale[3] = 0.25; + elementTint[3] = "1.0 1.0 1.0"; + elementRotate[3] = true; + elementUseLightColor[3] = true; + + elementRect[4] = "1024 128 128 128"; + elementDist[4] = 0.8; + elementScale[4] = 0.6; + elementTint[4] = "1.0 1.0 1.0"; + elementRotate[4] = true; + elementUseLightColor[4] = true; + + elementRect[5] = "1024 0 128 128"; + elementDist[5] = 1.18; + elementScale[5] = 0.5; + elementTint[5] = "0.7 0.7 0.7"; + elementRotate[5] = true; + elementUseLightColor[5] = true; + + elementRect[6] = "1152 128 128 128"; + elementDist[6] = 1.25; + elementScale[6] = 0.35; + elementTint[6] = "0.8 0.8 0.8"; + elementRotate[6] = true; + elementUseLightColor[6] = true; + + elementRect[7] = "1024 0 128 128"; + elementDist[7] = 2.0; + elementScale[7] = 0.25; + elementTint[7] = "1.0 1.0 1.0"; + elementRotate[7] = true; + elementUseLightColor[7] = true; +}; diff --git a/Templates/Empty/game/core/art/datablocks/markers.cs b/Templates/Empty/game/core/art/datablocks/markers.cs new file mode 100644 index 000000000..04ea6af48 --- /dev/null +++ b/Templates/Empty/game/core/art/datablocks/markers.cs @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +datablock MissionMarkerData(WayPointMarker) +{ + category = "Misc"; + shapeFile = "core/art/shapes/octahedron.dts"; +}; + +datablock MissionMarkerData(SpawnSphereMarker) +{ + category = "Misc"; + shapeFile = "core/art/shapes/octahedron.dts"; +}; + +datablock MissionMarkerData(CameraBookmarkMarker) +{ + category = "Misc"; + shapeFile = "core/art/shapes/camera.dts"; +}; diff --git a/Templates/Empty/game/core/art/defaultParticle.png b/Templates/Empty/game/core/art/defaultParticle.png new file mode 100644 index 000000000..cb899f84d Binary files /dev/null and b/Templates/Empty/game/core/art/defaultParticle.png differ diff --git a/Templates/Empty/game/core/art/defaultRoadTextureOther.png b/Templates/Empty/game/core/art/defaultRoadTextureOther.png new file mode 100644 index 000000000..a2f08fe6a Binary files /dev/null and b/Templates/Empty/game/core/art/defaultRoadTextureOther.png differ diff --git a/Templates/Empty/game/core/art/defaultRoadTextureTop.png b/Templates/Empty/game/core/art/defaultRoadTextureTop.png new file mode 100644 index 000000000..17e69adcf Binary files /dev/null and b/Templates/Empty/game/core/art/defaultRoadTextureTop.png differ diff --git a/Templates/Empty/game/core/art/defaultpath.png b/Templates/Empty/game/core/art/defaultpath.png new file mode 100644 index 000000000..2f08509c2 Binary files /dev/null and b/Templates/Empty/game/core/art/defaultpath.png differ diff --git a/Templates/Empty/game/core/art/defaultpath_normal.png b/Templates/Empty/game/core/art/defaultpath_normal.png new file mode 100644 index 000000000..3122dbe41 Binary files /dev/null and b/Templates/Empty/game/core/art/defaultpath_normal.png differ diff --git a/Templates/Empty/game/core/art/fizz_noise.dds b/Templates/Empty/game/core/art/fizz_noise.dds new file mode 100644 index 000000000..2cb6cee10 Binary files /dev/null and b/Templates/Empty/game/core/art/fizz_noise.dds differ diff --git a/Templates/Empty/game/core/art/grids/512_black.png b/Templates/Empty/game/core/art/grids/512_black.png new file mode 100644 index 000000000..5e57c16c2 Binary files /dev/null and b/Templates/Empty/game/core/art/grids/512_black.png differ diff --git a/Templates/Empty/game/core/art/grids/512_blue.png b/Templates/Empty/game/core/art/grids/512_blue.png new file mode 100644 index 000000000..2511284dd Binary files /dev/null and b/Templates/Empty/game/core/art/grids/512_blue.png differ diff --git a/Templates/Empty/game/core/art/grids/512_forestgreen.png b/Templates/Empty/game/core/art/grids/512_forestgreen.png new file mode 100644 index 000000000..179831bea Binary files /dev/null and b/Templates/Empty/game/core/art/grids/512_forestgreen.png differ diff --git a/Templates/Empty/game/core/art/grids/512_forestgreen_lines.png b/Templates/Empty/game/core/art/grids/512_forestgreen_lines.png new file mode 100644 index 000000000..4a09fc4a1 Binary files /dev/null and b/Templates/Empty/game/core/art/grids/512_forestgreen_lines.png differ diff --git a/Templates/Empty/game/core/art/grids/512_green.png b/Templates/Empty/game/core/art/grids/512_green.png new file mode 100644 index 000000000..d2cbde68e Binary files /dev/null and b/Templates/Empty/game/core/art/grids/512_green.png differ diff --git a/Templates/Empty/game/core/art/grids/512_grey.png b/Templates/Empty/game/core/art/grids/512_grey.png new file mode 100644 index 000000000..c4b574c76 Binary files /dev/null and b/Templates/Empty/game/core/art/grids/512_grey.png differ diff --git a/Templates/Empty/game/core/art/grids/512_grey_base.png b/Templates/Empty/game/core/art/grids/512_grey_base.png new file mode 100644 index 000000000..a1e440f29 Binary files /dev/null and b/Templates/Empty/game/core/art/grids/512_grey_base.png differ diff --git a/Templates/Empty/game/core/art/grids/512_orange.png b/Templates/Empty/game/core/art/grids/512_orange.png new file mode 100644 index 000000000..43c4953e8 Binary files /dev/null and b/Templates/Empty/game/core/art/grids/512_orange.png differ diff --git a/Templates/Empty/game/core/art/grids/512_orange_lines.png b/Templates/Empty/game/core/art/grids/512_orange_lines.png new file mode 100644 index 000000000..51813d98c Binary files /dev/null and b/Templates/Empty/game/core/art/grids/512_orange_lines.png differ diff --git a/Templates/Empty/game/core/art/grids/512_red.png b/Templates/Empty/game/core/art/grids/512_red.png new file mode 100644 index 000000000..a9f95638a Binary files /dev/null and b/Templates/Empty/game/core/art/grids/512_red.png differ diff --git a/Templates/Empty/game/core/art/grids/materials.cs b/Templates/Empty/game/core/art/grids/materials.cs new file mode 100644 index 000000000..ea05af987 --- /dev/null +++ b/Templates/Empty/game/core/art/grids/materials.cs @@ -0,0 +1,91 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +singleton Material( Grid512_Black_Mat ) +{ + mapTo = "Grid512_Black_Mat"; + diffuseMap[0] = "512_black"; + materialTag0 = "TestMaterial"; +}; + +singleton Material( Grid512_Blue_Mat ) +{ + mapTo = "Grid512_Blue_Mat"; + diffuseMap[0] = "512_blue"; + materialTag0 = "TestMaterial"; +}; + +singleton Material( Grid512_ForestGreen_Mat ) +{ + mapTo = "Grid512_ForestGreen_Mat"; + diffuseMap[0] = "512_forestgreen"; + materialTag0 = "TestMaterial"; +}; + +singleton Material( Grid512_ForestGreenLines_Mat ) +{ + mapTo = "Grid512_ForestGreenLines_Mat"; + diffuseMap[0] = "512_forestgreen_lines"; + materialTag0 = "TestMaterial"; +}; + +singleton Material( Grid512_Green_Mat ) +{ + mapTo = "Grid512_Green_Mat"; + diffuseMap[0] = "512_green"; + materialTag0 = "TestMaterial"; +}; + +singleton Material( Grid512_Grey_Mat ) +{ + mapTo = "Grid512_Grey_Mat"; + diffuseMap[0] = "512_grey"; + materialTag0 = "TestMaterial"; +}; + +singleton Material( Grid512_GreyBase_Mat ) +{ + mapTo = "Grid512_GreyBase_Mat"; + diffuseMap[0] = "512_grey_base"; + materialTag0 = "TestMaterial"; +}; + +singleton Material( Grid512_Orange_Mat ) +{ + mapTo = "Grid512_Orange_Mat"; + diffuseMap[0] = "512_orange"; + materialTag0 = "TestMaterial"; +}; + +singleton Material( Grid512_OrangeLines_Mat ) +{ + mapTo = "Grid512_OrangeLines_Mat"; + diffuseMap[0] = "512_orange_lines"; + materialTag0 = "TestMaterial"; +}; + +singleton Material( Grid512_Red_Mat ) +{ + mapTo = "Grid512_Red_Mat"; + diffuseMap[0] = "512_red"; + materialTag0 = "TestMaterial"; +}; diff --git a/Templates/Empty/game/core/art/gui/FrameOverlayGui.gui b/Templates/Empty/game/core/art/gui/FrameOverlayGui.gui new file mode 100644 index 000000000..04a3f1472 --- /dev/null +++ b/Templates/Empty/game/core/art/gui/FrameOverlayGui.gui @@ -0,0 +1,28 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(FrameOverlayGui) { + profile = "GuiModelessDialogProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "True"; + modal = "false"; + helpTag = "0"; + noCursor = true; + new GuiConsoleTextCtrl(TextOverlayControl) { + profile = "GuiConsoleTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 5"; + extent = "130 18"; + minExtent = "4 4"; + visible = "True"; + setFirstResponder = "True"; + modal = "True"; + helpTag = "0"; + expression = "10"; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/core/art/gui/RecordingsDlg.gui b/Templates/Empty/game/core/art/gui/RecordingsDlg.gui new file mode 100644 index 000000000..44df55ca1 --- /dev/null +++ b/Templates/Empty/game/core/art/gui/RecordingsDlg.gui @@ -0,0 +1,99 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(recordingsDlg) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new GuiWindowCtrl() { + profile = "GuiWindowProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "55 65"; + extent = "530 338"; + minExtent = "48 92"; + visible = "1"; + helpTag = "0"; + text = "Demo Recordings"; + maxLength = "255"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "Canvas.popDialog(recordingsDlg);"; + + new GuiScrollCtrl() { + profile = "GuiScrollProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "23 37"; + extent = "484 260"; + minExtent = "32 32"; + visible = "1"; + helpTag = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "alwaysOn"; + lockHorizScroll = "false"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + defaultLineHeight = "15"; + + new GuiTextListCtrl(RecordingsDlgList) { + profile = "GuiTextArrayProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "2 2"; + extent = "462 20"; + minExtent = "8 20"; + visible = "1"; + helpTag = "0"; + enumerate = "0"; + columns = "0"; + resizeCell = "1"; + fitParentWidth = "1"; + clipColumnText = "0"; + noDuplicates = "false"; + }; + }; + new GuiButtonCtrl(DR_CancelBtn) { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "396 306"; + extent = "110 20"; + minExtent = "8 8"; + visible = "1"; + command = "Canvas.popDialog(recordingsDlg);"; + accelerator = "escape"; + helpTag = "0"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + }; + new GuiButtonCtrl(DR_StartDemoBtn) { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "25 305"; + extent = "110 20"; + minExtent = "8 8"; + visible = "1"; + command = "StartSelectedDemo();"; + helpTag = "0"; + text = "Play"; + groupNum = "-1"; + buttonType = "PushButton"; + }; + }; +}; +//--- OBJECT WRITE END --- + diff --git a/Templates/Empty/game/core/art/gui/chooseLevelDlg.gui b/Templates/Empty/game/core/art/gui/chooseLevelDlg.gui new file mode 100644 index 000000000..db5336318 --- /dev/null +++ b/Templates/Empty/game/core/art/gui/chooseLevelDlg.gui @@ -0,0 +1,273 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ChooseLevelDlg) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiOverlayProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCtrl(ChooseLevelWindow) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + Position = "252 224"; + Extent = "600 433"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Choose Level"; + closeCommand = "Canvas.popDialog(ChooseLevelDlg);"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "1"; + internalName = "CurrentPreview"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 31"; + Extent = "400 300"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = "./images/no-preview"; + wrap = "0"; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + internalName = "LevelName"; + isContainer = "0"; + Profile = "GuiMediumTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "420 31"; + Extent = "165 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Level"; + maxLength = "255"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "420 50"; + Extent = "72 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Description:"; + maxLength = "255"; + }; + new GuiMLTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + internalName = "LevelDescription"; + isContainer = "0"; + Profile = "GuiMLTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "420 76"; + Extent = "165 189"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = ""; + maxLength = "255"; + }; + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "420 303"; + Extent = "45 23"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Variable = "pref::HostMultiPlayer"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = " Host"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiButtonCtrl(ChooseLevelDlgGoBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiMenuButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "458 287"; + Extent = "143 56"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Go!"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + }; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "1"; + internalName = "PreviousSmallPreviews"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 343"; + Extent = "11 81"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = "core/art/gui/images/previous-button"; + wrap = "0"; + command = "ChooseLevelWindow.previousPreviews();"; + }; + + new GuiDynamicCtrlArrayControl() { + internalName = "SmallPreviews"; + position = "24 343"; + extent = "600 81"; + autoCellSize = true; + colSpacing = 3; + colCount = 5; + rowCount = 1; + }; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "1"; + internalName = "NextSmallPreviews"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "579 343"; + Extent = "11 81"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = "core/art/gui/images/next-button"; + wrap = "0"; + command = "ChooseLevelWindow.nextPreviews();"; + }; + + new GuiTextListCtrl(CL_levelList) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTextArrayProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "421 144"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + enumerate = "0"; + resizeCell = "1"; + columns = "0"; + fitParentWidth = "1"; + clipColumnText = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + +// Do this onMouseUp not via Command which occurs onMouseDown so we do +// not have a lingering mouseUp event lingering in the ether. +function ChooseLevelDlgGoBtn::onMouseUp( %this ) +{ + // So we can't fire the button when loading is in progress. + if ( isObject( ServerGroup ) ) + return; + + // Launch the chosen level with the editor open? + if ( ChooseLevelDlg.launchInEditor ) + { + activatePackage( "BootEditor" ); + ChooseLevelDlg.launchInEditor = false; + StartLevel("", "SinglePlayer"); + } + else + { + StartLevel(); + } +} diff --git a/Templates/Empty/game/core/art/gui/console.gui b/Templates/Empty/game/core/art/gui/console.gui new file mode 100644 index 000000000..70e5fb61b --- /dev/null +++ b/Templates/Empty/game/core/art/gui/console.gui @@ -0,0 +1,175 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ConsoleDlg) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new GuiConsoleEditCtrl(ConsoleEntry) { + profile = "ConsoleTextEditProfile"; + horizSizing = "width"; + vertSizing = "top"; + position = "0 462"; + extent = "640 18"; + minExtent = "8 8"; + visible = "1"; + altCommand = "ConsoleEntry::eval();"; + helpTag = "0"; + maxLength = "255"; + historySize = "40"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "1"; + useSiblingScroller = "1"; + }; + new GuiScrollCtrl() { + internalName = "Scroll"; + profile = "ConsoleScrollProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 462"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOn"; + vScrollBar = "alwaysOn"; + lockHorizScroll = "false"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiConsole( ConsoleMessageLogView ) { + profile = "GuiConsoleProfile"; + position = "0 0"; + }; + }; +}; +//--- OBJECT WRITE END --- + + +function ConsoleEntry::eval() +{ + %text = trim( ConsoleEntry.getValue() ); + if( %text $= "" ) + return; + + // If it's missing a trailing () and it's not a variable, + // append the parentheses. + + if( strpos(%text, "(") == -1 && !isDefined( %text ) ) + { + if(strpos(%text, "=") == -1 && strpos(%text, " ") == -1) + { + if(strpos(%text, "{") == -1 && strpos(%text, "}") == -1) + { + %text = %text @ "()"; + } + } + } + + // Append a semicolon if need be. + + %pos = strlen(%text) - 1; + if(strpos(%text, ";", %pos) == -1 && strpos(%text, "}") == -1) + { + %text = %text @ ";"; + } + + // Turn off warnings for assigning from void + // and evaluate the snippet. + + if( !isDefined( "$Con::warnVoidAssignment" ) ) + %oldWarnVoidAssignment = true; + else + %oldWarnVoidAssignment = $Con::warnVoidAssignment; + $Con::warnVoidAssignment = false; + + echo("==>" @ %text); + if( !startsWith( %text, "function " ) + && !startsWith( %text, "datablock " ) + && !startsWith( %text, "foreach(" ) + && !startsWith( %text, "foreach$(" ) + && !startsWith( %text, "if(" ) + && !startsWith( %text, "while(" ) + && !startsWith( %text, "for(" ) + && !startsWith( %text, "switch(" ) + && !startsWith( %text, "switch$(" ) ) + eval( "%result = " @ %text ); + else + eval( %text ); + $Con::warnVoidAssignment = %oldWarnVoidAssignment; + + ConsoleEntry.setValue(""); + + // Echo result. + + if( %result !$= "" ) + echo( %result ); +} + +function ToggleConsole(%make) +{ + if (%make) + { + if (ConsoleDlg.isAwake()) + { + // Deactivate the console. + Canvas.popDialog(ConsoleDlg); + } + else + { + Canvas.pushDialog(ConsoleDlg, 99); + } + } +} + +function ConsoleDlg::hideWindow( %this ) +{ + %this-->Scroll.setVisible( false ); +} + +function ConsoleDlg::showWindow( %this ) +{ + %this-->Scroll.setVisible( true ); +} + +function ConsoleDlg::setAlpha( %this, %alpha ) +{ + if ( %alpha $= "" ) + ConsoleScrollProfile.fillColor = $ConsoleDefaultFillColor; + else + ConsoleScrollProfile.fillColor = getWords( $ConsoleDefaultFillColor, 0, 2 ) SPC %alpha * 255.0; +} + +// If a message is selected that has a source location preceding it, allow jumping to the +// source location in Torsion by clicking on the message in the log view. +function ConsoleMessageLogView::onMessageSelected( %this, %level, %message ) +{ + if( !isFunction( "EditorOpenFileInTorsion" ) ) + return; + + %fileText = getWord( %message, 0 ); + %lineText = getWord( %message, 1 ); + + if( %fileText $= "" || %lineText $= "" ) + return; + + %fileName = makeFullPath( %fileText ); + if( !isFile( %fileName ) ) + return; + + %lineTextLen = strlen( %lineText ); + if( !startsWith( %lineText, "(" ) || + !endsWith( %lineText, "):" ) ) + return; + + %lineNumber = getSubStr( %lineText, 1, %lineTextLen - 2 ); + + EditorOpenFileInTorsion( %fileName, %lineNumber ); +} diff --git a/Templates/Empty/game/core/art/gui/consoleVarDlg.gui b/Templates/Empty/game/core/art/gui/consoleVarDlg.gui new file mode 100644 index 000000000..fc7ab123e --- /dev/null +++ b/Templates/Empty/game/core/art/gui/consoleVarDlg.gui @@ -0,0 +1,118 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ConsoleVarDlg) { + isContainer = "1"; + Profile = "GuiModelessDialogProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + noCursor = true; + + new GuiWindowCtrl() { + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "1"; + canMaximize = "1"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Console Variables"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "131 153"; + Extent = "194 324"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "window"; + canSaveDynamicFields = "0"; + closeCommand = "Canvas.popDialog( ConsoleVarDlg );"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 21"; + Extent = "192 300"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "Scroll"; + canSaveDynamicFields = "0"; + + new GuiVariableInspector(ConsoleVarInspector) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "190 298"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + dividerMargin = "5"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- + +function InspectVars( %filter ) +{ + if ( %filter $= "" ) + %filter = "*"; + + //if ( !ConsoleVarDlg.isAwake() ) + Canvas.pushDialog( ConsoleVarDlg, 100 ); + + ConsoleVarInspector.loadVars( %filter ); +} + +function InspectVarsToggleCursor() +{ + ConsoleVarDlg.noCursor = !(ConsoleVarDlg.noCursor); +} \ No newline at end of file diff --git a/Templates/Empty/game/core/art/gui/images/GG_Icon.png b/Templates/Empty/game/core/art/gui/images/GG_Icon.png new file mode 100644 index 000000000..bdc5bc74c Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/GG_Icon.png differ diff --git a/Templates/Empty/game/core/art/gui/images/arrowbtn_d.png b/Templates/Empty/game/core/art/gui/images/arrowbtn_d.png new file mode 100644 index 000000000..be39b42bd Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/arrowbtn_d.png differ diff --git a/Templates/Empty/game/core/art/gui/images/arrowbtn_n.png b/Templates/Empty/game/core/art/gui/images/arrowbtn_n.png new file mode 100644 index 000000000..0c0fd526d Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/arrowbtn_n.png differ diff --git a/Templates/Empty/game/core/art/gui/images/breadcrumbs.png b/Templates/Empty/game/core/art/gui/images/breadcrumbs.png new file mode 100644 index 000000000..e9c420c4d Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/breadcrumbs.png differ diff --git a/Templates/Empty/game/core/art/gui/images/button.png b/Templates/Empty/game/core/art/gui/images/button.png new file mode 100644 index 000000000..1c7361e25 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/button.png differ diff --git a/Templates/Empty/game/core/art/gui/images/buttontab.png b/Templates/Empty/game/core/art/gui/images/buttontab.png new file mode 100644 index 000000000..047b88645 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/buttontab.png differ diff --git a/Templates/Empty/game/core/art/gui/images/chatHudBorderArray.png b/Templates/Empty/game/core/art/gui/images/chatHudBorderArray.png new file mode 100644 index 000000000..1aebdb2d8 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/chatHudBorderArray.png differ diff --git a/Templates/Empty/game/core/art/gui/images/checkbox-list.png b/Templates/Empty/game/core/art/gui/images/checkbox-list.png new file mode 100644 index 000000000..04ca2b0dc Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/checkbox-list.png differ diff --git a/Templates/Empty/game/core/art/gui/images/checkbox-list_fliped.png b/Templates/Empty/game/core/art/gui/images/checkbox-list_fliped.png new file mode 100644 index 000000000..2db4489de Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/checkbox-list_fliped.png differ diff --git a/Templates/Empty/game/core/art/gui/images/checkbox.png b/Templates/Empty/game/core/art/gui/images/checkbox.png new file mode 100644 index 000000000..46e0ac959 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/checkbox.png differ diff --git a/Templates/Empty/game/core/art/gui/images/clear-btn_d.png b/Templates/Empty/game/core/art/gui/images/clear-btn_d.png new file mode 100644 index 000000000..229c71e8b Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/clear-btn_d.png differ diff --git a/Templates/Empty/game/core/art/gui/images/clear-btn_h.png b/Templates/Empty/game/core/art/gui/images/clear-btn_h.png new file mode 100644 index 000000000..5e67cb13b Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/clear-btn_h.png differ diff --git a/Templates/Empty/game/core/art/gui/images/clear-btn_n.png b/Templates/Empty/game/core/art/gui/images/clear-btn_n.png new file mode 100644 index 000000000..ecb13a8d6 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/clear-btn_n.png differ diff --git a/Templates/Empty/game/core/art/gui/images/collapse-toolbar_d.png b/Templates/Empty/game/core/art/gui/images/collapse-toolbar_d.png new file mode 100644 index 000000000..984a63853 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/collapse-toolbar_d.png differ diff --git a/Templates/Empty/game/core/art/gui/images/collapse-toolbar_h.png b/Templates/Empty/game/core/art/gui/images/collapse-toolbar_h.png new file mode 100644 index 000000000..7e3de8387 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/collapse-toolbar_h.png differ diff --git a/Templates/Empty/game/core/art/gui/images/collapse-toolbar_n.png b/Templates/Empty/game/core/art/gui/images/collapse-toolbar_n.png new file mode 100644 index 000000000..b36de3ae0 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/collapse-toolbar_n.png differ diff --git a/Templates/Empty/game/core/art/gui/images/crosshair.png b/Templates/Empty/game/core/art/gui/images/crosshair.png new file mode 100644 index 000000000..06bcf5c6c Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/crosshair.png differ diff --git a/Templates/Empty/game/core/art/gui/images/crosshair_blue.png b/Templates/Empty/game/core/art/gui/images/crosshair_blue.png new file mode 100644 index 000000000..d5b0485d7 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/crosshair_blue.png differ diff --git a/Templates/Empty/game/core/art/gui/images/default.png b/Templates/Empty/game/core/art/gui/images/default.png new file mode 100644 index 000000000..e687a1d1c Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/default.png differ diff --git a/Templates/Empty/game/core/art/gui/images/defaultCursor.png b/Templates/Empty/game/core/art/gui/images/defaultCursor.png new file mode 100644 index 000000000..ee03cd483 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/defaultCursor.png differ diff --git a/Templates/Empty/game/core/art/gui/images/dropDown-tab.png b/Templates/Empty/game/core/art/gui/images/dropDown-tab.png new file mode 100644 index 000000000..d79c6c70e Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/dropDown-tab.png differ diff --git a/Templates/Empty/game/core/art/gui/images/dropDown.png b/Templates/Empty/game/core/art/gui/images/dropDown.png new file mode 100644 index 000000000..9b7414acc Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/dropDown.png differ diff --git a/Templates/Empty/game/core/art/gui/images/dropdown-button-arrow.png b/Templates/Empty/game/core/art/gui/images/dropdown-button-arrow.png new file mode 100644 index 000000000..8c420ab85 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/dropdown-button-arrow.png differ diff --git a/Templates/Empty/game/core/art/gui/images/dropdown-textEdit.png b/Templates/Empty/game/core/art/gui/images/dropdown-textEdit.png new file mode 100644 index 000000000..3966efbb5 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/dropdown-textEdit.png differ diff --git a/Templates/Empty/game/core/art/gui/images/dropslider_d.png b/Templates/Empty/game/core/art/gui/images/dropslider_d.png new file mode 100644 index 000000000..0c65347aa Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/dropslider_d.png differ diff --git a/Templates/Empty/game/core/art/gui/images/dropslider_h.png b/Templates/Empty/game/core/art/gui/images/dropslider_h.png new file mode 100644 index 000000000..bd2cb89d8 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/dropslider_h.png differ diff --git a/Templates/Empty/game/core/art/gui/images/dropslider_n.png b/Templates/Empty/game/core/art/gui/images/dropslider_n.png new file mode 100644 index 000000000..a4577f9ea Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/dropslider_n.png differ diff --git a/Templates/Empty/game/core/art/gui/images/expand-toolbar_d.png b/Templates/Empty/game/core/art/gui/images/expand-toolbar_d.png new file mode 100644 index 000000000..462929e95 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/expand-toolbar_d.png differ diff --git a/Templates/Empty/game/core/art/gui/images/expand-toolbar_h.png b/Templates/Empty/game/core/art/gui/images/expand-toolbar_h.png new file mode 100644 index 000000000..c33bcad69 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/expand-toolbar_h.png differ diff --git a/Templates/Empty/game/core/art/gui/images/expand-toolbar_n.png b/Templates/Empty/game/core/art/gui/images/expand-toolbar_n.png new file mode 100644 index 000000000..0af2f1bd1 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/expand-toolbar_n.png differ diff --git a/Templates/Empty/game/core/art/gui/images/file.png b/Templates/Empty/game/core/art/gui/images/file.png new file mode 100644 index 000000000..28fa55ec3 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/file.png differ diff --git a/Templates/Empty/game/core/art/gui/images/folder.png b/Templates/Empty/game/core/art/gui/images/folder.png new file mode 100644 index 000000000..571a904d0 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/folder.png differ diff --git a/Templates/Empty/game/core/art/gui/images/folderClosed.png b/Templates/Empty/game/core/art/gui/images/folderClosed.png new file mode 100644 index 000000000..51936100b Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/folderClosed.png differ diff --git a/Templates/Empty/game/core/art/gui/images/group-border.png b/Templates/Empty/game/core/art/gui/images/group-border.png new file mode 100644 index 000000000..61234ae1f Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/group-border.png differ diff --git a/Templates/Empty/game/core/art/gui/images/htoolbar-window.png b/Templates/Empty/game/core/art/gui/images/htoolbar-window.png new file mode 100644 index 000000000..4caa48caa Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/htoolbar-window.png differ diff --git a/Templates/Empty/game/core/art/gui/images/hudfill.png b/Templates/Empty/game/core/art/gui/images/hudfill.png new file mode 100644 index 000000000..57d72468b Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/hudfill.png differ diff --git a/Templates/Empty/game/core/art/gui/images/iconbutton.png b/Templates/Empty/game/core/art/gui/images/iconbutton.png new file mode 100644 index 000000000..b6f3bb6b7 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/iconbutton.png differ diff --git a/Templates/Empty/game/core/art/gui/images/iconbuttonsmall.png b/Templates/Empty/game/core/art/gui/images/iconbuttonsmall.png new file mode 100644 index 000000000..25d5ae80b Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/iconbuttonsmall.png differ diff --git a/Templates/Empty/game/core/art/gui/images/inactive-overlay.png b/Templates/Empty/game/core/art/gui/images/inactive-overlay.png new file mode 100644 index 000000000..feab83209 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/inactive-overlay.png differ diff --git a/Templates/Empty/game/core/art/gui/images/loadingbar.png b/Templates/Empty/game/core/art/gui/images/loadingbar.png new file mode 100644 index 000000000..34f594403 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/loadingbar.png differ diff --git a/Templates/Empty/game/core/art/gui/images/macCursor.png b/Templates/Empty/game/core/art/gui/images/macCursor.png new file mode 100644 index 000000000..22c444970 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/macCursor.png differ diff --git a/Templates/Empty/game/core/art/gui/images/menu.png b/Templates/Empty/game/core/art/gui/images/menu.png new file mode 100644 index 000000000..2b7a33f58 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/menu.png differ diff --git a/Templates/Empty/game/core/art/gui/images/menubar-window.png b/Templates/Empty/game/core/art/gui/images/menubar-window.png new file mode 100644 index 000000000..dd38cad80 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/menubar-window.png differ diff --git a/Templates/Empty/game/core/art/gui/images/menubar.png b/Templates/Empty/game/core/art/gui/images/menubar.png new file mode 100644 index 000000000..353451a27 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/menubar.png differ diff --git a/Templates/Empty/game/core/art/gui/images/new_d.png b/Templates/Empty/game/core/art/gui/images/new_d.png new file mode 100644 index 000000000..bdfc9400d Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/new_d.png differ diff --git a/Templates/Empty/game/core/art/gui/images/new_h.png b/Templates/Empty/game/core/art/gui/images/new_h.png new file mode 100644 index 000000000..1f9b722c1 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/new_h.png differ diff --git a/Templates/Empty/game/core/art/gui/images/new_n.png b/Templates/Empty/game/core/art/gui/images/new_n.png new file mode 100644 index 000000000..06531327d Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/new_n.png differ diff --git a/Templates/Empty/game/core/art/gui/images/next-button_d.png b/Templates/Empty/game/core/art/gui/images/next-button_d.png new file mode 100644 index 000000000..76c3ec0ff Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/next-button_d.png differ diff --git a/Templates/Empty/game/core/art/gui/images/next-button_h.png b/Templates/Empty/game/core/art/gui/images/next-button_h.png new file mode 100644 index 000000000..f52f5fb42 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/next-button_h.png differ diff --git a/Templates/Empty/game/core/art/gui/images/next-button_n.png b/Templates/Empty/game/core/art/gui/images/next-button_n.png new file mode 100644 index 000000000..203133732 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/next-button_n.png differ diff --git a/Templates/Empty/game/core/art/gui/images/no-preview.png b/Templates/Empty/game/core/art/gui/images/no-preview.png new file mode 100644 index 000000000..fccdc858b Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/no-preview.png differ diff --git a/Templates/Empty/game/core/art/gui/images/numericslider.png b/Templates/Empty/game/core/art/gui/images/numericslider.png new file mode 100644 index 000000000..6a97d60c8 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/numericslider.png differ diff --git a/Templates/Empty/game/core/art/gui/images/popupMenu.png b/Templates/Empty/game/core/art/gui/images/popupMenu.png new file mode 100644 index 000000000..67222c9e0 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/popupMenu.png differ diff --git a/Templates/Empty/game/core/art/gui/images/previous-button_d.png b/Templates/Empty/game/core/art/gui/images/previous-button_d.png new file mode 100644 index 000000000..688b30345 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/previous-button_d.png differ diff --git a/Templates/Empty/game/core/art/gui/images/previous-button_h.png b/Templates/Empty/game/core/art/gui/images/previous-button_h.png new file mode 100644 index 000000000..26cf0e8c6 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/previous-button_h.png differ diff --git a/Templates/Empty/game/core/art/gui/images/previous-button_n.png b/Templates/Empty/game/core/art/gui/images/previous-button_n.png new file mode 100644 index 000000000..c0b9f4662 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/previous-button_n.png differ diff --git a/Templates/Empty/game/core/art/gui/images/radioButton.png b/Templates/Empty/game/core/art/gui/images/radioButton.png new file mode 100644 index 000000000..d5ecc9853 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/radioButton.png differ diff --git a/Templates/Empty/game/core/art/gui/images/rl-loadingbar.png b/Templates/Empty/game/core/art/gui/images/rl-loadingbar.png new file mode 100644 index 000000000..7116eec14 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/rl-loadingbar.png differ diff --git a/Templates/Empty/game/core/art/gui/images/scrollBar.png b/Templates/Empty/game/core/art/gui/images/scrollBar.png new file mode 100644 index 000000000..e8c34dc85 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/scrollBar.png differ diff --git a/Templates/Empty/game/core/art/gui/images/selector-button.png b/Templates/Empty/game/core/art/gui/images/selector-button.png new file mode 100644 index 000000000..cd0780068 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/selector-button.png differ diff --git a/Templates/Empty/game/core/art/gui/images/separator-h.png b/Templates/Empty/game/core/art/gui/images/separator-h.png new file mode 100644 index 000000000..339c0fbe0 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/separator-h.png differ diff --git a/Templates/Empty/game/core/art/gui/images/separator-v.png b/Templates/Empty/game/core/art/gui/images/separator-v.png new file mode 100644 index 000000000..6a0f87361 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/separator-v.png differ diff --git a/Templates/Empty/game/core/art/gui/images/simGroupSelected.png b/Templates/Empty/game/core/art/gui/images/simGroupSelected.png new file mode 100644 index 000000000..94f3b0f02 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/simGroupSelected.png differ diff --git a/Templates/Empty/game/core/art/gui/images/simGroupSelectedClosed.png b/Templates/Empty/game/core/art/gui/images/simGroupSelectedClosed.png new file mode 100644 index 000000000..0c746e404 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/simGroupSelectedClosed.png differ diff --git a/Templates/Empty/game/core/art/gui/images/simgroup.png b/Templates/Empty/game/core/art/gui/images/simgroup.png new file mode 100644 index 000000000..571a904d0 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/simgroup.png differ diff --git a/Templates/Empty/game/core/art/gui/images/simgroupClosed.png b/Templates/Empty/game/core/art/gui/images/simgroupClosed.png new file mode 100644 index 000000000..51936100b Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/simgroupClosed.png differ diff --git a/Templates/Empty/game/core/art/gui/images/slider-w-box.png b/Templates/Empty/game/core/art/gui/images/slider-w-box.png new file mode 100644 index 000000000..d9ef04961 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/slider-w-box.png differ diff --git a/Templates/Empty/game/core/art/gui/images/slider.png b/Templates/Empty/game/core/art/gui/images/slider.png new file mode 100644 index 000000000..92fee1e9c Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/slider.png differ diff --git a/Templates/Empty/game/core/art/gui/images/tab-border.png b/Templates/Empty/game/core/art/gui/images/tab-border.png new file mode 100644 index 000000000..6703924d4 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/tab-border.png differ diff --git a/Templates/Empty/game/core/art/gui/images/tab.png b/Templates/Empty/game/core/art/gui/images/tab.png new file mode 100644 index 000000000..ecd81daf7 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/tab.png differ diff --git a/Templates/Empty/game/core/art/gui/images/textEdit.png b/Templates/Empty/game/core/art/gui/images/textEdit.png new file mode 100644 index 000000000..5a65fac3c Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/textEdit.png differ diff --git a/Templates/Empty/game/core/art/gui/images/textEditSliderBox.png b/Templates/Empty/game/core/art/gui/images/textEditSliderBox.png new file mode 100644 index 000000000..57a0c49d3 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/textEditSliderBox.png differ diff --git a/Templates/Empty/game/core/art/gui/images/thumbHightlightButton.png b/Templates/Empty/game/core/art/gui/images/thumbHightlightButton.png new file mode 100644 index 000000000..9d83b75f3 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/thumbHightlightButton.png differ diff --git a/Templates/Empty/game/core/art/gui/images/toolbar-window.png b/Templates/Empty/game/core/art/gui/images/toolbar-window.png new file mode 100644 index 000000000..fa57993c2 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/toolbar-window.png differ diff --git a/Templates/Empty/game/core/art/gui/images/transp_grid.png b/Templates/Empty/game/core/art/gui/images/transp_grid.png new file mode 100644 index 000000000..e6b9db4cc Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/transp_grid.png differ diff --git a/Templates/Empty/game/core/art/gui/images/trashCan.png b/Templates/Empty/game/core/art/gui/images/trashCan.png new file mode 100644 index 000000000..12f785d9c Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/trashCan.png differ diff --git a/Templates/Empty/game/core/art/gui/images/trashCan_d.png b/Templates/Empty/game/core/art/gui/images/trashCan_d.png new file mode 100644 index 000000000..51f0110fb Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/trashCan_d.png differ diff --git a/Templates/Empty/game/core/art/gui/images/trashCan_h.png b/Templates/Empty/game/core/art/gui/images/trashCan_h.png new file mode 100644 index 000000000..12f785d9c Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/trashCan_h.png differ diff --git a/Templates/Empty/game/core/art/gui/images/trashCan_i.png b/Templates/Empty/game/core/art/gui/images/trashCan_i.png new file mode 100644 index 000000000..12f785d9c Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/trashCan_i.png differ diff --git a/Templates/Empty/game/core/art/gui/images/treeView.png b/Templates/Empty/game/core/art/gui/images/treeView.png new file mode 100644 index 000000000..cbc20d49e Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/treeView.png differ diff --git a/Templates/Empty/game/core/art/gui/images/treeview/default.png b/Templates/Empty/game/core/art/gui/images/treeview/default.png new file mode 100644 index 000000000..ceadfa861 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/treeview/default.png differ diff --git a/Templates/Empty/game/core/art/gui/images/treeview/hidden.png b/Templates/Empty/game/core/art/gui/images/treeview/hidden.png new file mode 100644 index 000000000..0fbcf3840 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/treeview/hidden.png differ diff --git a/Templates/Empty/game/core/art/gui/images/treeview/shll_icon_passworded.png b/Templates/Empty/game/core/art/gui/images/treeview/shll_icon_passworded.png new file mode 100644 index 000000000..a5530e968 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/treeview/shll_icon_passworded.png differ diff --git a/Templates/Empty/game/core/art/gui/images/treeview/shll_icon_passworded_hi.png b/Templates/Empty/game/core/art/gui/images/treeview/shll_icon_passworded_hi.png new file mode 100644 index 000000000..509c4f595 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/treeview/shll_icon_passworded_hi.png differ diff --git a/Templates/Empty/game/core/art/gui/images/treeview/simgroup.png b/Templates/Empty/game/core/art/gui/images/treeview/simgroup.png new file mode 100644 index 000000000..0babc1392 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/treeview/simgroup.png differ diff --git a/Templates/Empty/game/core/art/gui/images/treeview/simgroup_closed.png b/Templates/Empty/game/core/art/gui/images/treeview/simgroup_closed.png new file mode 100644 index 000000000..0babc1392 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/treeview/simgroup_closed.png differ diff --git a/Templates/Empty/game/core/art/gui/images/treeview/simgroup_selected.png b/Templates/Empty/game/core/art/gui/images/treeview/simgroup_selected.png new file mode 100644 index 000000000..7a6bb8ec3 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/treeview/simgroup_selected.png differ diff --git a/Templates/Empty/game/core/art/gui/images/treeview/simgroup_selected_closed.png b/Templates/Empty/game/core/art/gui/images/treeview/simgroup_selected_closed.png new file mode 100644 index 000000000..7a6bb8ec3 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/treeview/simgroup_selected_closed.png differ diff --git a/Templates/Empty/game/core/art/gui/images/window.png b/Templates/Empty/game/core/art/gui/images/window.png new file mode 100644 index 000000000..d9e8006e4 Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/window.png differ diff --git a/Templates/Empty/game/core/art/gui/images/windowPattern.png b/Templates/Empty/game/core/art/gui/images/windowPattern.png new file mode 100644 index 000000000..44869c0cd Binary files /dev/null and b/Templates/Empty/game/core/art/gui/images/windowPattern.png differ diff --git a/Templates/Empty/game/core/art/gui/loadingGui.gui b/Templates/Empty/game/core/art/gui/loadingGui.gui new file mode 100644 index 000000000..2704adeab --- /dev/null +++ b/Templates/Empty/game/core/art/gui/loadingGui.gui @@ -0,0 +1,99 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = singleton GuiChunkedBitmapCtrl(LoadingGui) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiContentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = "art/gui/background"; + useVariable = "0"; + tile = "0"; + + new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "center"; + VertSizing = "center"; + Position = "151 217"; + Extent = "497 166"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiBitmapCtrl(LoadingLogo) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "center"; + VertSizing = "bottom"; + Position = "27 6"; + Extent = "443 139"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = "art/gui/Torque-3D-logo.png"; + wrap = "0"; + }; + singleton GuiProgressBitmapCtrl(LoadingProgress) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiProgressBitmapProfile"; + HorizSizing = "center"; + VertSizing = "bottom"; + Position = "17 126"; + Extent = "464 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + }; + singleton GuiTextCtrl(LoadingProgressTxt) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiProgressTextProfile"; + HorizSizing = "center"; + VertSizing = "bottom"; + Position = "28 144"; + Extent = "440 20"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "WAITING FOR SERVER"; + maxLength = "255"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/core/art/gui/netGraphGui.gui b/Templates/Empty/game/core/art/gui/netGraphGui.gui new file mode 100644 index 000000000..b62e8ea23 --- /dev/null +++ b/Templates/Empty/game/core/art/gui/netGraphGui.gui @@ -0,0 +1,238 @@ +function execNetGraphGuiGUI() +{ + if ( isObject( NetGraphGui ) ) + NetGraphGui.delete(); + + if ( isObject( NetGraphProfile ) ) + NetGraphProfile.delete(); + + if ( isObject( NetGraphGhostsActiveProfile ) ) + NetGraphGhostsActiveProfile.delete(); + + if ( isObject( NetGraphGhostUpdatesProfile ) ) + NetGraphGhostUpdatesProfile.delete(); + + if ( isObject( NetGraphBitsSentProfile ) ) + NetGraphBitsSentProfile.delete(); + + if ( isObject( NetGraphBitsReceivedProfile ) ) + NetGraphBitsReceivedProfile.delete(); + + if ( isObject( NetGraphLatencyProfile ) ) + NetGraphLatencyProfile.delete(); + + if ( isObject( NetGraphPacketLossProfile ) ) + NetGraphPacketLossProfile.delete(); + + exec( "./NetGraphGui.gui" ); +} + +// Profiles +new GuiControlProfile (NetGraphProfile) +{ + modal = false; + opaque = false; + canKeyFocus = false; +}; + +new GuiControlProfile (NetGraphKeyContainerProfile) +{ + border = true; + opaque = true; + fillColor = "100 100 100 200"; +}; +new GuiControlProfile (NetGraphGhostsActiveProfile) +{ + border = false; + fontColor = "255 255 255"; +}; +new GuiControlProfile (NetGraphGhostUpdatesProfile) +{ + border = false; + fontColor = "255 0 0"; +}; +new GuiControlProfile (NetGraphBitsSentProfile) +{ + border = false; + fontColor = "0 255 0"; +}; +new GuiControlProfile (NetGraphBitsReceivedProfile) +{ + border = false; + fontColor = "0 0 255"; +}; +new GuiControlProfile (NetGraphLatencyProfile) +{ + border = false; + fontColor = "0 255 255"; +}; +new GuiControlProfile (NetGraphPacketLossProfile) +{ + border = false; + fontColor = "0 0 0"; +}; + +//--- OBJECT WRITE BEGIN --- +new GuiControl(NetGraphGui) { + profile = "NetGraphProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 2"; + visible = "1"; + noCursor = "1"; + + new GuiGraphCtrl(NetGraph) { + profile = "NetGraphKeyContainerProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "432 5"; + extent = "200 200"; + minExtent = "8 2"; + visible = "1"; + }; + + new GuiControl() { + profile = "NetGraphKeyContainerProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "432 205"; + extent = "200 52"; + minExtent = "8 2"; + visible = "1"; + + new GuiTextCtrl(GhostsActive) { + profile = "NetGraphGhostsActiveProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "0 0"; + extent = "100 18"; + minExtent = "8 2"; + visible = "1"; + text = "Ghosts Active"; + maxLength = "255"; + }; + new GuiTextCtrl(GhostUpdates) { + profile = "NetGraphGhostUpdatesProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "100 0"; + extent = "100 18"; + minExtent = "8 2"; + visible = "1"; + text = "Ghost Updates"; + maxLength = "255"; + }; + new GuiTextCtrl(BitsSent) { + profile = "NetGraphBitsSentProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "0 18 "; + extent = "100 18"; + minExtent = "8 2"; + visible = "1"; + text = "Bytes Sent"; + maxLength = "255"; + }; + new GuiTextCtrl(BitsReceived) { + profile = "NetGraphBitsReceivedProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "100 18"; + extent = "100 18"; + minExtent = "8 2"; + visible = "1"; + text = "Bytes Received"; + maxLength = "255"; + }; + new GuiTextCtrl(Latency) { + profile = "NetGraphLatencyProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "0 36"; + extent = "100 18"; + minExtent = "8 2"; + visible = "1"; + text = "Latency"; + maxLength = "255"; + }; + new GuiTextCtrl(PacketLoss) { + profile = "NetGraphPacketLossProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "100 36"; + extent = "59 18"; + minExtent = "8 2"; + visible = "1"; + text = "Packet Loss"; + maxLength = "255"; + }; + }; +}; +//--- OBJECT WRITE END --- + +// Functions +function toggleNetGraph() +{ + if(!$NetGraph::isInitialized) + { + NetGraph::updateStats(); + $NetGraph::isInitialized = true; + } + + if(!Canvas.isMember(NetGraphGui)) + { + Canvas.add(NetGraphGui); + } + else + Canvas.remove(NetGraphGui); +} + +function NetGraph::updateStats() +{ + $NetGraphThread = NetGraph.schedule(32, "updateStats"); + + if(!$Stats::netGhostUpdates) + return; + + if(isobject(NetGraph)) + { + if(isobject(ServerConnection)) + NetGraph.addDatum(0,ServerConnection.getGhostsActive()); + GhostsActive.setText("Ghosts Active: " @ ServerConnection.getGhostsActive()); + NetGraph.addDatum(1,$Stats::netGhostUpdates); + GhostUpdates.setText("Ghost Updates: " @ $Stats::netGhostUpdates); + NetGraph.addDatum(2,$Stats::netBitsSent); + BitsSent.setText("Bytes Sent: " @ $Stats::netBitsSent); + NetGraph.addDatum(3,$Stats::netBitsReceived); + BitsReceived.setText("Bytes Received: " @ $Stats::netBitsReceived); + NetGraph.matchScale(2,3); + NetGraph.addDatum(4,ServerConnection.getPing()); + Latency.setText("Latency: " @ ServerConnection.getPing()); + NetGraph.addDatum(5,ServerConnection.getPacketLoss()); + PacketLoss.setText("Packet Loss: " @ ServerConnection.getPacketLoss()); + } +} + +function NetGraph::toggleKey() +{ + if(!GhostsActive.visible) + { + GhostsActive.visible = 1; + GhostUpdates.visible = 1; + BitsSent.visible = 1; + BitsReceived.visible = 1; + Latency.visible = 1; + PacketLoss.visible = 1; + } + else + { + GhostsActive.visible = 0; + GhostUpdates.visible = 0; + BitsSent.visible = 0; + BitsReceived.visible = 0; + Latency.visible = 0; + PacketLoss.visible = 0; + } +} diff --git a/Templates/Empty/game/core/art/gui/optionsDlg.gui b/Templates/Empty/game/core/art/gui/optionsDlg.gui new file mode 100644 index 000000000..fcff1cb95 --- /dev/null +++ b/Templates/Empty/game/core/art/gui/optionsDlg.gui @@ -0,0 +1,1417 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(OptionsDlg) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiOverlayProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + fixedAspectRatio = "0"; + + new GuiWindowCtrl() { + text = "Options"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + closeCommand = "Canvas.popDialog(optionsDlg);"; + edgeSnap = "0"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "323 232"; + extent = "377 303"; + minExtent = "8 8"; + horizSizing = "center"; + vertSizing = "center"; + profile = "GuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiButtonCtrl() { + text = "Done"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "306 271"; + extent = "60 23"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog(optionsDlg);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapBorderCtrl() { + position = "9 55"; + extent = "358 210"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabBorderProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "OptControlsPane"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "alwaysOn"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "5 24"; + extent = "347 152"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextListCtrl() { + columns = "0 160"; + fitParentWidth = "1"; + clipColumnText = "0"; + position = "1 1"; + extent = "329 780"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + altCommand = "OptionsDlg.doRemap();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "OptRemapList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTextCtrl() { + text = "Control Name"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "6 6"; + extent = "64 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Control Binding"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "165 6"; + extent = "72 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + + new GuiSliderCtrl(OptMouseSensitivity) { + range = "0.02 2"; + ticks = "10"; + value = "0.75"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "105 182"; + Extent = "244 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "OptMouseSetSensitivity(OptMouseSensitivity.value);"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Mouse Sensitivity:"; + maxLength = "255"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "15 182"; + Extent = "85 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapBorderCtrl() { + position = "9 55"; + extent = "358 210"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabBorderProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "OptAudioPane"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiMLTextCtrl() { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + position = "149 10"; + extent = "190 14"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMLTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptAudioInfo"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Audio Provider:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "16 16"; + extent = "75 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(OptAudioProviderList) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "Null"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "101 15"; + extent = "240 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Audio Device:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "23 48"; + extent = "75 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(OptAudioDeviceList) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "SFX Null Device"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "101 47"; + extent = "240 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiControl() { + position = "18 84"; + extent = "325 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Master Volume"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "72 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiAutoSizeTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "0 1"; + ticks = "0"; + snap = "0"; + value = "0.8"; + position = "85 1"; + extent = "240 14"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + altCommand = "OptAudioUpdateMasterVolume( $thisControl.value );"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptAudioVolumeMaster"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "9 115"; + extent = "334 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Interface Volume"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "82 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiAutoSizeTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "0 1"; + ticks = "0"; + snap = "0"; + value = "1"; + position = "94 2"; + extent = "240 13"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + altCommand = "OptAudioUpdateChannelVolume(AudioGui, $thisControl.value);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptAudioVolumeShell"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "18 146"; + extent = "325 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Effects Volume"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "74 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiAutoSizeTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "0 1"; + ticks = "0"; + snap = "0"; + value = "1"; + position = "85 2"; + extent = "240 13"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + altCommand = "OptAudioUpdateChannelVolume(AudioEffect, $thisControl.value);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptAudioVolumeSim"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "23 177"; + extent = "320 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiSliderCtrl() { + range = "0 1"; + ticks = "0"; + snap = "0"; + value = "1"; + position = "80 2"; + extent = "240 13"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + altCommand = "OptAudioUpdateChannelVolume(AudioMusic, $thisControl.value);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptAudioVolumeMusic"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Music Volume"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "67 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiAutoSizeTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiBitmapBorderCtrl() { + position = "9 55"; + extent = "358 210"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabBorderProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "OptGraphicsPane"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Display Driver:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "11 8"; + extent = "70 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Resolution:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "11 35"; + extent = "53 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + text = "Fullscreen"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "11 62"; + extent = "85 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + command = "OptionsDlg._updateApplyState();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptGraphicsFullscreenToggle"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(OptGraphicsDriverMenu) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "ATI Radeon HD 5700 Series (D3D9)"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "88 8"; + extent = "258 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "1024 x 768 (4:3)"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "67 35"; + extent = "127 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + command = "OptionsDlg._updateApplyState();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptGraphicsResolutionMenu"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Refresh:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "207 35"; + extent = "45 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "60"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "252 35"; + extent = "49 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + command = "OptionsDlg._updateApplyState();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptRefreshSelectMenu"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Mesh Quality:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "21 91"; + extent = "62 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "Low"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "90 91"; + extent = "78 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + command = "OptionsDlg._updateApplyState();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptMeshQualityPopup"; + class = "GraphicsQualityPopup"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "Low"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "90 118"; + extent = "78 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + command = "OptionsDlg._updateApplyState();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptTextureQualityPopup"; + class = "GraphicsQualityPopup"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Texture Quality:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "11 118"; + extent = "77 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "Low"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "90 143"; + extent = "78 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + command = "OptionsDlg._updateApplyState();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptLightingQualityPopup"; + class = "GraphicsQualityPopup"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Lighting Quality:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "11 143"; + extent = "73 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Effect Quality:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "191 91"; + extent = "73 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "263 91"; + extent = "78 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + command = "OptionsDlg._updateApplyState();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptEffectQualityPopup"; + class = "GraphicsQualityPopup"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Shader Quality:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "186 118"; + extent = "77 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "Low"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "263 118"; + extent = "78 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + command = "OptionsDlg._updateApplyState();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptShaderQualityPopup"; + class = "GraphicsQualityPopup"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Particle Quality:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "186 156"; + extent = "73 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "263 156"; + extent = "78 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "0"; + active = "1"; + command = "OptionsDlg._updateApplyState();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptParticleQualityPopup"; + class = "GraphicsQualityPopup"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Anisotropic Filtering:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "22 167"; + extent = "105 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "Off"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "123 167"; + extent = "45 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + command = "OptionsDlg._updateApplyState();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptAnisotropicPopup"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + text = "Vertical Sync"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "92 62"; + extent = "85 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + command = "OptionsDlg._updateApplyState();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptGraphicsVSyncToggle"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Auto Detect Quality"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "205 152"; + extent = "110 27"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "OptionsDlg._autoDetectQuality();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "263 62"; + extent = "78 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + command = "OptionsDlg._updateApplyState();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptAAQualityPopup"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Anti-aliasing"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "191 62"; + extent = "73 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiControl() { + position = "0 190"; + extent = "352 15"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "GammaSliderContainer"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiSliderCtrl() { + range = "0.001 2.2"; + ticks = "0"; + snap = "0"; + value = "1"; + position = "76 -1"; + extent = "268 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + variable = "$pref::Video::Gamma"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Gamma:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "22 -4"; + extent = "105 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiControl() { + position = "9 55"; + extent = "357 208"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiWindowProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "OptNetworkPane"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Graphics"; + groupNum = "-1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + position = "9 33"; + extent = "117 23"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonTabProfile"; + visible = "1"; + active = "1"; + command = "optionsDlg.setPane(Graphics);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptGraphicsButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Audio"; + groupNum = "-1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + position = "126 33"; + extent = "117 23"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonTabProfile"; + visible = "1"; + active = "1"; + command = "optionsDlg.setPane(Audio);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Controls"; + groupNum = "-1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + position = "243 33"; + extent = "117 23"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonTabProfile"; + visible = "1"; + active = "1"; + command = "optionsDlg.setPane(Controls);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Apply"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "241 271"; + extent = "60 23"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "0"; + command = "optionsDlg.applyGraphics();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "apply"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/core/art/gui/profiles.cs b/Templates/Empty/game/core/art/gui/profiles.cs new file mode 100644 index 000000000..ed7dc9de7 --- /dev/null +++ b/Templates/Empty/game/core/art/gui/profiles.cs @@ -0,0 +1,1144 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// If we got back no prefs path modification +if( $Gui::fontCacheDirectory $= "") +{ + $Gui::fontCacheDirectory = expandFilename( "~/fonts" ); +} + +//--------------------------------------------------------------------------------------------- +// GuiDefaultProfile is a special profile that all other profiles inherit defaults from. It +// must exist. +//--------------------------------------------------------------------------------------------- +if( !isObject( GuiDefaultProfile ) ) +new GuiControlProfile (GuiDefaultProfile) +{ + tab = false; + canKeyFocus = false; + hasBitmapArray = false; + mouseOverSelected = false; + + // fill color + opaque = false; + fillColor = "242 241 240"; + fillColorHL ="228 228 235"; + fillColorSEL = "98 100 137"; + fillColorNA = "255 255 255 "; + + // border color + border = 0; + borderColor = "100 100 100"; + borderColorHL = "50 50 50 50"; + borderColorNA = "75 75 75"; + + // font + fontType = "Arial"; + fontSize = 14; + fontCharset = ANSI; + + fontColor = "0 0 0"; + fontColorHL = "0 0 0"; + fontColorNA = "0 0 0"; + fontColorSEL= "255 255 255"; + + // bitmap information + bitmap = ""; + bitmapBase = ""; + textOffset = "0 0"; + + // used by guiTextControl + modal = true; + justify = "left"; + autoSizeWidth = false; + autoSizeHeight = false; + returnTab = false; + numbersOnly = false; + cursorColor = "0 0 0 255"; + + // sounds + //soundButtonDown = ""; + //soundButtonOver = ""; +}; + +if( !isObject( GuiSolidDefaultProfile ) ) +new GuiControlProfile (GuiSolidDefaultProfile) +{ + opaque = true; + border = true; + category = "Core"; +}; + +if( !isObject( GuiTransparentProfile ) ) +new GuiControlProfile (GuiTransparentProfile) +{ + opaque = false; + border = false; + category = "Core"; +}; + +if( !isObject( GuiTransparentwbProfile ) ) +new GuiControlProfile (GuiTransparentwbProfile) +{ + opaque = false; + border = true; + //fillcolor ="255 255 255"; + borderColor = "100 100 100"; + category = "Core"; +}; + +if( !isObject( GuiGroupBorderProfile ) ) +new GuiControlProfile( GuiGroupBorderProfile ) +{ + border = false; + opaque = false; + hasBitmapArray = true; + bitmap = "./images/group-border"; + category = "Core"; +}; + +if( !isObject( GuiTabBorderProfile ) ) +new GuiControlProfile( GuiTabBorderProfile ) +{ + border = false; + opaque = false; + hasBitmapArray = true; + bitmap = "./images/tab-border"; + category = "Core"; +}; + +if( !isObject( GuiGroupTitleProfile ) ) +new GuiControlProfile( GuiGroupTitleProfile ) +{ + fillColor = "242 241 240"; + fillColorHL ="242 241 240"; + fillColorNA = "242 241 240"; + fontColor = "0 0 0"; + opaque = true; + category = "Core"; +}; + +if( !isObject( GuiToolTipProfile ) ) +new GuiControlProfile (GuiToolTipProfile) +{ + // fill color + fillColor = "239 237 222"; + + // border color + borderColor = "138 134 122"; + + // font + fontType = "Arial"; + fontSize = 14; + fontColor = "0 0 0"; + + category = "Core"; +}; + +if( !isObject( GuiModelessDialogProfile ) ) +new GuiControlProfile( GuiModelessDialogProfile ) +{ + modal = false; + category = "Core"; +}; + +if( !isObject( GuiFrameSetProfile ) ) +new GuiControlProfile (GuiFrameSetProfile) +{ + fillcolor = "255 255 255";//GuiDefaultProfile.fillColor; + borderColor = "246 245 244"; + border = 1; + //fillColor = "240 239 238"; + //borderColor = "50 50 50";//"204 203 202"; + //fillColor = GuiDefaultProfile.fillColorNA; + //borderColor = GuiDefaultProfile.borderColorNA; + opaque = true; + border = true; + category = "Core"; +}; + + +if ($platform $= "macos") +{ + if( !isObject( GuiWindowProfile ) ) + new GuiControlProfile (GuiWindowProfile) + { + opaque = false; + border = 2; + fillColor = "242 241 240"; + fillColorHL = "221 221 221"; + fillColorNA = "200 200 200"; + fontColor = "50 50 50"; + fontColorHL = "0 0 0"; + bevelColorHL = "255 255 255"; + bevelColorLL = "0 0 0"; + text = "untitled"; + bitmap = "./images/window"; + textOffset = "8 4"; + hasBitmapArray = true; + justify = "center"; + category = "Core"; + }; +} +else { + + if( !isObject( GuiWindowProfile ) ) + new GuiControlProfile (GuiWindowProfile) + { + opaque = false; + border = 2; + fillColor = "242 241 240"; + fillColorHL = "221 221 221"; + fillColorNA = "200 200 200"; + fontColor = "50 50 50"; + fontColorHL = "0 0 0"; + bevelColorHL = "255 255 255"; + bevelColorLL = "0 0 0"; + text = "untitled"; + bitmap = "./images/window"; + textOffset = "8 4"; + hasBitmapArray = true; + justify = "left"; + category = "Core"; + }; +} + +if( !isObject( GuiToolbarWindowProfile ) ) +new GuiControlProfile(GuiToolbarWindowProfile : GuiWindowProfile) +{ + bitmap = "./images/toolbar-window"; + text = ""; + category = "Core"; +}; + +if( !isObject( GuiHToolbarWindowProfile ) ) +new GuiControlProfile (GuiHToolbarWindowProfile : GuiWindowProfile) +{ + bitmap = "./images/htoolbar-window"; + text = ""; + category = "Core"; +}; + +if( !isObject( GuiMenubarWindowProfile ) ) +new GuiControlProfile (GuiMenubarWindowProfile : GuiWindowProfile) +{ + bitmap = "./images/menubar-window"; + text = ""; + category = "Core"; +}; + +if( !isObject( GuiWindowCollapseProfile ) ) +new GuiControlProfile (GuiWindowCollapseProfile : GuiWindowProfile) +{ + category = "Core"; +}; + +if( !isObject( GuiControlProfile ) ) +new GuiControlProfile (GuiContentProfile) +{ + opaque = true; + fillColor = "255 255 255"; + category = "Core"; +}; + +if( !isObject( GuiBlackContentProfile ) ) +new GuiControlProfile (GuiBlackContentProfile) +{ + opaque = true; + fillColor = "0 0 0"; + category = "Core"; +}; + +if( !isObject( GuiInputCtrlProfile ) ) +new GuiControlProfile( GuiInputCtrlProfile ) +{ + tab = true; + canKeyFocus = true; + category = "Core"; +}; + +if( !isObject( GuiTextProfile ) ) +new GuiControlProfile (GuiTextProfile) +{ + justify = "left"; + fontColor = "20 20 20"; + category = "Core"; +}; + +if( !isObject( GuiTextBoldProfile ) ) +new GuiControlProfile (GuiTextBoldProfile : GuiTextProfile) +{ + fontType = "Arial Bold"; + fontSize = 16; + category = "Core"; +}; + +if( !isObject( GuiTextBoldCenterProfile ) ) +new GuiControlProfile (GuiTextBoldCenterProfile : GuiTextProfile) +{ + fontColor = "50 50 50"; + fontType = "Arial Bold"; + fontSize = 16; + justify = "center"; + category = "Core"; +}; + +if( !isObject( GuiTextRightProfile ) ) +new GuiControlProfile (GuiTextRightProfile : GuiTextProfile) +{ + justify = "right"; + category = "Core"; +}; + +if( !isObject( GuiTextCenterProfile ) ) +new GuiControlProfile (GuiTextCenterProfile : GuiTextProfile) +{ + justify = "center"; + category = "Core"; +}; + +if( !isObject( GuiTextSolidProfile ) ) +new GuiControlProfile (GuiTextSolidProfile : GuiTextProfile) +{ + opaque = true; + border = 5; + borderColor = GuiDefaultProfile.fillColor; + category = "Core"; +}; + +if( !isObject( InspectorTitleTextProfile ) ) +new GuiControlProfile (InspectorTitleTextProfile) +{ + fontColor = "100 100 100"; + category = "Core"; +}; + +if( !isObject( GuiTextProfileLight ) ) +new GuiControlProfile (GuiTextProfileLight) +{ + fontColor = "220 220 220"; + category = "Core"; +}; + +if( !isObject( GuiAutoSizeTextProfile ) ) +new GuiControlProfile (GuiAutoSizeTextProfile) +{ + fontColor = "0 0 0"; + autoSizeWidth = true; + autoSizeHeight = true; + category = "Core"; +}; + +if( !isObject( GuiTextRightProfile ) ) +new GuiControlProfile (GuiTextRightProfile : GuiTextProfile) +{ + justify = "right"; + category = "Core"; +}; + +if( !isObject( GuiMediumTextProfile ) ) +new GuiControlProfile( GuiMediumTextProfile : GuiTextProfile ) +{ + fontSize = 24; + category = "Core"; +}; + +if( !isObject( GuiBigTextProfile ) ) +new GuiControlProfile( GuiBigTextProfile : GuiTextProfile ) +{ + fontSize = 36; + category = "Core"; +}; + +if( !isObject( GuiMLTextProfile ) ) +new GuiControlProfile( GuiMLTextProfile ) +{ + fontColorLink = "100 100 100"; + fontColorLinkHL = "255 255 255"; + autoSizeWidth = true; + autoSizeHeight = true; + border = false; + category = "Core"; +}; + +if( !isObject( GuiTextArrayProfile ) ) +new GuiControlProfile( GuiTextArrayProfile : GuiTextProfile ) +{ + fontColor = "50 50 50"; + fontColorHL = " 0 0 0"; + fontColorSEL = "0 0 0"; + fillColor ="200 200 200"; + fillColorHL = "228 228 235"; + fillColorSEL = "200 200 200"; + border = false; + category = "Core"; +}; + +if( !isObject( GuiTextListProfile ) ) +new GuiControlProfile( GuiTextListProfile : GuiTextProfile ) +{ + tab = true; + canKeyFocus = true; + category = "Core"; +}; + +if( !isObject( GuiTextEditProfile ) ) +new GuiControlProfile( GuiTextEditProfile ) +{ + opaque = true; + bitmap = "./images/textEdit"; + hasBitmapArray = true; + border = -2; // fix to display textEdit img + //borderWidth = "1"; // fix to display textEdit img + //borderColor = "100 100 100"; + fillColor = "242 241 240 0"; + fillColorHL = "255 255 255"; + fontColor = "0 0 0"; + fontColorHL = "255 255 255"; + fontColorSEL = "98 100 137"; + fontColorNA = "200 200 200"; + textOffset = "4 2"; + autoSizeWidth = false; + autoSizeHeight = true; + justify = "left"; + tab = true; + canKeyFocus = true; + category = "Core"; +}; + +if( !isObject( GuiTreeViewRenameCtrlProfile ) ) +new GuiControlProfile( GuiTreeViewRenameCtrlProfile : GuiTextEditProfile ) +{ + returnTab = true; + category = "Core"; +}; + +if( !isObject( GuiTextEditProfileNumbersOnly ) ) +new GuiControlProfile( GuiTextEditProfileNumbersOnly : GuiTextEditProfile ) +{ + numbersOnly = true; + category = "Core"; +}; + +if( !isObject( GuiTextEditNumericProfile ) ) +new GuiControlProfile( GuiTextEditNumericProfile : GuiTextEditProfile ) +{ + numbersOnly = true; + category = "Core"; +}; + +if( !isObject( GuiNumericDropSliderTextProfile ) ) +new GuiControlProfile( GuiNumericDropSliderTextProfile : GuiTextEditProfile ) +{ + bitmap = "./images/textEditSliderBox"; + category = "Core"; +}; + +if( !isObject( GuiTextEditDropSliderNumbersOnly ) ) +new GuiControlProfile( GuiTextEditDropSliderNumbersOnly : GuiTextEditProfile ) +{ + numbersOnly = true; + bitmap = "./images/textEditSliderBox"; + category = "Core"; +}; + +if( !isObject( GuiProgressProfile ) ) +new GuiControlProfile( GuiProgressProfile ) +{ + opaque = false; + fillColor = "0 162 255 200"; + border = true; + borderColor = "50 50 50 200"; + category = "Core"; +}; + +if( !isObject( GuiProgressBitmapProfile ) ) +new GuiControlProfile( GuiProgressBitmapProfile ) +{ + border = false; + hasBitmapArray = true; + bitmap = "./images/loadingbar"; + category = "Core"; +}; + +if( !isObject( GuiRLProgressBitmapProfile ) ) +new GuiControlProfile( GuiRLProgressBitmapProfile ) +{ + border = false; + hasBitmapArray = true; + bitmap = "./images/rl-loadingbar"; + category = "Core"; +}; + +if( !isObject( GuiProgressTextProfile ) ) +new GuiControlProfile( GuiProgressTextProfile ) +{ + fontSize = "14"; + fontType = "Arial"; + fontColor = "0 0 0"; + justify = "center"; + category = "Core"; +}; + +if( !isObject( GuiButtonProfile ) ) +new GuiControlProfile( GuiButtonProfile ) +{ + opaque = true; + border = true; + + fontColor = "50 50 50"; + fontColorHL = "0 0 0"; + fontColorNA = "200 200 200"; + //fontColorSEL ="0 0 0"; + fixedExtent = false; + justify = "center"; + canKeyFocus = false; + bitmap = "./images/button"; + hasBitmapArray = false; + category = "Core"; +}; + +if( !isObject( GuiThumbHighlightButtonProfile ) ) +new GuiControlProfile( GuiThumbHighlightButtonProfile : GuiButtonProfile ) +{ + bitmap = "./images/thumbHightlightButton"; + category = "Core"; +}; + +if( !isObject( InspectorDynamicFieldButton ) ) +new GuiControlProfile( InspectorDynamicFieldButton : GuiButtonProfile ) +{ + canKeyFocus = true; + category = "Core"; +}; + +if( !isObject( GuiMenuButtonProfile ) ) +new GuiControlProfile( GuiMenuButtonProfile ) +{ + opaque = true; + border = false; + fontSize = 18; + fontType = "Arial Bold"; + fontColor = "50 50 50"; + fontColorHL = "0 0 0"; + fontColorNA = "200 200 200"; + //fontColorSEL ="0 0 0"; + fixedExtent = false; + justify = "center"; + canKeyFocus = false; + bitmap = "./images/selector-button"; + hasBitmapArray = false; + category = "Core"; +}; + +if( !isObject( GuiIconButtonProfile ) ) +new GuiControlProfile( GuiIconButtonProfile ) +{ + opaque = true; + border = true; + + fontColor = "50 50 50"; + fontColorHL = "0 0 0"; + fontColorNA = "200 200 200"; + //fontColorSEL ="0 0 0"; + fixedExtent = false; + justify = "center"; + canKeyFocus = false; + bitmap = "./images/iconbutton"; + hasBitmapArray = true; + category = "Core"; +}; + +if( !isObject( GuiIconButtonSolidProfile ) ) +new GuiControlProfile( GuiIconButtonSolidProfile : GuiIconButtonProfile ) +{ + bitmap = "./images/iconbuttonsolid"; + category = "Core"; +}; + +if( !isObject( GuiIconButtonSmallProfile ) ) +new GuiControlProfile( GuiIconButtonSmallProfile : GuiIconButtonProfile ) +{ + bitmap = "./images/iconbuttonsmall"; + category = "Core"; +}; + +if( !isObject( GuiButtonTabProfile ) ) +new GuiControlProfile( GuiButtonTabProfile ) +{ + opaque = true; + border = true; + + fontColor = "50 50 50"; + fontColorHL = "0 0 0"; + fontColorNA = "0 0 0"; + //fontColorSEL ="0 0 0"; + fixedExtent = false; + justify = "center"; + canKeyFocus = false; + bitmap = "./images/buttontab"; + // hasBitmapArray = false; + category = "Core"; +}; + +if( !isObject( EditorTabPage ) ) +new GuiControlProfile(EditorTabPage) +{ + opaque = true; + border = false; + //fontSize = 18; + //fontType = "Arial"; + fontColor = "0 0 0"; + fontColorHL = "0 0 0"; + fixedExtent = false; + justify = "center"; + canKeyFocus = false; + bitmap = "./images/tab"; + hasBitmapArray = true; //false; + category = "Core"; +}; + +if( !isObject( GuiCheckBoxProfile ) ) +new GuiControlProfile( GuiCheckBoxProfile ) +{ + opaque = false; + fillColor = "232 232 232"; + border = false; + borderColor = "100 100 100"; + fontSize = 14; + fontColor = "20 20 20"; + fontColorHL = "80 80 80"; + fontColorNA = "200 200 200"; + fixedExtent = true; + justify = "left"; + bitmap = "./images/checkbox"; + hasBitmapArray = true; + category = "Core"; +}; + +if( !isObject( GuiCheckBoxListProfile ) ) +new GuiControlProfile( GuiCheckBoxListProfile : GuiCheckBoxProfile) +{ + bitmap = "./images/checkbox-list"; + category = "Core"; +}; + +if( !isObject( GuiCheckBoxListFlipedProfile ) ) +new GuiControlProfile( GuiCheckBoxListFlipedProfile : GuiCheckBoxProfile) +{ + bitmap = "./images/checkbox-list_fliped"; + category = "Core"; +}; + +if( !isObject( InspectorCheckBoxTitleProfile ) ) +new GuiControlProfile( InspectorCheckBoxTitleProfile : GuiCheckBoxProfile ){ + fontColor = "100 100 100"; + category = "Core"; +}; + +if( !isObject( GuiRadioProfile ) ) +new GuiControlProfile( GuiRadioProfile ) +{ + fontSize = 14; + fillColor = "232 232 232"; + /*fontColor = "200 200 200"; + fontColorHL = "255 255 255";*/ + fontColor = "20 20 20"; + fontColorHL = "80 80 80"; + fixedExtent = true; + bitmap = "./images/radioButton"; + hasBitmapArray = true; + category = "Core"; +}; + +if( !isObject( GuiScrollProfile ) ) +new GuiControlProfile( GuiScrollProfile ) +{ + opaque = true; + fillcolor = "255 255 255"; + fontColor = "0 0 0"; + fontColorHL = "150 150 150"; + //borderColor = GuiDefaultProfile.borderColor; + border = true; + bitmap = "./images/scrollBar"; + hasBitmapArray = true; + category = "Core"; +}; + +if( !isObject( GuiOverlayProfile ) ) +new GuiControlProfile( GuiOverlayProfile ) +{ + opaque = true; + fillcolor = "255 255 255"; + fontColor = "0 0 0"; + fontColorHL = "255 255 255"; + fillColor = "0 0 0 100"; + category = "Core"; +}; + +if( !isObject( GuiTransparentScrollProfile ) ) +new GuiControlProfile( GuiTransparentScrollProfile ) +{ + opaque = false; + fillColor = "255 255 255"; + fontColor = "0 0 0"; + border = false; + borderThickness = 2; + borderColor = "100 100 100"; + bitmap = "./images/scrollBar"; + hasBitmapArray = true; + category = "Core"; +}; + +if( !isObject( GuiSliderProfile ) ) +new GuiControlProfile( GuiSliderProfile ) +{ + bitmap = "./images/slider"; + category = "Core"; +}; + +if( !isObject( GuiSliderBoxProfile ) ) +new GuiControlProfile( GuiSliderBoxProfile ) +{ + bitmap = "./images/slider-w-box"; + category = "Core"; +}; + +if( !isObject( GuiPaneProfile ) ) +new GuiControlProfile( GuiPaneProfile ) +{ + bitmap = "./images/popupMenu"; + hasBitmapArray = true; + category = "Core"; +}; + +if( !isObject( GuiPopupMenuItemBorder ) ) +new GuiControlProfile( GuiPopupMenuItemBorder : GuiButtonProfile ) +{ + // borderThickness = 1; + //borderColor = "100 100 100 220"; //200 + //borderColorHL = "51 51 51 220"; //200 + + opaque = true; + border = true; + + fontColor = "0 0 0"; + fontColorHL = "0 0 0"; + fontColorNA = "255 255 255"; + fixedExtent = false; + justify = "center"; + canKeyFocus = false; + bitmap = "./images/button"; + // hasBitmapArray = false; + + category = "Core"; +}; + +if( !isObject( GuiPopUpMenuDefault ) ) +new GuiControlProfile( GuiPopUpMenuDefault : GuiDefaultProfile ) +{ + opaque = true; + mouseOverSelected = true; + textOffset = "3 3"; + border = 0; + borderThickness = 0; + fixedExtent = true; + bitmap = "./images/scrollbar"; + hasBitmapArray = true; + profileForChildren = GuiPopupMenuItemBorder; + fillColor = "242 241 240 ";//"255 255 255";//100 + fillColorHL = "228 228 235 ";//"204 203 202"; + fillColorSEL = "98 100 137 ";//"204 203 202"; + // font color is black + fontColorHL = "0 0 0 ";//"0 0 0"; + fontColorSEL = "255 255 255";//"0 0 0"; + borderColor = "100 100 100"; + category = "Core"; +}; + +if( !isObject( GuiPopupBackgroundProfile ) ) +new GuiControlProfile( GuiPopupBackgroundProfile ) +{ + modal = true; + category = "Core"; +}; + +if( !isObject( GuiPopUpMenuProfile ) ) +new GuiControlProfile( GuiPopUpMenuProfile : GuiPopUpMenuDefault ) +{ + textOffset = "6 4"; + bitmap = "./images/dropDown"; + hasBitmapArray = true; + border = 1; + profileForChildren = GuiPopUpMenuDefault; + category = "Core"; +}; + +if( !isObject( GuiPopUpMenuTabProfile ) ) +new GuiControlProfile( GuiPopUpMenuTabProfile : GuiPopUpMenuDefault ) +{ + bitmap = "./images/dropDown-tab"; + textOffset = "6 4"; + canKeyFocus = true; + hasBitmapArray = true; + border = 1; + profileForChildren = GuiPopUpMenuDefault; + category = "Core"; +}; + +if( !isObject( GuiPopUpMenuEditProfile ) ) +new GuiControlProfile( GuiPopUpMenuEditProfile : GuiPopUpMenuDefault ) +{ + textOffset = "6 4"; + canKeyFocus = true; + bitmap = "./images/dropDown"; + hasBitmapArray = true; + border = 1; + profileForChildren = GuiPopUpMenuDefault; + category = "Core"; +}; + +if( !isObject( GuiListBoxProfile ) ) +new GuiControlProfile( GuiListBoxProfile ) +{ + tab = true; + canKeyFocus = true; + category = "Core"; +}; + +if( !isObject( GuiTabBookProfile ) ) +new GuiControlProfile( GuiTabBookProfile ) +{ + fillColorHL = "100 100 100"; + fillColorNA = "150 150 150"; + fontColor = "30 30 30"; + fontColorHL = "0 0 0"; + fontColorNA = "50 50 50"; + fontType = "Arial"; + fontSize = 14; + justify = "center"; + bitmap = "./images/tab"; + tabWidth = 64; + tabHeight = 24; + tabPosition = "Top"; + tabRotation = "Horizontal"; + textOffset = "0 -3"; + tab = true; + cankeyfocus = true; + //border = false; + //opaque = false; + category = "Core"; +}; + +if( !isObject( GuiTabBookNoBitmapProfile ) ) +new GuiControlProfile( GuiTabBookNoBitmapProfile : GuiTabBookProfile ) +{ + bitmap = ""; + category = "Core"; +}; + +if( !isObject( GuiTabPageProfile ) ) +new GuiControlProfile( GuiTabPageProfile : GuiDefaultProfile ) +{ + fontType = "Arial"; + fontSize = 10; + justify = "center"; + bitmap = "./images/tab"; + opaque = false; + fillColor = "240 239 238"; + category = "Core"; +}; + +if( !isObject( GuiMenuBarProfile ) ) +new GuiControlProfile( GuiMenuBarProfile ) +{ + fontType = "Arial"; + fontSize = 14; + opaque = true; + fillColor = "240 239 238"; + fillColorHL = "202 201 200"; + fillColorSEL = "202 0 0"; + + borderColorNA = "202 201 200"; + borderColorHL = "50 50 50"; + border = 0; + fontColor = "20 20 20"; + fontColorHL = "0 0 0"; + fontColorNA = "255 255 255"; + //fixedExtent = true; + justify = "center"; + canKeyFocus = false; + mouseOverSelected = true; + bitmap = "./images/menu"; + hasBitmapArray = true; + category = "Core"; +}; + +if( !isObject( GuiConsoleProfile ) ) +new GuiControlProfile( GuiConsoleProfile ) +{ + fontType = ($platform $= "macos") ? "Monaco" : "Lucida Console"; + fontSize = ($platform $= "macos") ? 13 : 12; + fontColor = "255 255 255"; + fontColorHL = "0 255 255"; + fontColorNA = "255 0 0"; + fontColors[6] = "100 100 100"; + fontColors[7] = "100 100 0"; + fontColors[8] = "0 0 100"; + fontColors[9] = "0 100 0"; + category = "Core"; +}; + +if( !isObject( GuiConsoleTextEditProfile ) ) +new GuiControlProfile( GuiConsoleTextEditProfile : GuiTextEditProfile ) +{ + fontType = ($platform $= "macos") ? "Monaco" : "Lucida Console"; + fontSize = ($platform $= "macos") ? 13 : 12; + category = "Core"; +}; + +if( !isObject( GuiConsoleTextProfile ) ) +new GuiControlProfile( GuiConsoleTextProfile ) +{ + fontColor = "0 0 0"; + autoSizeWidth = true; + autoSizeHeight = true; + + textOffset = "2 2"; + opaque = true; + fillColor = "255 255 255"; + border = true; + borderThickness = 1; + borderColor = "0 0 0"; + category = "Core"; +}; + +if( !isObject( GuiTreeViewProfile ) ) +new GuiControlProfile( GuiTreeViewProfile ) +{ + bitmap = "./images/treeView"; + autoSizeHeight = true; + canKeyFocus = true; + + fillColor = "255 255 255"; //GuiDefaultProfile.fillColor; + fillColorHL = "228 228 235";//GuiDefaultProfile.fillColorHL; + fillColorSEL = "98 100 137"; + fillColorNA = "255 255 255";//GuiDefaultProfile.fillColorNA; + fontColor = "0 0 0";//GuiDefaultProfile.fontColor; + fontColorHL = "0 0 0";//GuiDefaultProfile.fontColorHL; + fontColorSEL= "255 255 255";//GuiDefaultProfile.fontColorSEL; + fontColorNA = "200 200 200";//GuiDefaultProfile.fontColorNA; + borderColor = "128 000 000"; + borderColorHL = "255 228 235"; + + fontSize = 14; + + opaque = false; + border = false; + category = "Core"; +}; + +if( !isObject( GuiSimpleTreeProfile ) ) +new GuiControlProfile( GuiSimpleTreeProfile : GuiTreeViewProfile ) +{ + opaque = true; + fillColor = "255 255 255 255"; + border = true; + category = "Core"; +}; + +if( !isObject( GuiText24Profile ) ) +new GuiControlProfile( GuiText24Profile : GuiTextProfile ) +{ + fontSize = 24; + category = "Core"; +}; + +if( !isObject( GuiRSSFeedMLTextProfile ) ) +new GuiControlProfile( GuiRSSFeedMLTextProfile ) +{ + fontColorLink = "55 55 255"; + fontColorLinkHL = "255 55 55"; + category = "Core"; +}; + +$ConsoleDefaultFillColor = "0 0 0 175"; + +if( !isObject( ConsoleScrollProfile ) ) +new GuiControlProfile( ConsoleScrollProfile : GuiScrollProfile ) +{ + opaque = true; + fillColor = $ConsoleDefaultFillColor; + border = 1; + //borderThickness = 0; + borderColor = "0 0 0"; + category = "Core"; +}; + +if( !isObject( ConsoleTextEditProfile ) ) +new GuiControlProfile( ConsoleTextEditProfile : GuiTextEditProfile ) +{ + fillColor = "242 241 240 255"; + fillColorHL = "255 255 255"; + category = "Core"; +}; + +if( !isObject( GuiTextPadProfile ) ) +new GuiControlProfile( GuiTextPadProfile ) +{ + fontType = ($platform $= "macos") ? "Monaco" : "Lucida Console"; + fontSize = ($platform $= "macos") ? 13 : 12; + tab = true; + canKeyFocus = true; + + // Deviate from the Default + opaque=true; + fillColor = "255 255 255"; + + border = 0; + category = "Core"; +}; + +if( !isObject( GuiTransparentProfileModeless ) ) +new GuiControlProfile( GuiTransparentProfileModeless : GuiTransparentProfile ) +{ + modal = false; + category = "Core"; +}; + +if( !isObject( GuiFormProfile ) ) +new GuiControlProfile( GuiFormProfile : GuiTextProfile ) +{ + opaque = false; + border = 5; + + bitmap = "./images/form"; + hasBitmapArray = true; + + justify = "center"; + + profileForChildren = GuiButtonProfile; + + // border color + opaque = false; + //border = 5; + bitmap = "./images/button"; + // borderColor = "153 153 153"; + // borderColorHL = "230 230 230"; + // borderColorNA = "126 79 37"; + category = "Core"; +}; + +if( !isObject( GuiNumericTextEditSliderProfile ) ) +new GuiControlProfile( GuiNumericTextEditSliderProfile ) +{ + // Transparent Background + opaque = true; + fillColor = "0 0 0 0"; + fillColorHL = "255 255 255"; + + border = true; + + tab = false; + canKeyFocus = true; + + // font + fontType = "Arial"; + fontSize = 14; + + fontColor = "0 0 0"; + fontColorSEL = "43 107 206"; + fontColorHL = "244 244 244"; + fontColorNA = "100 100 100"; + + numbersOnly = true; + category = "Core"; +}; + +if( !isObject( GuiNumericTextEditSliderBitmapProfile ) ) +new GuiControlProfile( GuiNumericTextEditSliderBitmapProfile ) +{ + // Transparent Background + opaque = true; + + border = true; + borderColor = "100 100 100"; + + tab = false; + canKeyFocus = true; + + // font + fontType = "Arial"; + fontSize = 14; + + fillColor = "242 241 240";//"255 255 255"; + fillColorHL = "255 255 255";//"222 222 222"; + fontColor = "0 0 0";//"0 0 0"; + fontColorHL = "255 255 255";//"0 0 0"; + fontColorSEL = "98 100 137";//"230 230 230"; + fontColorNA = "200 200 200";//"0 0 0"; + + numbersOnly = true; + + hasBitmapArray = true; + bitmap = "./images/numericslider"; + category = "Core"; +}; + +if( !isObject( GuiMultiFieldTextEditProfile ) ) +new GuiControlProfile( GuiMultiFieldTextEditProfile : GuiTextEditProfile ) +{ + category = "Core"; +}; + +if( !isObject( GuiModalDialogBackgroundProfile ) ) +new GuiControlProfile( GuiModalDialogBackgroundProfile ) +{ + opaque = true; + fillColor = "221 221 221 150"; + category = "Core"; +}; + +//----------------------------------------------------------------------------- +// Center and bottom print +//----------------------------------------------------------------------------- + +if( !isObject( CenterPrintProfile ) ) +new GuiControlProfile ( CenterPrintProfile ) +{ + opaque = false; + fillColor = "128 128 128"; + fontColor = "0 255 0"; + border = true; + borderColor = "0 255 0"; + category = "Core"; +}; + +if( !isObject( CenterPrintTextProfile ) ) +new GuiControlProfile ( CenterPrintTextProfile ) +{ + opaque = false; + fontType = "Arial"; + fontSize = 12; + fontColor = "0 255 0"; + category = "Core"; +}; diff --git a/Templates/Empty/game/core/art/gui/remapDlg.gui b/Templates/Empty/game/core/art/gui/remapDlg.gui new file mode 100644 index 000000000..d14fec661 --- /dev/null +++ b/Templates/Empty/game/core/art/gui/remapDlg.gui @@ -0,0 +1,90 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(RemapDlg) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + helpTag = "0"; + + new GuiWindowCtrl() { + text = "Remap Control"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "1"; + canMaximize = "1"; + canCollapse = "0"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "390 352"; + extent = "243 64"; + minExtent = "8 8"; + horizSizing = "center"; + vertSizing = "center"; + profile = "GuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Re-bind control to..."; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "49 32"; + extent = "144 20"; + minExtent = "8 8"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "OptRemapText"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiInputCtrl(OptRemapInputCtrl) { + lockMouse = "0"; + position = "0 0"; + extent = "64 64"; + minExtent = "8 8"; + horizSizing = "center"; + vertSizing = "bottom"; + profile = "GuiInputCtrlProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/core/art/materials.cs b/Templates/Empty/game/core/art/materials.cs new file mode 100644 index 000000000..c7db049da --- /dev/null +++ b/Templates/Empty/game/core/art/materials.cs @@ -0,0 +1,54 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +singleton Material( DefaultDecalRoadMaterial ) +{ + diffuseMap[0] = "core/art/defaultRoadTextureTop.png"; + mapTo = "unmapped_mat"; + materialTag0 = "RoadAndPath"; +}; + +singleton Material( BlankWhite ) +{ + diffuseMap[0] = "core/art/white"; + mapTo = "white"; + materialTag0 = "Miscellaneous"; +}; + +singleton Material( Empty ) +{ +}; + +singleton Material(DefaultRoadMaterialTop) +{ + mapTo = "unmapped_mat"; + diffuseMap[0] = "core/art/defaultRoadTextureTop.png"; + materialTag0 = "RoadAndPath"; +}; + +singleton Material(DefaultRoadMaterialOther) +{ + mapTo = "unmapped_mat"; + diffuseMap[0] = "core/art/defaultRoadTextureOther.png"; + materialTag0 = "RoadAndPath"; +}; + diff --git a/Templates/Empty/game/core/art/missingTexture.png b/Templates/Empty/game/core/art/missingTexture.png new file mode 100644 index 000000000..80a7874da Binary files /dev/null and b/Templates/Empty/game/core/art/missingTexture.png differ diff --git a/Templates/Empty/game/core/art/shapes/.gitignore b/Templates/Empty/game/core/art/shapes/.gitignore new file mode 100644 index 000000000..cbdc49d44 --- /dev/null +++ b/Templates/Empty/game/core/art/shapes/.gitignore @@ -0,0 +1,5 @@ +# Allow the following 3D mesh file formats in this directory: +!*.obj +!*.mtl +!*.3ds +!*.max diff --git a/Templates/Empty/game/core/art/shapes/base-normal.png b/Templates/Empty/game/core/art/shapes/base-normal.png new file mode 100644 index 000000000..27ed35fcd Binary files /dev/null and b/Templates/Empty/game/core/art/shapes/base-normal.png differ diff --git a/Templates/Empty/game/core/art/shapes/base.png b/Templates/Empty/game/core/art/shapes/base.png new file mode 100644 index 000000000..34ac6baa2 Binary files /dev/null and b/Templates/Empty/game/core/art/shapes/base.png differ diff --git a/Templates/Empty/game/core/art/shapes/blue.jpg b/Templates/Empty/game/core/art/shapes/blue.jpg new file mode 100644 index 000000000..b6fcd4e66 Binary files /dev/null and b/Templates/Empty/game/core/art/shapes/blue.jpg differ diff --git a/Templates/Empty/game/core/art/shapes/camera.dts b/Templates/Empty/game/core/art/shapes/camera.dts new file mode 100644 index 000000000..fdd5dbbe0 Binary files /dev/null and b/Templates/Empty/game/core/art/shapes/camera.dts differ diff --git a/Templates/Empty/game/core/art/shapes/camera.mb b/Templates/Empty/game/core/art/shapes/camera.mb new file mode 100644 index 000000000..641f1c1b6 Binary files /dev/null and b/Templates/Empty/game/core/art/shapes/camera.mb differ diff --git a/Templates/Empty/game/core/art/shapes/camera.png b/Templates/Empty/game/core/art/shapes/camera.png new file mode 100644 index 000000000..4cde4fe67 Binary files /dev/null and b/Templates/Empty/game/core/art/shapes/camera.png differ diff --git a/Templates/Empty/game/core/art/shapes/green.jpg b/Templates/Empty/game/core/art/shapes/green.jpg new file mode 100644 index 000000000..c95126226 Binary files /dev/null and b/Templates/Empty/game/core/art/shapes/green.jpg differ diff --git a/Templates/Empty/game/core/art/shapes/lightray.png b/Templates/Empty/game/core/art/shapes/lightray.png new file mode 100644 index 000000000..1f3ed83ba Binary files /dev/null and b/Templates/Empty/game/core/art/shapes/lightray.png differ diff --git a/Templates/Empty/game/core/art/shapes/materials.cs b/Templates/Empty/game/core/art/shapes/materials.cs new file mode 100644 index 000000000..f413f54b0 --- /dev/null +++ b/Templates/Empty/game/core/art/shapes/materials.cs @@ -0,0 +1,161 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +singleton Material(OctahedronMat) +{ + mapTo = "green"; + + diffuseMap[0] = "camera"; + + translucent = "1"; + translucentBlendOp = "LerpAlpha"; + emissive = "0"; + castShadows = "0"; + + colorMultiply[0] = "0 1 0 1"; +}; + +singleton Material(SimpleConeMat) +{ + mapTo = "blue"; + + diffuseMap[0] = "blue"; + translucent = "0"; + emissive = "1"; + castShadows = "0"; +}; + +//--- camera.dts MATERIALS BEGIN --- +singleton Material(CameraMat) +{ + mapTo = "pasted__phongE1"; + + diffuseMap[0] = "camera"; + + diffuseColor[0] = "0 0.627451 1 1"; + specular[0] = "1 1 1 1"; + specularPower[0] = 211; + pixelSpecular[0] = 1; + emissive[0] = 1; + + doubleSided = 1; + translucent = true; + translucentBlendOp = "LerpAlpha"; + castShadows = false; + materialTag0 = "Miscellaneous"; +}; + +//--- camera.dts MATERIALS END --- +//--- noshape.dts MATERIALS BEGIN --- +singleton Material(noshape_NoShape) +{ + mapTo = "NoShape"; + + diffuseMap[0] = ""; + + diffuseColor[0] = "0.8 0.003067 0 .8"; + emissive[0] = 0; + + doubleSided = false; + translucent = 1; + translucentBlendOp = "LerpAlpha"; + castShadows = false; +}; + +//--- noshape.dts MATERIALS END --- + +//--- noshapetext.dae MATERIALS BEGIN --- +singleton Material(noshapetext_lambert1) +{ + mapTo = "lambert1"; + + diffuseMap[0] = ""; + + diffuseColor[0] = "0.4 0.4 0.4 1"; + specular[0] = "1 1 1 1"; + specularPower[0] = 8; + pixelSpecular[0] = false; + emissive[0] = true; + + doubleSided = false; + translucent = false; + translucentBlendOp = "None"; +}; + +singleton Material(noshapetext_noshape_mat) +{ + mapTo = "noshape_mat"; + + diffuseMap[0] = ""; + + diffuseColor[0] = "0.4 0.3504 0.363784 0.33058"; + specular[0] = "1 1 1 1"; + specularPower[0] = 8; + pixelSpecular[0] = false; + emissive[0] = true; + + doubleSided = false; + translucent = true; + translucentBlendOp = "None"; +}; + +//--- noshapetext.dae MATERIALS END --- + +//--- portal MATERIALS BEGIN --- + +singleton Material(portal5_portal_top) +{ + mapTo = "portal_top"; + + diffuseMap[0] = "top"; + normalMap[0] = "top-normal"; + + diffuseColor[0] = "0.4 0.4 0.4 1"; + specular[0] = "0.5 0.5 0.5 1"; + specularPower[0] = 2; + pixelSpecular[0] = false; + emissive[0] = true; + + doubleSided = false; + translucent = false; + translucentBlendOp = "None"; +}; + +singleton Material(portal5_portal_lightray) +{ + mapTo = "portal_lightray"; + + diffuseMap[0] = "lightray"; + + diffuseColor[0] = "0.4 0.4 0.4 0.64462"; + specular[0] = "0.5 0.5 0.5 1"; + specularPower[0] = 2; + pixelSpecular[0] = false; + emissive[0] = true; + + doubleSided = 1; + translucent = true; + translucentBlendOp = "AddAlpha"; + castShadows = "0"; +}; +//--- portal MATERIALS END --- + diff --git a/Templates/Empty/game/core/art/shapes/noshape.dts b/Templates/Empty/game/core/art/shapes/noshape.dts new file mode 100644 index 000000000..a7a64cf10 Binary files /dev/null and b/Templates/Empty/game/core/art/shapes/noshape.dts differ diff --git a/Templates/Empty/game/core/art/shapes/noshape.mb b/Templates/Empty/game/core/art/shapes/noshape.mb new file mode 100644 index 000000000..24330c1db Binary files /dev/null and b/Templates/Empty/game/core/art/shapes/noshape.mb differ diff --git a/Templates/Empty/game/core/art/shapes/octahedron.3ds b/Templates/Empty/game/core/art/shapes/octahedron.3ds new file mode 100644 index 000000000..e4004f283 Binary files /dev/null and b/Templates/Empty/game/core/art/shapes/octahedron.3ds differ diff --git a/Templates/Empty/game/core/art/shapes/octahedron.dts b/Templates/Empty/game/core/art/shapes/octahedron.dts new file mode 100644 index 000000000..c10f96663 Binary files /dev/null and b/Templates/Empty/game/core/art/shapes/octahedron.dts differ diff --git a/Templates/Empty/game/core/art/shapes/octahedron.max b/Templates/Empty/game/core/art/shapes/octahedron.max new file mode 100644 index 000000000..36a1aef66 Binary files /dev/null and b/Templates/Empty/game/core/art/shapes/octahedron.max differ diff --git a/Templates/Empty/game/core/art/shapes/portal.dts b/Templates/Empty/game/core/art/shapes/portal.dts new file mode 100644 index 000000000..edbd851c7 Binary files /dev/null and b/Templates/Empty/game/core/art/shapes/portal.dts differ diff --git a/Templates/Empty/game/core/art/shapes/simplecone.3ds b/Templates/Empty/game/core/art/shapes/simplecone.3ds new file mode 100644 index 000000000..090cb5d93 Binary files /dev/null and b/Templates/Empty/game/core/art/shapes/simplecone.3ds differ diff --git a/Templates/Empty/game/core/art/shapes/simplecone.dts b/Templates/Empty/game/core/art/shapes/simplecone.dts new file mode 100644 index 000000000..ed356132d Binary files /dev/null and b/Templates/Empty/game/core/art/shapes/simplecone.dts differ diff --git a/Templates/Empty/game/core/art/shapes/simplecone.mtl b/Templates/Empty/game/core/art/shapes/simplecone.mtl new file mode 100644 index 000000000..4e946ac63 --- /dev/null +++ b/Templates/Empty/game/core/art/shapes/simplecone.mtl @@ -0,0 +1,10 @@ +newmtl simplecone +Ka 0 0 0 +Kd 0 0.501961 0.752941 +Ks 0 0 0 +Ni 1 +Ns 400 +Tf 1 1 1 +d 1 +map_Kd blue.jpg + diff --git a/Templates/Empty/game/core/art/shapes/simplecone.obj b/Templates/Empty/game/core/art/shapes/simplecone.obj new file mode 100644 index 000000000..43a193001 --- /dev/null +++ b/Templates/Empty/game/core/art/shapes/simplecone.obj @@ -0,0 +1,35 @@ +#### +# +# OBJ File Generated by LightWave3D +# LightWave3D OBJ Export v2.3 +# +#### +o simplecone.obj +mtllib simplecone.mtl +g default +v -0.649519 -0.375 0.25 +v 0 0 -1.25 +v 0 0.75 0.25 +v 0.649519 -0.375 0.25 +vt 0.00874126 0.463343 +vt 0.00879765 0.00874126 +vt 0.00879765 0.445804 +vt 0.227273 0.991202 +vt 0.445804 0.463343 +vt 0.463343 0.463287 +vt 0.463343 0.90035 +vt 0.536657 0.154429 +vt 0.554196 0.00874126 +vt 0.772727 0.445804 +vt 0.991202 0.608974 +vt 0.991259 0.00874126 +vn -0.764951 -0.441644 0.468829 +vn 0 0 -1 +vn 0 0.883289 0.468829 +vn 0.764951 -0.441644 0.468829 +usemtl simplecone +s off +f 1/9/1 4/12/4 3/10/3 +f 2/8/2 3/3/3 4/2/4 +f 1/1/1 2/4/2 4/5/4 +f 3/7/3 2/11/2 1/6/1 diff --git a/Templates/Empty/game/core/art/shapes/top-normal.png b/Templates/Empty/game/core/art/shapes/top-normal.png new file mode 100644 index 000000000..30e35fedb Binary files /dev/null and b/Templates/Empty/game/core/art/shapes/top-normal.png differ diff --git a/Templates/Empty/game/core/art/shapes/top.png b/Templates/Empty/game/core/art/shapes/top.png new file mode 100644 index 000000000..0ceb304da Binary files /dev/null and b/Templates/Empty/game/core/art/shapes/top.png differ diff --git a/Templates/Empty/game/core/art/shapes/unit_capsule.dts b/Templates/Empty/game/core/art/shapes/unit_capsule.dts new file mode 100644 index 000000000..bc9483fac Binary files /dev/null and b/Templates/Empty/game/core/art/shapes/unit_capsule.dts differ diff --git a/Templates/Empty/game/core/art/shapes/unit_cube.dts b/Templates/Empty/game/core/art/shapes/unit_cube.dts new file mode 100644 index 000000000..feee7cf94 Binary files /dev/null and b/Templates/Empty/game/core/art/shapes/unit_cube.dts differ diff --git a/Templates/Empty/game/core/art/shapes/unit_sphere.dts b/Templates/Empty/game/core/art/shapes/unit_sphere.dts new file mode 100644 index 000000000..4d435438e Binary files /dev/null and b/Templates/Empty/game/core/art/shapes/unit_sphere.dts differ diff --git a/Templates/Empty/game/core/art/skies/Black_sky/materials.cs b/Templates/Empty/game/core/art/skies/Black_sky/materials.cs new file mode 100644 index 000000000..8967025df --- /dev/null +++ b/Templates/Empty/game/core/art/skies/Black_sky/materials.cs @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +singleton CubemapData( BlackSkyCubemap ) +{ + cubeFace[0] = "./skybox_1"; + cubeFace[1] = "./skybox_2"; + cubeFace[2] = "./skybox_3"; + cubeFace[3] = "./skybox_4"; + cubeFace[4] = "./skybox_5"; + cubeFace[5] = "./skybox_6"; +}; + +singleton Material( BlackSkyMat ) +{ + cubemap = BlackSkyCubemap; +}; diff --git a/Templates/Empty/game/core/art/skies/Black_sky/sky_skybox.dml b/Templates/Empty/game/core/art/skies/Black_sky/sky_skybox.dml new file mode 100644 index 000000000..5ca0a1cb6 --- /dev/null +++ b/Templates/Empty/game/core/art/skies/Black_sky/sky_skybox.dml @@ -0,0 +1,7 @@ +skybox_1 +skybox_2 +skybox_3 +skybox_4 +skybox_5 +skybox_6 +skybox_6 \ No newline at end of file diff --git a/Templates/Empty/game/core/art/skies/Black_sky/skybox_1.jpg b/Templates/Empty/game/core/art/skies/Black_sky/skybox_1.jpg new file mode 100644 index 000000000..bce44102c Binary files /dev/null and b/Templates/Empty/game/core/art/skies/Black_sky/skybox_1.jpg differ diff --git a/Templates/Empty/game/core/art/skies/Black_sky/skybox_2.jpg b/Templates/Empty/game/core/art/skies/Black_sky/skybox_2.jpg new file mode 100644 index 000000000..5a81cd241 Binary files /dev/null and b/Templates/Empty/game/core/art/skies/Black_sky/skybox_2.jpg differ diff --git a/Templates/Empty/game/core/art/skies/Black_sky/skybox_3.jpg b/Templates/Empty/game/core/art/skies/Black_sky/skybox_3.jpg new file mode 100644 index 000000000..ed7d05fd6 Binary files /dev/null and b/Templates/Empty/game/core/art/skies/Black_sky/skybox_3.jpg differ diff --git a/Templates/Empty/game/core/art/skies/Black_sky/skybox_4.jpg b/Templates/Empty/game/core/art/skies/Black_sky/skybox_4.jpg new file mode 100644 index 000000000..f08164be2 Binary files /dev/null and b/Templates/Empty/game/core/art/skies/Black_sky/skybox_4.jpg differ diff --git a/Templates/Empty/game/core/art/skies/Black_sky/skybox_5.jpg b/Templates/Empty/game/core/art/skies/Black_sky/skybox_5.jpg new file mode 100644 index 000000000..aa987b79e Binary files /dev/null and b/Templates/Empty/game/core/art/skies/Black_sky/skybox_5.jpg differ diff --git a/Templates/Empty/game/core/art/skies/Black_sky/skybox_6.jpg b/Templates/Empty/game/core/art/skies/Black_sky/skybox_6.jpg new file mode 100644 index 000000000..3ebfb6e4f Binary files /dev/null and b/Templates/Empty/game/core/art/skies/Black_sky/skybox_6.jpg differ diff --git a/Templates/Empty/game/core/art/skies/Blank_sky/materials.cs b/Templates/Empty/game/core/art/skies/Blank_sky/materials.cs new file mode 100644 index 000000000..08e1c2b58 --- /dev/null +++ b/Templates/Empty/game/core/art/skies/Blank_sky/materials.cs @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +singleton CubemapData( BlankSkyCubemap ) +{ + cubeFace[0] = "./skybox_1"; + cubeFace[1] = "./skybox_2"; + cubeFace[2] = "./skybox_3"; + cubeFace[3] = "./skybox_4"; + cubeFace[4] = "./skybox_5"; + cubeFace[5] = "./skybox_6"; +}; + +singleton Material( BlankSkyMat ) +{ + cubemap = BlankSkyCubemap; +}; diff --git a/Templates/Empty/game/core/art/skies/Blank_sky/sky_skybox.dml b/Templates/Empty/game/core/art/skies/Blank_sky/sky_skybox.dml new file mode 100644 index 000000000..5ca0a1cb6 --- /dev/null +++ b/Templates/Empty/game/core/art/skies/Blank_sky/sky_skybox.dml @@ -0,0 +1,7 @@ +skybox_1 +skybox_2 +skybox_3 +skybox_4 +skybox_5 +skybox_6 +skybox_6 \ No newline at end of file diff --git a/Templates/Empty/game/core/art/skies/Blank_sky/skybox_1.jpg b/Templates/Empty/game/core/art/skies/Blank_sky/skybox_1.jpg new file mode 100644 index 000000000..871322e94 Binary files /dev/null and b/Templates/Empty/game/core/art/skies/Blank_sky/skybox_1.jpg differ diff --git a/Templates/Empty/game/core/art/skies/Blank_sky/skybox_2.jpg b/Templates/Empty/game/core/art/skies/Blank_sky/skybox_2.jpg new file mode 100644 index 000000000..3e2a810de Binary files /dev/null and b/Templates/Empty/game/core/art/skies/Blank_sky/skybox_2.jpg differ diff --git a/Templates/Empty/game/core/art/skies/Blank_sky/skybox_3.jpg b/Templates/Empty/game/core/art/skies/Blank_sky/skybox_3.jpg new file mode 100644 index 000000000..757f99b33 Binary files /dev/null and b/Templates/Empty/game/core/art/skies/Blank_sky/skybox_3.jpg differ diff --git a/Templates/Empty/game/core/art/skies/Blank_sky/skybox_4.jpg b/Templates/Empty/game/core/art/skies/Blank_sky/skybox_4.jpg new file mode 100644 index 000000000..30eb1d2a3 Binary files /dev/null and b/Templates/Empty/game/core/art/skies/Blank_sky/skybox_4.jpg differ diff --git a/Templates/Empty/game/core/art/skies/Blank_sky/skybox_5.jpg b/Templates/Empty/game/core/art/skies/Blank_sky/skybox_5.jpg new file mode 100644 index 000000000..10a24db73 Binary files /dev/null and b/Templates/Empty/game/core/art/skies/Blank_sky/skybox_5.jpg differ diff --git a/Templates/Empty/game/core/art/skies/Blank_sky/skybox_6.jpg b/Templates/Empty/game/core/art/skies/Blank_sky/skybox_6.jpg new file mode 100644 index 000000000..3ec28d02e Binary files /dev/null and b/Templates/Empty/game/core/art/skies/Blank_sky/skybox_6.jpg differ diff --git a/Templates/Empty/game/core/art/skies/Desert_Sky/cubemap/skybox_1.png b/Templates/Empty/game/core/art/skies/Desert_Sky/cubemap/skybox_1.png new file mode 100644 index 000000000..12e4a1119 Binary files /dev/null and b/Templates/Empty/game/core/art/skies/Desert_Sky/cubemap/skybox_1.png differ diff --git a/Templates/Empty/game/core/art/skies/Desert_Sky/cubemap/skybox_2.png b/Templates/Empty/game/core/art/skies/Desert_Sky/cubemap/skybox_2.png new file mode 100644 index 000000000..d75e4265d Binary files /dev/null and b/Templates/Empty/game/core/art/skies/Desert_Sky/cubemap/skybox_2.png differ diff --git a/Templates/Empty/game/core/art/skies/Desert_Sky/cubemap/skybox_3.png b/Templates/Empty/game/core/art/skies/Desert_Sky/cubemap/skybox_3.png new file mode 100644 index 000000000..5468975fb Binary files /dev/null and b/Templates/Empty/game/core/art/skies/Desert_Sky/cubemap/skybox_3.png differ diff --git a/Templates/Empty/game/core/art/skies/Desert_Sky/cubemap/skybox_4.png b/Templates/Empty/game/core/art/skies/Desert_Sky/cubemap/skybox_4.png new file mode 100644 index 000000000..6cf2b6e8d Binary files /dev/null and b/Templates/Empty/game/core/art/skies/Desert_Sky/cubemap/skybox_4.png differ diff --git a/Templates/Empty/game/core/art/skies/Desert_Sky/cubemap/skybox_5.png b/Templates/Empty/game/core/art/skies/Desert_Sky/cubemap/skybox_5.png new file mode 100644 index 000000000..ec34b0f5f Binary files /dev/null and b/Templates/Empty/game/core/art/skies/Desert_Sky/cubemap/skybox_5.png differ diff --git a/Templates/Empty/game/core/art/skies/Desert_Sky/cubemap/skybox_6.png b/Templates/Empty/game/core/art/skies/Desert_Sky/cubemap/skybox_6.png new file mode 100644 index 000000000..e8cebd131 Binary files /dev/null and b/Templates/Empty/game/core/art/skies/Desert_Sky/cubemap/skybox_6.png differ diff --git a/Templates/Empty/game/core/art/skies/Desert_Sky/materials.cs b/Templates/Empty/game/core/art/skies/Desert_Sky/materials.cs new file mode 100644 index 000000000..fe5ec60ef --- /dev/null +++ b/Templates/Empty/game/core/art/skies/Desert_Sky/materials.cs @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +singleton CubemapData( DesertSkyCubemap ) +{ + cubeFace[0] = "./cubemap/skybox_1"; + cubeFace[1] = "./cubemap/skybox_2"; + cubeFace[2] = "./cubemap/skybox_3"; + cubeFace[3] = "./cubemap/skybox_4"; + cubeFace[4] = "./cubemap/skybox_5"; + cubeFace[5] = "./cubemap/skybox_6"; +}; + +singleton Material( DesertSkyMat ) +{ + cubemap = DesertSkyCubemap; +}; diff --git a/Templates/Empty/game/core/art/skies/Desert_Sky/sky_skybox.dml b/Templates/Empty/game/core/art/skies/Desert_Sky/sky_skybox.dml new file mode 100644 index 000000000..5ca0a1cb6 --- /dev/null +++ b/Templates/Empty/game/core/art/skies/Desert_Sky/sky_skybox.dml @@ -0,0 +1,7 @@ +skybox_1 +skybox_2 +skybox_3 +skybox_4 +skybox_5 +skybox_6 +skybox_6 \ No newline at end of file diff --git a/Templates/Empty/game/core/art/skies/Grey_sky/materials.cs b/Templates/Empty/game/core/art/skies/Grey_sky/materials.cs new file mode 100644 index 000000000..ea9d7b0dd --- /dev/null +++ b/Templates/Empty/game/core/art/skies/Grey_sky/materials.cs @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +singleton CubemapData( GreySkyCubemap ) +{ + cubeFace[0] = "./skybox_1"; + cubeFace[1] = "./skybox_2"; + cubeFace[2] = "./skybox_3"; + cubeFace[3] = "./skybox_4"; + cubeFace[4] = "./skybox_5"; + cubeFace[5] = "./skybox_6"; +}; + diff --git a/Templates/Empty/game/core/art/skies/Grey_sky/sky_skybox.dml b/Templates/Empty/game/core/art/skies/Grey_sky/sky_skybox.dml new file mode 100644 index 000000000..5ca0a1cb6 --- /dev/null +++ b/Templates/Empty/game/core/art/skies/Grey_sky/sky_skybox.dml @@ -0,0 +1,7 @@ +skybox_1 +skybox_2 +skybox_3 +skybox_4 +skybox_5 +skybox_6 +skybox_6 \ No newline at end of file diff --git a/Templates/Empty/game/core/art/skies/Grey_sky/skybox_1.jpg b/Templates/Empty/game/core/art/skies/Grey_sky/skybox_1.jpg new file mode 100644 index 000000000..d24d1e671 Binary files /dev/null and b/Templates/Empty/game/core/art/skies/Grey_sky/skybox_1.jpg differ diff --git a/Templates/Empty/game/core/art/skies/Grey_sky/skybox_2.jpg b/Templates/Empty/game/core/art/skies/Grey_sky/skybox_2.jpg new file mode 100644 index 000000000..fb799cbd1 Binary files /dev/null and b/Templates/Empty/game/core/art/skies/Grey_sky/skybox_2.jpg differ diff --git a/Templates/Empty/game/core/art/skies/Grey_sky/skybox_3.jpg b/Templates/Empty/game/core/art/skies/Grey_sky/skybox_3.jpg new file mode 100644 index 000000000..7707d903a Binary files /dev/null and b/Templates/Empty/game/core/art/skies/Grey_sky/skybox_3.jpg differ diff --git a/Templates/Empty/game/core/art/skies/Grey_sky/skybox_4.jpg b/Templates/Empty/game/core/art/skies/Grey_sky/skybox_4.jpg new file mode 100644 index 000000000..32761aab3 Binary files /dev/null and b/Templates/Empty/game/core/art/skies/Grey_sky/skybox_4.jpg differ diff --git a/Templates/Empty/game/core/art/skies/Grey_sky/skybox_5.jpg b/Templates/Empty/game/core/art/skies/Grey_sky/skybox_5.jpg new file mode 100644 index 000000000..dfdf4aaf8 Binary files /dev/null and b/Templates/Empty/game/core/art/skies/Grey_sky/skybox_5.jpg differ diff --git a/Templates/Empty/game/core/art/skies/Grey_sky/skybox_6.jpg b/Templates/Empty/game/core/art/skies/Grey_sky/skybox_6.jpg new file mode 100644 index 000000000..f1fc74d6e Binary files /dev/null and b/Templates/Empty/game/core/art/skies/Grey_sky/skybox_6.jpg differ diff --git a/Templates/Empty/game/core/art/skies/NewLevel_sky/cubemap/skybox_1.png b/Templates/Empty/game/core/art/skies/NewLevel_sky/cubemap/skybox_1.png new file mode 100644 index 000000000..12e4a1119 Binary files /dev/null and b/Templates/Empty/game/core/art/skies/NewLevel_sky/cubemap/skybox_1.png differ diff --git a/Templates/Empty/game/core/art/skies/NewLevel_sky/cubemap/skybox_2.png b/Templates/Empty/game/core/art/skies/NewLevel_sky/cubemap/skybox_2.png new file mode 100644 index 000000000..d75e4265d Binary files /dev/null and b/Templates/Empty/game/core/art/skies/NewLevel_sky/cubemap/skybox_2.png differ diff --git a/Templates/Empty/game/core/art/skies/NewLevel_sky/cubemap/skybox_3.png b/Templates/Empty/game/core/art/skies/NewLevel_sky/cubemap/skybox_3.png new file mode 100644 index 000000000..5468975fb Binary files /dev/null and b/Templates/Empty/game/core/art/skies/NewLevel_sky/cubemap/skybox_3.png differ diff --git a/Templates/Empty/game/core/art/skies/NewLevel_sky/cubemap/skybox_4.png b/Templates/Empty/game/core/art/skies/NewLevel_sky/cubemap/skybox_4.png new file mode 100644 index 000000000..6cf2b6e8d Binary files /dev/null and b/Templates/Empty/game/core/art/skies/NewLevel_sky/cubemap/skybox_4.png differ diff --git a/Templates/Empty/game/core/art/skies/NewLevel_sky/cubemap/skybox_5.png b/Templates/Empty/game/core/art/skies/NewLevel_sky/cubemap/skybox_5.png new file mode 100644 index 000000000..ec34b0f5f Binary files /dev/null and b/Templates/Empty/game/core/art/skies/NewLevel_sky/cubemap/skybox_5.png differ diff --git a/Templates/Empty/game/core/art/skies/NewLevel_sky/cubemap/skybox_6.png b/Templates/Empty/game/core/art/skies/NewLevel_sky/cubemap/skybox_6.png new file mode 100644 index 000000000..e8cebd131 Binary files /dev/null and b/Templates/Empty/game/core/art/skies/NewLevel_sky/cubemap/skybox_6.png differ diff --git a/Templates/Empty/game/core/art/skies/NewLevel_sky/materials.cs b/Templates/Empty/game/core/art/skies/NewLevel_sky/materials.cs new file mode 100644 index 000000000..df7cf4926 --- /dev/null +++ b/Templates/Empty/game/core/art/skies/NewLevel_sky/materials.cs @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +singleton CubemapData( NewLevelSkyCubemap ) +{ + cubeFace[0] = "./cubemap/skybox_1"; + cubeFace[1] = "./cubemap/skybox_2"; + cubeFace[2] = "./cubemap/skybox_3"; + cubeFace[3] = "./cubemap/skybox_4"; + cubeFace[4] = "./cubemap/skybox_5"; + cubeFace[5] = "./cubemap/skybox_6"; +}; + +singleton Material( NewLevelSkyMat ) +{ + cubemap = NewLevelSkyCubemap; +}; diff --git a/Templates/Empty/game/core/art/skies/NewLevel_sky/sky_skybox.dml b/Templates/Empty/game/core/art/skies/NewLevel_sky/sky_skybox.dml new file mode 100644 index 000000000..5ca0a1cb6 --- /dev/null +++ b/Templates/Empty/game/core/art/skies/NewLevel_sky/sky_skybox.dml @@ -0,0 +1,7 @@ +skybox_1 +skybox_2 +skybox_3 +skybox_4 +skybox_5 +skybox_6 +skybox_6 \ No newline at end of file diff --git a/Templates/Empty/game/core/art/skies/clouds/cloud1.png b/Templates/Empty/game/core/art/skies/clouds/cloud1.png new file mode 100644 index 000000000..f13b63d5a Binary files /dev/null and b/Templates/Empty/game/core/art/skies/clouds/cloud1.png differ diff --git a/Templates/Empty/game/core/art/skies/clouds/cloud2.png b/Templates/Empty/game/core/art/skies/clouds/cloud2.png new file mode 100644 index 000000000..a7ee34b6c Binary files /dev/null and b/Templates/Empty/game/core/art/skies/clouds/cloud2.png differ diff --git a/Templates/Empty/game/core/art/skies/clouds/cloud3.png b/Templates/Empty/game/core/art/skies/clouds/cloud3.png new file mode 100644 index 000000000..5767f5486 Binary files /dev/null and b/Templates/Empty/game/core/art/skies/clouds/cloud3.png differ diff --git a/Templates/Empty/game/core/art/skies/clouds/clouds_normal_displacement.png b/Templates/Empty/game/core/art/skies/clouds/clouds_normal_displacement.png new file mode 100644 index 000000000..0419cdace Binary files /dev/null and b/Templates/Empty/game/core/art/skies/clouds/clouds_normal_displacement.png differ diff --git a/Templates/Empty/game/core/art/skies/night/materials.cs b/Templates/Empty/game/core/art/skies/night/materials.cs new file mode 100644 index 000000000..beaa90dd3 --- /dev/null +++ b/Templates/Empty/game/core/art/skies/night/materials.cs @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +singleton CubemapData( NightCubemap ) +{ + cubeFace[0] = "./skybox_1"; + cubeFace[1] = "./skybox_2"; + cubeFace[2] = "./skybox_3"; + cubeFace[3] = "./skybox_4"; + cubeFace[4] = "./skybox_5"; + cubeFace[5] = "./skybox_6"; +}; + +singleton Material( Moon_Glow_Mat ) +{ + baseTex = "./moon_wglow.png"; + emissive = true; + translucent = true; + vertColor[ 0 ] = true; +}; + +singleton Material( Moon_Mat ) +{ + baseTex = "./moon_noglow.png"; + emissive = true; + translucent = true; + vertColor[ 0 ] = true; +}; diff --git a/Templates/Empty/game/core/art/skies/night/moon_noglow.png b/Templates/Empty/game/core/art/skies/night/moon_noglow.png new file mode 100644 index 000000000..973ddb6c2 Binary files /dev/null and b/Templates/Empty/game/core/art/skies/night/moon_noglow.png differ diff --git a/Templates/Empty/game/core/art/skies/night/moon_wcorona.png b/Templates/Empty/game/core/art/skies/night/moon_wcorona.png new file mode 100644 index 000000000..568f260ba Binary files /dev/null and b/Templates/Empty/game/core/art/skies/night/moon_wcorona.png differ diff --git a/Templates/Empty/game/core/art/skies/night/moon_wglow.png b/Templates/Empty/game/core/art/skies/night/moon_wglow.png new file mode 100644 index 000000000..e8fdf0647 Binary files /dev/null and b/Templates/Empty/game/core/art/skies/night/moon_wglow.png differ diff --git a/Templates/Empty/game/core/art/skies/night/skybox_1.png b/Templates/Empty/game/core/art/skies/night/skybox_1.png new file mode 100644 index 000000000..aa9a94cc8 Binary files /dev/null and b/Templates/Empty/game/core/art/skies/night/skybox_1.png differ diff --git a/Templates/Empty/game/core/art/skies/night/skybox_2.png b/Templates/Empty/game/core/art/skies/night/skybox_2.png new file mode 100644 index 000000000..c04d1648a Binary files /dev/null and b/Templates/Empty/game/core/art/skies/night/skybox_2.png differ diff --git a/Templates/Empty/game/core/art/skies/night/skybox_3.png b/Templates/Empty/game/core/art/skies/night/skybox_3.png new file mode 100644 index 000000000..00d03d634 Binary files /dev/null and b/Templates/Empty/game/core/art/skies/night/skybox_3.png differ diff --git a/Templates/Empty/game/core/art/skies/night/skybox_4.png b/Templates/Empty/game/core/art/skies/night/skybox_4.png new file mode 100644 index 000000000..1ba8ba331 Binary files /dev/null and b/Templates/Empty/game/core/art/skies/night/skybox_4.png differ diff --git a/Templates/Empty/game/core/art/skies/night/skybox_5.png b/Templates/Empty/game/core/art/skies/night/skybox_5.png new file mode 100644 index 000000000..c71140a0d Binary files /dev/null and b/Templates/Empty/game/core/art/skies/night/skybox_5.png differ diff --git a/Templates/Empty/game/core/art/skies/night/skybox_6.png b/Templates/Empty/game/core/art/skies/night/skybox_6.png new file mode 100644 index 000000000..6398ace05 Binary files /dev/null and b/Templates/Empty/game/core/art/skies/night/skybox_6.png differ diff --git a/Templates/Empty/game/core/art/sound/volumeTest.wav b/Templates/Empty/game/core/art/sound/volumeTest.wav new file mode 100644 index 000000000..087c0db4e Binary files /dev/null and b/Templates/Empty/game/core/art/sound/volumeTest.wav differ diff --git a/Templates/Empty/game/core/art/special/corona.png b/Templates/Empty/game/core/art/special/corona.png new file mode 100644 index 000000000..b325da06e Binary files /dev/null and b/Templates/Empty/game/core/art/special/corona.png differ diff --git a/Templates/Empty/game/core/art/special/lensFlareSheet0.png b/Templates/Empty/game/core/art/special/lensFlareSheet0.png new file mode 100644 index 000000000..c043c08ec Binary files /dev/null and b/Templates/Empty/game/core/art/special/lensFlareSheet0.png differ diff --git a/Templates/Empty/game/core/art/special/lensFlareSheet1.png b/Templates/Empty/game/core/art/special/lensFlareSheet1.png new file mode 100644 index 000000000..04abc05b3 Binary files /dev/null and b/Templates/Empty/game/core/art/special/lensFlareSheet1.png differ diff --git a/Templates/Empty/game/core/art/special/lensflareSheet3.png b/Templates/Empty/game/core/art/special/lensflareSheet3.png new file mode 100644 index 000000000..aa5f3ef47 Binary files /dev/null and b/Templates/Empty/game/core/art/special/lensflareSheet3.png differ diff --git a/Templates/Empty/game/core/art/special/materials.cs b/Templates/Empty/game/core/art/special/materials.cs new file mode 100644 index 000000000..5371f3098 --- /dev/null +++ b/Templates/Empty/game/core/art/special/materials.cs @@ -0,0 +1,30 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +singleton Material( Corona_Mat ) +{ + emissive = true; + translucent = true; + mapTo = "corona.png"; + diffuseMap[0] = "./corona.png"; + materialTag0 = "FX"; +}; diff --git a/Templates/Empty/game/core/art/unavailable.png b/Templates/Empty/game/core/art/unavailable.png new file mode 100644 index 000000000..9d818a376 Binary files /dev/null and b/Templates/Empty/game/core/art/unavailable.png differ diff --git a/Templates/Empty/game/core/art/warnMat.dds b/Templates/Empty/game/core/art/warnMat.dds new file mode 100644 index 000000000..ea99dcbd7 Binary files /dev/null and b/Templates/Empty/game/core/art/warnMat.dds differ diff --git a/Templates/Empty/game/core/art/water/depthcolor_ramp.png b/Templates/Empty/game/core/art/water/depthcolor_ramp.png new file mode 100644 index 000000000..749cec437 Binary files /dev/null and b/Templates/Empty/game/core/art/water/depthcolor_ramp.png differ diff --git a/Templates/Empty/game/core/art/water/foam.dds b/Templates/Empty/game/core/art/water/foam.dds new file mode 100644 index 000000000..6469bdb9c Binary files /dev/null and b/Templates/Empty/game/core/art/water/foam.dds differ diff --git a/Templates/Empty/game/core/art/water/foam.png b/Templates/Empty/game/core/art/water/foam.png new file mode 100644 index 000000000..d86c95716 Binary files /dev/null and b/Templates/Empty/game/core/art/water/foam.png differ diff --git a/Templates/Empty/game/core/art/water/lava_depthcolor_ramp.png b/Templates/Empty/game/core/art/water/lava_depthcolor_ramp.png new file mode 100644 index 000000000..8950e2064 Binary files /dev/null and b/Templates/Empty/game/core/art/water/lava_depthcolor_ramp.png differ diff --git a/Templates/Empty/game/core/art/water/lava_foam.dds b/Templates/Empty/game/core/art/water/lava_foam.dds new file mode 100644 index 000000000..78e4f3787 Binary files /dev/null and b/Templates/Empty/game/core/art/water/lava_foam.dds differ diff --git a/Templates/Empty/game/core/art/water/ripple.dds b/Templates/Empty/game/core/art/water/ripple.dds new file mode 100644 index 000000000..aa9285883 Binary files /dev/null and b/Templates/Empty/game/core/art/water/ripple.dds differ diff --git a/Templates/Empty/game/core/art/water/river_depthcolor_ramp.png b/Templates/Empty/game/core/art/water/river_depthcolor_ramp.png new file mode 100644 index 000000000..df43b86a9 Binary files /dev/null and b/Templates/Empty/game/core/art/water/river_depthcolor_ramp.png differ diff --git a/Templates/Empty/game/core/art/water/riversuds.dds b/Templates/Empty/game/core/art/water/riversuds.dds new file mode 100644 index 000000000..11e093d85 Binary files /dev/null and b/Templates/Empty/game/core/art/water/riversuds.dds differ diff --git a/Templates/Empty/game/core/art/water/riversuds.png b/Templates/Empty/game/core/art/water/riversuds.png new file mode 100644 index 000000000..ae6c75d4d Binary files /dev/null and b/Templates/Empty/game/core/art/water/riversuds.png differ diff --git a/Templates/Empty/game/core/art/water/wateredge512.dds b/Templates/Empty/game/core/art/water/wateredge512.dds new file mode 100644 index 000000000..90131022d Binary files /dev/null and b/Templates/Empty/game/core/art/water/wateredge512.dds differ diff --git a/Templates/Empty/game/core/art/white.jpg b/Templates/Empty/game/core/art/white.jpg new file mode 100644 index 000000000..e2f2a1a7e Binary files /dev/null and b/Templates/Empty/game/core/art/white.jpg differ diff --git a/Templates/Empty/game/core/fonts/.gitignore b/Templates/Empty/game/core/fonts/.gitignore new file mode 100644 index 000000000..1bc0e838a --- /dev/null +++ b/Templates/Empty/game/core/fonts/.gitignore @@ -0,0 +1 @@ +# Keep directory in git repo diff --git a/Templates/Empty/game/core/main.cs b/Templates/Empty/game/core/main.cs new file mode 100644 index 000000000..21ada8231 --- /dev/null +++ b/Templates/Empty/game/core/main.cs @@ -0,0 +1,196 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Constants for referencing video resolution preferences +$WORD::RES_X = 0; +$WORD::RES_Y = 1; +$WORD::FULLSCREEN = 2; +$WORD::BITDEPTH = 3; +$WORD::REFRESH = 4; +$WORD::AA = 5; + +//--------------------------------------------------------------------------------------------- +// CorePackage +// Adds functionality for this mod to some standard functions. +//--------------------------------------------------------------------------------------------- +package CorePackage +{ +//--------------------------------------------------------------------------------------------- +// onStart +// Called when the engine is starting up. Initializes this mod. +//--------------------------------------------------------------------------------------------- +function onStart() +{ + Parent::onStart(); + + // Here is where we will do the video device stuff, so it overwrites the defaults + // First set the PCI device variables (yes AGP/PCI-E works too) + $isFirstPersonVar = 1; + + // Uncomment to enable AdvancedLighting on the Mac (T3D 2009 Beta 3) + //$pref::machax::enableAdvancedLighting = true; + + // Uncomment to disable ShaderGen, useful when debugging + //$ShaderGen::GenNewShaders = false; + + // Uncomment to dump disassembly for any shader that is compiled to disk. + // These will appear as shadername_dis.txt in the same path as the + // hlsl or glsl shader. + //$gfx::disassembleAllShaders = true; + + // Uncomment useNVPerfHud to allow you to start up correctly + // when you drop your executable onto NVPerfHud + //$Video::useNVPerfHud = true; + + // Uncomment these to allow you to force your app into using + // a specific pixel shader version (0 is for fixed function) + //$pref::Video::forcePixVersion = true; + //$pref::Video::forcedPixVersion = 0; + + if ($platform $= "macos") + $pref::Video::displayDevice = "OpenGL"; + else + $pref::Video::displayDevice = "D3D9"; + + // Initialise stuff. + exec("./scripts/client/core.cs"); + initializeCore(); + + exec("./unifiedShell/main.cs"); + + exec("./scripts/client/client.cs"); + exec("./scripts/server/server.cs"); + + exec("./scripts/gui/guiTreeViewCtrl.cs"); + exec("./scripts/gui/messageBoxes/messageBox.ed.cs"); + + exec("./art/gui/customProfiles.cs"); + + // Level Chooser GUI + exec("./art/gui/chooseLevelDlg.gui"); + exec("./scripts/gui/chooseLevelDlg.cs"); + + exec("./scripts/gui/optionsDlg.cs"); + exec("./art/gui/optionsDlg.gui"); + exec("./scripts/gui/loadingGui.cs"); + exec("./art/gui/loadingGui.gui"); + + echo(" % - Initialized Core"); +} + +//--------------------------------------------------------------------------------------------- +// onExit +// Called when the engine is shutting down. Shutdowns this mod. +//--------------------------------------------------------------------------------------------- +function onExit() +{ + // Shutdown stuff. + shutdownCore(); + + Parent::onExit(); +} + +function loadKeybindings() +{ + $keybindCount = 0; + // Load up the active projects keybinds. + if(isFunction("setupKeybinds")) + setupKeybinds(); +} + +//--------------------------------------------------------------------------------------------- +// displayHelp +// Prints the command line options available for this mod. +//--------------------------------------------------------------------------------------------- +function displayHelp() { + // Let the parent do its stuff. + Parent::displayHelp(); + + error("Core Mod options:\n" @ + " -fullscreen Starts game in full screen mode\n" @ + " -windowed Starts game in windowed mode\n" @ + " -autoVideo Auto detect video, but prefers OpenGL\n" @ + " -openGL Force OpenGL acceleration\n" @ + " -directX Force DirectX acceleration\n" @ + " -voodoo2 Force Voodoo2 acceleration\n" @ + " -prefs Exec the config file\n"); +} + +//--------------------------------------------------------------------------------------------- +// parseArgs +// Parses the command line arguments and processes those valid for this mod. +//--------------------------------------------------------------------------------------------- +function parseArgs() +{ + // Let the parent grab the arguments it wants first. + Parent::parseArgs(); + + // Loop through the arguments. + for (%i = 1; %i < $Game::argc; %i++) + { + %arg = $Game::argv[%i]; + %nextArg = $Game::argv[%i+1]; + %hasNextArg = $Game::argc - %i > 1; + + switch$ (%arg) + { + case "-fullscreen": + setFullScreen(true); + $argUsed[%i]++; + + case "-windowed": + setFullScreen(false); + $argUsed[%i]++; + + case "-openGL": + $pref::Video::displayDevice = "OpenGL"; + $argUsed[%i]++; + + case "-directX": + $pref::Video::displayDevice = "D3D"; + $argUsed[%i]++; + + case "-voodoo2": + $pref::Video::displayDevice = "Voodoo2"; + $argUsed[%i]++; + + case "-autoVideo": + $pref::Video::displayDevice = ""; + $argUsed[%i]++; + + case "-prefs": + $argUsed[%i]++; + if (%hasNextArg) { + exec(%nextArg, true, true); + $argUsed[%i+1]++; + %i++; + } + else + error("Error: Missing Command Line argument. Usage: -prefs "); + } + } +} + +}; + +activatePackage(CorePackage); + diff --git a/Templates/Empty/game/core/parseArgs.cs b/Templates/Empty/game/core/parseArgs.cs new file mode 100644 index 000000000..bd3f8d382 --- /dev/null +++ b/Templates/Empty/game/core/parseArgs.cs @@ -0,0 +1,348 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Support functions used to manage the directory list + +function pushFront(%list, %token, %delim) +{ + if (%list !$= "") + return %token @ %delim @ %list; + return %token; +} + +function pushBack(%list, %token, %delim) +{ + if (%list !$= "") + return %list @ %delim @ %token; + return %token; +} + +function popFront(%list, %delim) +{ + return nextToken(%list, unused, %delim); +} + +//----------------------------------------------------------------------------- +// The default global argument parsing + +function defaultParseArgs() +{ + for ($i = 1; $i < $Game::argc ; $i++) + { + $arg = $Game::argv[$i]; + $nextArg = $Game::argv[$i+1]; + $hasNextArg = $Game::argc - $i > 1; + $logModeSpecified = false; + + // Check for dedicated run + if( stricmp($arg,"-dedicated") == 0 ) + { + $userDirs = $defaultGame; + $dirCount = 1; + $isDedicated = true; + } + + switch$ ($arg) + { + //-------------------- + case "-log": + $argUsed[$i]++; + if ($hasNextArg) + { + // Turn on console logging + if ($nextArg != 0) + { + // Dump existing console to logfile first. + $nextArg += 4; + } + setLogMode($nextArg); + $logModeSpecified = true; + $argUsed[$i+1]++; + $i++; + } + else + error("Error: Missing Command Line argument. Usage: -log "); + + //-------------------- + case "-dir": + $argUsed[$i]++; + if ($hasNextArg) + { + // Append the mod to the end of the current list + $userDirs = strreplace($userDirs, $nextArg, ""); + $userDirs = pushFront($userDirs, $nextArg, ";"); + $argUsed[$i+1]++; + $i++; + $dirCount++; + } + else + error("Error: Missing Command Line argument. Usage: -dir "); + + //-------------------- + // changed the default behavior of this command line arg. It now + // defaults to ONLY loading the game, not tools + // default auto-run already loads in tools --SRZ 11/29/07 + case "-game": + $argUsed[$i]++; + if ($hasNextArg) + { + // Set the selected dir --NOTE: we no longer allow tools with this argument + /* + if( $isDedicated ) + { + $userDirs = $nextArg; + $dirCount = 1; + } + else + { + $userDirs = "tools;" @ $nextArg; + $dirCount = 2; + } + */ + $userDirs = $nextArg; + $dirCount = 1; + $argUsed[$i+1]++; + $i++; + error($userDirs); + } + else + error("Error: Missing Command Line argument. Usage: -game "); + + /* deprecated SRZ 11/29/07 + //-------------------- + case "-show": + // A useful shortcut for -mod show + $userMods = strreplace($userMods, "show", ""); + $userMods = pushFront($userMods, "show", ";"); + $argUsed[$i]++; + $modcount++; + */ + //-------------------- + case "-console": + enableWinConsole(true); + $argUsed[$i]++; + + //-------------------- + case "-jSave": + $argUsed[$i]++; + if ($hasNextArg) + { + echo("Saving event log to journal: " @ $nextArg); + saveJournal($nextArg); + $argUsed[$i+1]++; + $i++; + } + else + error("Error: Missing Command Line argument. Usage: -jSave "); + + //-------------------- + case "-jPlay": + $argUsed[$i]++; + if ($hasNextArg) + { + playJournal($nextArg,false); + $argUsed[$i+1]++; + $i++; + } + else + error("Error: Missing Command Line argument. Usage: -jPlay "); + + //-------------------- + case "-jPlayToVideo": + $argUsed[$i]++; + if ($hasNextArg) + { + $VideoCapture::journalName = $nextArg; + $VideoCapture::captureFromJournal = true; + $argUsed[$i+1]++; + $i++; + } + else + error("Error: Missing Command Line argument. Usage: -jPlayToVideo "); + + //-------------------- + case "-vidCapFile": + $argUsed[$i]++; + if ($hasNextArg) + { + $VideoCapture::fileName = $nextArg; + $argUsed[$i+1]++; + $i++; + } + else + error("Error: Missing Command Line argument. Usage: -vidCapFile "); + + //-------------------- + case "-vidCapFPS": + $argUsed[$i]++; + if ($hasNextArg) + { + $VideoCapture::fps = $nextArg; + $argUsed[$i+1]++; + $i++; + } + else + error("Error: Missing Command Line argument. Usage: -vidCapFPS "); + + //-------------------- + case "-vidCapEncoder": + $argUsed[$i]++; + if ($hasNextArg) + { + $VideoCapture::encoder = $nextArg; + $argUsed[$i+1]++; + $i++; + } + else + error("Error: Missing Command Line argument. Usage: -vidCapEncoder "); + + //-------------------- + case "-vidCapWidth": + $argUsed[$i]++; + if ($hasNextArg) + { + $videoCapture::width = $nextArg; + $argUsed[$i+1]++; + $i++; + } + else + error("Error: Missing Command Line argument. Usage: -vidCapWidth "); + + //-------------------- + case "-vidCapHeight": + $argUsed[$i]++; + if ($hasNextArg) + { + $videoCapture::height = $nextArg; + $argUsed[$i+1]++; + $i++; + } + else + error("Error: Missing Command Line argument. Usage: -vidCapHeight "); + + //-------------------- + case "-jDebug": + $argUsed[$i]++; + if ($hasNextArg) + { + playJournal($nextArg,true); + $argUsed[$i+1]++; + $i++; + } + else + error("Error: Missing Command Line argument. Usage: -jDebug "); + + //-------------------- + case "-level": + $argUsed[$i]++; + if ($hasNextArg) + { + %hasExt = strpos($nextArg, ".mis"); + if(%hasExt == -1) + { + $levelToLoad = $nextArg @ " "; + + for(%i = $i + 2; %i < $Game::argc; %i++) + { + %arg = $Game::argv[%i]; + %hasExt = strpos(%arg, ".mis"); + + if(%hasExt == -1) + { + $levelToLoad = $levelToLoad @ %arg @ " "; + } else + { + $levelToLoad = $levelToLoad @ %arg; + break; + } + } + } else + $levelToLoad = $nextArg; + $argUsed[$i+1]++; + $i++; + } + else + error("Error: Missing Command Line argument. Usage: -level "); + + //------------------- + case "-worldeditor": + $startWorldEditor = true; + $argUsed[$i]++; + + //------------------- + case "-guieditor": + $startGUIEditor = true; + $argUsed[$i]++; + + //------------------- + case "-help": + $displayHelp = true; + $argUsed[$i]++; + + //------------------- + case "-compileAll": + $compileAll = true; + $argUsed[$i]++; + + //------------------- + case "-compileTools": + $compileTools = true; + $argUsed[$i]++; + + //------------------- + case "-genScript": + $genScript = true; + $argUsed[$i]++; + + //------------------- + default: + $argUsed[$i]++; + if($userDirs $= "") + $userDirs = $arg; + } + } + + //----------------------------------------------- + // Play journal to video file? + if ($VideoCapture::captureFromJournal && $VideoCapture::journalName !$= "") + { + if ($VideoCapture::fileName $= "") + $VideoCapture::fileName = $VideoCapture::journalName; + + if ($VideoCapture::encoder $= "") + $VideoCapture::encoder = "THEORA"; + + if ($VideoCapture::fps $= "") + $VideoCapture::fps = 30; + + if ($videoCapture::width $= "") + $videoCapture::width = 0; + + if ($videoCapture::height $= "") + $videoCapture::height = 0; + + playJournalToVideo( $VideoCapture::journalName, $VideoCapture::fileName, + $VideoCapture::encoder, $VideoCapture::fps, + $videoCapture::width SPC $videoCapture::height ); + } +} diff --git a/Templates/Empty/game/core/profile/D3D9.ATITechnologiesInc.cs b/Templates/Empty/game/core/profile/D3D9.ATITechnologiesInc.cs new file mode 100644 index 000000000..10c6bdf5b --- /dev/null +++ b/Templates/Empty/game/core/profile/D3D9.ATITechnologiesInc.cs @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// ATI Vendor Profile Script +// +// This script is responsible for setting global +// capability strings based on the nVidia vendor. + +if(GFXCardProfiler::getVersion() < 64.44) +{ + $GFX::OutdatedDrivers = true; + $GFX::OutdatedDriversLink = "You can get newer drivers here.."; +} +else +{ + $GFX::OutdatedDrivers = false; +} diff --git a/Templates/Empty/game/core/profile/D3D9.NVIDIA.GeForce8600.cs b/Templates/Empty/game/core/profile/D3D9.NVIDIA.GeForce8600.cs new file mode 100644 index 000000000..328788dac --- /dev/null +++ b/Templates/Empty/game/core/profile/D3D9.NVIDIA.GeForce8600.cs @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// nVidia Vendor Profile Script +// +// This script is responsible for setting global +// capability strings based on the nVidia vendor. + +if(GFXCardProfiler::getVersion() < 1.2) +{ + $GFX::OutdatedDrivers = true; + $GFX::OutdatedDriversLink = "You can get newer drivers here.."; +} +else +{ + $GFX::OutdatedDrivers = false; +} diff --git a/Templates/Empty/game/core/profile/D3D9.NVIDIA.QuadroFXGo1000.cs b/Templates/Empty/game/core/profile/D3D9.NVIDIA.QuadroFXGo1000.cs new file mode 100644 index 000000000..5681b2f6d --- /dev/null +++ b/Templates/Empty/game/core/profile/D3D9.NVIDIA.QuadroFXGo1000.cs @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// nVidia Vendor Profile Script +// +// This script is responsible for setting global +// capability strings based on the nVidia vendor. + +if(GFXCardProfiler::getVersion() < 53.82) +{ + $GFX::OutdatedDrivers = true; + $GFX::OutdatedDriversLink = "You can get newer drivers here.."; +} +else +{ + $GFX::OutdatedDrivers = false; +} + +// Silly card has trouble with this! +GFXCardProfiler::setCapability("autoMipmapLevel", false); diff --git a/Templates/Empty/game/core/profile/D3D9.NVIDIA.cs b/Templates/Empty/game/core/profile/D3D9.NVIDIA.cs new file mode 100644 index 000000000..b33b8d5d3 --- /dev/null +++ b/Templates/Empty/game/core/profile/D3D9.NVIDIA.cs @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// nVidia Vendor Profile Script +// +// This script is responsible for setting global +// capability strings based on the nVidia vendor. + +if(GFXCardProfiler::getVersion() < 56.72) +{ + $GFX::OutdatedDrivers = true; + $GFX::OutdatedDriversLink = "You can get newer drivers here.."; +} +else +{ + $GFX::OutdatedDrivers = false; +} diff --git a/Templates/Empty/game/core/profile/D3D9.cs b/Templates/Empty/game/core/profile/D3D9.cs new file mode 100644 index 000000000..e1e299341 --- /dev/null +++ b/Templates/Empty/game/core/profile/D3D9.cs @@ -0,0 +1,26 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Direct3D 9 Renderer Profile Script +// +// This script is responsible for setting global +// capability strings based on the D3D9 renderer type. \ No newline at end of file diff --git a/Templates/Empty/game/core/scripts/client/actionMap.cs b/Templates/Empty/game/core/scripts/client/actionMap.cs new file mode 100644 index 000000000..0f5ed7219 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/actionMap.cs @@ -0,0 +1,60 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +// Utility remap functions: +//------------------------------------------------------------------------------ + +function ActionMap::copyBind( %this, %otherMap, %command ) +{ + if ( !isObject( %otherMap ) ) + { + error( "ActionMap::copyBind - \"" @ %otherMap @ "\" is not an object!" ); + return; + } + + %bind = %otherMap.getBinding( %command ); + if ( %bind !$= "" ) + { + %device = getField( %bind, 0 ); + %action = getField( %bind, 1 ); + %flags = %otherMap.isInverted( %device, %action ) ? "SDI" : "SD"; + %deadZone = %otherMap.getDeadZone( %device, %action ); + %scale = %otherMap.getScale( %device, %action ); + %this.bind( %device, %action, %flags, %deadZone, %scale, %command ); + } +} + +//------------------------------------------------------------------------------ +function ActionMap::blockBind( %this, %otherMap, %command ) +{ + if ( !isObject( %otherMap ) ) + { + error( "ActionMap::blockBind - \"" @ %otherMap @ "\" is not an object!" ); + return; + } + + %bind = %otherMap.getBinding( %command ); + if ( %bind !$= "" ) + %this.bind( getField( %bind, 0 ), getField( %bind, 1 ), "" ); +} + diff --git a/Templates/Empty/game/core/scripts/client/audio.cs b/Templates/Empty/game/core/scripts/client/audio.cs new file mode 100644 index 000000000..839dd4975 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/audio.cs @@ -0,0 +1,456 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Source groups. +//----------------------------------------------------------------------------- + +singleton SFXDescription( AudioMaster ); +singleton SFXSource( AudioChannelMaster ) +{ + description = AudioMaster; +}; + +singleton SFXDescription( AudioChannel ) +{ + sourceGroup = AudioChannelMaster; +}; + +singleton SFXSource( AudioChannelDefault ) +{ + description = AudioChannel; +}; +singleton SFXSource( AudioChannelGui ) +{ + description = AudioChannel; +}; +singleton SFXSource( AudioChannelEffects ) +{ + description = AudioChannel; +}; +singleton SFXSource( AudioChannelMessages ) +{ + description = AudioChannel; +}; +singleton SFXSource( AudioChannelMusic ) +{ + description = AudioChannel; +}; + +// Set default playback states of the channels. + +AudioChannelMaster.play(); +AudioChannelDefault.play(); + +AudioChannelGui.play(); +AudioChannelMusic.play(); +AudioChannelMessages.play(); + +// Stop in-game effects channels. +AudioChannelEffects.stop(); + +//----------------------------------------------------------------------------- +// Master SFXDescriptions. +//----------------------------------------------------------------------------- + +// Master description for interface audio. +singleton SFXDescription( AudioGui ) +{ + volume = 1.0; + sourceGroup = AudioChannelGui; +}; + +// Master description for game effects audio. +singleton SFXDescription( AudioEffect ) +{ + volume = 1.0; + sourceGroup = AudioChannelEffects; +}; + +// Master description for audio in notifications. +singleton SFXDescription( AudioMessage ) +{ + volume = 1.0; + sourceGroup = AudioChannelMessages; +}; + +// Master description for music. +singleton SFXDescription( AudioMusic ) +{ + volume = 1.0; + sourceGroup = AudioChannelMusic; +}; + +//----------------------------------------------------------------------------- +// SFX Functions. +//----------------------------------------------------------------------------- + +/// This initializes the sound system device from +/// the defaults in the $pref::SFX:: globals. +function sfxStartup() +{ + // The console builds should re-detect, by default, so that it plays nicely + // along side a PC build in the same script directory. + + if( $platform $= "xenon" ) + { + if( $pref::SFX::provider $= "DirectSound" || + $pref::SFX::provider $= "OpenAL" ) + { + $pref::SFX::provider = ""; + } + + if( $pref::SFX::provider $= "" ) + { + $pref::SFX::autoDetect = 1; + + warn( "Xbox360 is auto-detecting available sound providers..." ); + warn( " - You may wish to alter this functionality before release (core/scripts/client/audio.cs)" ); + } + } + + echo( "sfxStartup..." ); + + // If we have a provider set, try initialize a device now. + + if( $pref::SFX::provider !$= "" ) + { + if( sfxInit() ) + return; + else + { + // Force auto-detection. + $pref::SFX::autoDetect = true; + } + } + + // If enabled autodetect a safe device. + + if( ( !isDefined( "$pref::SFX::autoDetect" ) || $pref::SFX::autoDetect ) && + sfxAutodetect() ) + return; + + // Failure. + + error( " Failed to initialize device!\n\n" ); + + $pref::SFX::provider = ""; + $pref::SFX::device = ""; + + return; +} + + +/// This initializes the sound system device from +/// the defaults in the $pref::SFX:: globals. +function sfxInit() +{ + // If already initialized, shut down the current device first. + + if( sfxGetDeviceInfo() !$= "" ) + sfxShutdown(); + + // Start it up! + %maxBuffers = $pref::SFX::useHardware ? -1 : $pref::SFX::maxSoftwareBuffers; + if ( !sfxCreateDevice( $pref::SFX::provider, $pref::SFX::device, $pref::SFX::useHardware, %maxBuffers ) ) + return false; + + // This returns a tab seperated string with + // the initialized system info. + %info = sfxGetDeviceInfo(); + $pref::SFX::provider = getField( %info, 0 ); + $pref::SFX::device = getField( %info, 1 ); + $pref::SFX::useHardware = getField( %info, 2 ); + %useHardware = $pref::SFX::useHardware ? "Yes" : "No"; + %maxBuffers = getField( %info, 3 ); + + echo( " Provider: " @ $pref::SFX::provider ); + echo( " Device: " @ $pref::SFX::device ); + echo( " Hardware: " @ %useHardware ); + echo( " Buffers: " @ %maxBuffers ); + + if( isDefined( "$pref::SFX::distanceModel" ) ) + sfxSetDistanceModel( $pref::SFX::distanceModel ); + if( isDefined( "$pref::SFX::dopplerFactor" ) ) + sfxSetDopplerFactor( $pref::SFX::dopplerFactor ); + if( isDefined( "$pref::SFX::rolloffFactor" ) ) + sfxSetRolloffFactor( $pref::SFX::rolloffFactor ); + + // Restore master volume. + + sfxSetMasterVolume( $pref::SFX::masterVolume ); + + // Restore channel volumes. + + for( %channel = 0; %channel <= 8; %channel ++ ) + sfxSetChannelVolume( %channel, $pref::SFX::channelVolume[ %channel ] ); + + return true; +} + + +/// Destroys the current sound system device. +function sfxShutdown() +{ + // Store volume prefs. + + $pref::SFX::masterVolume = sfxGetMasterVolume(); + + for( %channel = 0; %channel <= 8; %channel ++ ) + $pref::SFX::channelVolume[ %channel ] = sfxGetChannelVolume( %channel ); + + // We're assuming here that a null info + // string means that no device is loaded. + if( sfxGetDeviceInfo() $= "" ) + return; + + sfxDeleteDevice(); +} + + +/// Determines which of the two SFX providers is preferable. +function sfxCompareProvider( %providerA, %providerB ) +{ + if( %providerA $= %providerB ) + return 0; + + switch$( %providerA ) + { + // Always prefer FMOD over anything else. + case "FMOD": + return 1; + + // Prefer OpenAL over anything but FMOD. + case "OpenAL": + if( %providerB $= "FMOD" ) + return -1; + else + return 1; + + // As long as the XAudio SFX provider still has issues, + // choose stable DSound over it. + case "DirectSound": + if( %providerB $= "FMOD" || %providerB $= "OpenAL" ) + return -1; + else + return 0; + + case "XAudio": + if( %providerB !$= "FMOD" && %providerB !$= "OpenAL" && %providerB !$= "DirectSound" ) + return 1; + else + return -1; + + default: + return -1; + } +} + + +/// Try to detect and initalize the best SFX device available. +function sfxAutodetect() +{ + // Get all the available devices. + + %devices = sfxGetAvailableDevices(); + + // Collect and sort the devices by preferentiality. + + %deviceTrySequence = new ArrayObject(); + %bestMatch = -1; + %count = getRecordCount( %devices ); + for( %i = 0; %i < %count; %i ++ ) + { + %info = getRecord( %devices, %i ); + %provider = getField( %info, 0 ); + + %deviceTrySequence.push_back( %provider, %info ); + } + + %deviceTrySequence.sortfkd( "sfxCompareProvider" ); + + // Try the devices in order. + + %count = %deviceTrySequence.count(); + for( %i = 0; %i < %count; %i ++ ) + { + %provider = %deviceTrySequence.getKey( %i ); + %info = %deviceTrySequence.getValue( %i ); + + $pref::SFX::provider = %provider; + $pref::SFX::device = getField( %info, 1 ); + $pref::SFX::useHardware = getField( %info, 2 ); + + // By default we've decided to avoid hardware devices as + // they are buggy and prone to problems. + $pref::SFX::useHardware = false; + + if( sfxInit() ) + { + $pref::SFX::autoDetect = false; + %deviceTrySequence.delete(); + return true; + } + } + + // Found no suitable device. + + error( "sfxAutodetect - Could not initialize a valid SFX device." ); + + $pref::SFX::provider = ""; + $pref::SFX::device = ""; + $pref::SFX::useHardware = ""; + + %deviceTrySequence.delete(); + + return false; +} + + +//----------------------------------------------------------------------------- +// Backwards-compatibility with old channel system. +//----------------------------------------------------------------------------- + +// Volume channel IDs for backwards-compatibility. + +$GuiAudioType = 1; // Interface. +$SimAudioType = 2; // Game. +$MessageAudioType = 3; // Notifications. +$MusicAudioType = 4; // Music. + +$AudioChannels[ 0 ] = AudioChannelDefault; +$AudioChannels[ $GuiAudioType ] = AudioChannelGui; +$AudioChannels[ $SimAudioType ] = AudioChannelEffects; +$AudioChannels[ $MessageAudioType ] = AudioChannelMessages; +$AudioChannels[ $MusicAudioType ] = AudioChannelMusic; + +function sfxOldChannelToGroup( %channel ) +{ + return $AudioChannels[ %channel ]; +} + +function sfxGroupToOldChannel( %group ) +{ + %id = %group.getId(); + for( %i = 0;; %i ++ ) + if( !isObject( $AudioChannels[ %i ] ) ) + return -1; + else if( $AudioChannels[ %i ].getId() == %id ) + return %i; + + return -1; +} + +function sfxSetMasterVolume( %volume ) +{ + AudioChannelMaster.setVolume( %volume ); +} + +function sfxGetMasterVolume( %volume ) +{ + return AudioChannelMaster.getVolume(); +} + +function sfxStopAll( %channel ) +{ + // Don't stop channel itself since that isn't quite what the function + // here intends. + + %channel = sfxOldChannelToGroup( %channel ); + if (isObject(%channel)) + { + foreach( %source in %channel ) + %source.stop(); + } +} + +function sfxGetChannelVolume( %channel ) +{ + %obj = sfxOldChannelToGroup( %channel ); + if( isObject( %obj ) ) + return %obj.getVolume(); +} + +function sfxSetChannelVolume( %channel, %volume ) +{ + %obj = sfxOldChannelToGroup( %channel ); + if( isObject( %obj ) ) + %obj.setVolume( %volume ); +} + +singleton SimSet( SFXPausedSet ); + + +/// Pauses the playback of active sound sources. +/// +/// @param %channels An optional word list of channel indices or an empty +/// string to pause sources on all channels. +/// @param %pauseSet An optional SimSet which is filled with the paused +/// sources. If not specified the global SfxSourceGroup +/// is used. +/// +/// @deprecated +/// +function sfxPause( %channels, %pauseSet ) +{ + // Did we get a set to populate? + if ( !isObject( %pauseSet ) ) + %pauseSet = SFXPausedSet; + + %count = SFXSourceSet.getCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %source = SFXSourceSet.getObject( %i ); + + %channel = sfxGroupToOldChannel( %source.getGroup() ); + if( %channels $= "" || findWord( %channels, %channel ) != -1 ) + { + %source.pause(); + %pauseSet.add( %source ); + } + } +} + + +/// Resumes the playback of paused sound sources. +/// +/// @param %pauseSet An optional SimSet which contains the paused sound +/// sources to be resumed. If not specified the global +/// SfxSourceGroup is used. +/// @deprecated +/// +function sfxResume( %pauseSet ) +{ + if ( !isObject( %pauseSet ) ) + %pauseSet = SFXPausedSet; + + %count = %pauseSet.getCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %source = %pauseSet.getObject( %i ); + %source.play(); + } + + // Clear our pause set... the caller is left + // to clear his own if he passed one. + %pauseSet.clear(); +} diff --git a/Templates/Empty/game/core/scripts/client/audioAmbiences.cs b/Templates/Empty/game/core/scripts/client/audioAmbiences.cs new file mode 100644 index 000000000..aa6452f7f --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/audioAmbiences.cs @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +singleton SFXAmbience( AudioAmbienceDefault ) +{ + environment = AudioEnvOff; +}; + +singleton SFXAmbience( AudioAmbienceOutside ) +{ + environment = AudioEnvPlain; + states[ 0 ] = AudioLocationOutside; +}; + +singleton SFXAmbience( AudioAmbienceInside ) +{ + environment = AudioEnvRoom; + states[ 0 ] = AudioLocationInside; +}; + +singleton SFXAmbience( AudioAmbienceUnderwater ) +{ + environment = AudioEnvUnderwater; + states[ 0 ] = AudioLocationUnderwater; +}; diff --git a/Templates/Empty/game/core/scripts/client/audioDescriptions.cs b/Templates/Empty/game/core/scripts/client/audioDescriptions.cs new file mode 100644 index 000000000..d682461cf --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/audioDescriptions.cs @@ -0,0 +1,143 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Always declare SFXDescription's (the type of sound) before SFXProfile's (the +// sound itself) when creating new ones + +//----------------------------------------------------------------------------- +// 3D Sounds +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Single shot sounds +//----------------------------------------------------------------------------- + +singleton SFXDescription( AudioDefault3D : AudioEffect ) +{ + is3D = true; + ReferenceDistance = 20.0; + MaxDistance = 100.0; +}; + +singleton SFXDescription( AudioSoft3D : AudioEffect ) +{ + is3D = true; + ReferenceDistance = 20.0; + MaxDistance = 100.0; + volume = 0.4; +}; + +singleton SFXDescription( AudioClose3D : AudioEffect ) +{ + is3D = true; + ReferenceDistance = 10.0; + MaxDistance = 60.0; +}; + +singleton SFXDescription( AudioClosest3D : AudioEffect ) +{ + is3D = true; + ReferenceDistance = 5.0; + MaxDistance = 10.0; +}; + +//----------------------------------------------------------------------------- +// Looping sounds +//----------------------------------------------------------------------------- + +singleton SFXDescription( AudioDefaultLoop3D : AudioEffect ) +{ + isLooping = true; + is3D = true; + ReferenceDistance = 20.0; + MaxDistance = 100.0; +}; + +singleton SFXDescription( AudioCloseLoop3D : AudioEffect ) +{ + isLooping = true; + is3D = true; + ReferenceDistance = 18.0; + MaxDistance = 25.0; +}; + +singleton SFXDescription( AudioClosestLoop3D : AudioEffect ) +{ + isLooping = true; + is3D = true; + ReferenceDistance = 5.0; + MaxDistance = 10.0; +}; + +//----------------------------------------------------------------------------- +// 2d sounds +//----------------------------------------------------------------------------- + +// Used for non-looping environmental sounds (like power on, power off) +singleton SFXDescription( Audio2D : AudioEffect ) +{ + isLooping = false; +}; + +// Used for Looping Environmental Sounds +singleton SFXDescription( AudioLoop2D : AudioEffect ) +{ + isLooping = true; +}; + +singleton SFXDescription( AudioStream2D : AudioEffect ) +{ + isStreaming = true; +}; +singleton SFXDescription( AudioStreamLoop2D : AudioEffect ) +{ + isLooping = true; + isStreaming = true; +}; + +//----------------------------------------------------------------------------- +// Music +//----------------------------------------------------------------------------- + +singleton SFXDescription( AudioMusic2D : AudioMusic ) +{ + isStreaming = true; +}; + +singleton SFXDescription( AudioMusicLoop2D : AudioMusic ) +{ + isLooping = true; + isStreaming = true; +}; + +singleton SFXDescription( AudioMusic3D : AudioMusic ) +{ + isStreaming = true; + is3D = true; +}; + +singleton SFXDescription( AudioMusicLoop3D : AudioMusic ) +{ + isStreaming = true; + is3D = true; + isLooping = true; +}; diff --git a/Templates/Empty/game/core/scripts/client/audioEnvironments.cs b/Templates/Empty/game/core/scripts/client/audioEnvironments.cs new file mode 100644 index 000000000..09fc4de1a --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/audioEnvironments.cs @@ -0,0 +1,916 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Reverb environment presets. +// +// For customized presets, best derive from one of these presets. + +singleton SFXEnvironment( AudioEnvOff ) +{ + envSize = "7.5"; + envDiffusion = "1.0"; + room = "-10000"; + roomHF = "-10000"; + roomLF = "0"; + decayTime = "1.0"; + decayHFRatio = "1.0"; + decayLFRatio = "1.0"; + reflections = "-2602"; + reflectionsDelay = "0.007"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "200"; + reverbDelay = "0.011"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "0.0"; + density = "0.0"; + flags = 0x33; +}; + +singleton SFXEnvironment( AudioEnvGeneric ) +{ + envSize = "7.5"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-100"; + roomLF = "0"; + decayTime = "1.49"; + decayHFRatio = "0.83"; + decayLFRatio = "1.0"; + reflections = "-2602"; + reflectionsDelay = "0.007"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "200"; + reverbDelay = "0.011"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvRoom ) +{ + envSize = "1.9"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-454"; + roomLF = "0"; + decayTime = "0.4"; + decayHFRatio = "0.83"; + decayLFRatio = "1.0"; + reflections = "-1646"; + reflectionsDelay = "0.002"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "53"; + reverbDelay = "0.003"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvPaddedCell ) +{ + envSize = "1.4"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-6000"; + roomLF = "0"; + decayTime = "0.17"; + decayHFRatio = "0.1"; + decayLFRatio = "1.0"; + reflections = "-1204"; + reflectionsDelay = "0.001"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "207"; + reverbDelay = "0.002"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvBathroom ) +{ + envSize = "1.4"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-1200"; + roomLF = "0"; + decayTime = "1.49"; + decayHFRatio = "0.54"; + decayLFRatio = "1.0"; + reflections = "-370"; + reflectionsDelay = "0.007"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "1030"; + reverbDelay = "0.011"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "60.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvLivingRoom ) +{ + envSize = "2.5"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-6000"; + roomLF = "0"; + decayTime = "0.5"; + decayHFRatio = "0.1"; + decayLFRatio = "1.0"; + reflections = "-1376"; + reflectionsDelay = "0.003"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "-1104"; + reverbDelay = "0.004"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvStoneRoom ) +{ + envSize = "11.6"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "300"; + roomLF = "0"; + decayTime = "2.31"; + decayHFRatio = "0.64"; + decayLFRatio = "1.0"; + reflections = "-711"; + reflectionsDelay = "0.012"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "83"; + reverbDelay = "0.017"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "-5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvAuditorium ) +{ + envSize = "21.6"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-476"; + roomLF = "0"; + decayTime = "4.32"; + decayHFRatio = "0.59"; + decayLFRatio = "1.0"; + reflections = "0.789"; + reflectionsDelay = "0.02"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "-289"; + reverbDelay = "0.03"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvConcertHall ) +{ + envSize = "19.6"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-500"; + roomLF = "0"; + decayTime = "3.92"; + decayHFRatio = "0.7"; + decayLFRatio = "1.0"; + reflections = "-1230"; + reflectionsDelay = "0.02"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "-2"; + reverbDelay = "0.029"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvCave ) +{ + envSize = "14.6"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "0"; + roomLF = "0"; + decayTime = "2.91"; + decayHFRatio = "1.3"; + decayLFRatio = "1.0"; + reflections = "-602"; + reflectionsDelay = "0.015"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "-302"; + reverbDelay = "0.022"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x1f; +}; + +singleton SFXEnvironment( AudioEnvArena ) +{ + envSize = "36.2f"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-698"; + roomLF = "0"; + decayTime = "7.24"; + decayHFRatio = "0.33"; + decayLFRatio = "1.0"; + reflections = "-1166"; + reflectionsDelay = "0.02"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "16"; + reverbDelay = "0.03"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvHangar ) +{ + envSize = "50.3"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-1000"; + roomLF = "0"; + decayTime = "10.05"; + decayHFRatio = "0.23"; + decayLFRatio = "1.0"; + reflections = "-602"; + reflectionsDelay = "0.02"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "198"; + reverbDelay = "0.03"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvCarpettedHallway ) +{ + envSize = "1.9"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-4000"; + roomLF = "0"; + decayTime = "0.3"; + decayHFRatio = "0.1"; + decayLFRatio = "1.0"; + reflections = "-1831"; + reflectionsDelay = "0.002"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "-1630"; + reverbDelay = "0.03"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvHallway ) +{ + envSize = "1.8"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-300"; + roomLF = "0"; + decayTime = "1.49"; + decayHFRatio = "0.59"; + decayLFRatio = "1.0"; + reflections = "-1219"; + reflectionsDelay = "0.007"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "441"; + reverbDelay = "0.011"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvStoneCorridor ) +{ + envSize = "13.5"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-237"; + roomLF = "0"; + decayTime = "2.7"; + decayHFRatio = "0.79"; + decayLFRatio = "1.0"; + reflections = "-1214"; + reflectionsDelay = "0.013"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "395"; + reverbDelay = "0.02"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvAlley ) +{ + envSize = "7.5"; + envDiffusion = "0.3"; + room = "-1000"; + roomHF = "-270"; + roomLF = "0"; + decayTime = "1.49"; + decayHFRatio = "0.86"; + decayLFRatio = "1.0"; + reflections = "-1204"; + reflectionsDelay = "0.007"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "-4"; + reverbDelay = "0.011"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.125"; + echoDepth = "0.95"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvForest ) +{ + envSize = "38.0"; + envDiffusion = "0.3"; + room = "-1000"; + roomHF = "-3300"; + roomLF = "0"; + decayTime = "1.49"; + decayHFRatio = "0.54"; + decayLFRatio = "1.0"; + reflections = "-2560"; + reflectionsDelay = "0.162"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "-229"; + reverbDelay = "0.088"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.125"; + echoDepth = "1.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "79.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvCity ) +{ + envSize = "7.5"; + envDiffusion = "0.5"; + room = "-1000"; + roomHF = "-800"; + roomLF = "0"; + decayTime = "1.49"; + decayHFRatio = "0.67"; + decayLFRatio = "1.0"; + reflections = "-2273"; + reflectionsDelay = "0.007"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "-1691"; + reverbDelay = "0.011"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "50.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvMountains ) +{ + envSize = "100.0"; + envDiffusion = "0.27"; + room = "-1000"; + roomHF = "-2500"; + roomLF = "0"; + decayTime = "1.49"; + decayHFRatio = "0.21"; + decayLFRatio = "1.0"; + reflections = "-2780"; + reflectionsDelay = "0.3"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "-1434"; + reverbDelay = "0.1"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "1.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "27.0"; + density = "100.0"; + flags = 0x1f; +}; + +singleton SFXEnvironment( AudioEnvQuary ) +{ + envSize = "17.5"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-1000"; + roomLF = "0"; + decayTime = "1.49"; + decayHFRatio = "0.83"; + decayLFRatio = "1.0"; + reflections = "-10000"; + reflectionsDelay = "0.061"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "500"; + reverbDelay = "0.025"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.125"; + echoDepth = "0.7"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvPlain ) +{ + envSize = "42.5"; + envDiffusion = "0.21"; + room = "-1000"; + roomHF = "-2000"; + roomLF = "0"; + decayTime = "1.49"; + decayHFRatio = "0.5"; + decayLFRatio = "1.0"; + reflections = "-2466"; + reflectionsDelay = "0.179"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "-1926"; + reverbDelay = "0.1"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "1.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "21.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvParkingLot ) +{ + envSize = "8.3"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "0"; + roomLF = "0"; + decayTime = "1.65"; + decayHFRatio = "1.5"; + decayLFRatio = "1.0"; + reflections = "-1363"; + reflectionsDelay = "0.008"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "-1153"; + reverbDelay = "0.012"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x1f; +}; + +singleton SFXEnvironment( AudioEnvSewerPipe ) +{ + envSize = "1.7"; + envDiffusion = "0.8"; + room = "-1000"; + roomHF = "-1000"; + roomLF = "0"; + decayTime = "2.81"; + decayHFRatio = "0.14"; + decayLFRatio = "1.0"; + reflections = "429"; + reflectionsDelay = "0.014"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "1023"; + reverbDelay = "0.21"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "80.0"; + density = "60.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvUnderwater ) +{ + envSize = "1.8"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-4000"; + roomLF = "0"; + decayTime = "1.49"; + decayHFRatio = "0.1"; + decayLFRatio = "1.0"; + reflections = "-449"; + reflectionsDelay = "0.007"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "1700"; + reverbDelay = "0.011"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "1.18"; + modulationDepth = "0.348"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvDrugged ) +{ + envSize = "1.9"; + envDiffusion = "0.5"; + room = "-1000"; + roomHF = "0"; + roomLF = "0"; + decayTime = "8.39"; + decayHFRatio = "1.39"; + decayLFRatio = "1.0"; + reflections = "-115"; + reflectionsDelay = "0.002"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "985"; + reverbDelay = "0.03"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "1.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x1f; +}; + +singleton SFXEnvironment( AudioEnvDizzy ) +{ + envSize = "1.8"; + envDiffusion = "0.6"; + room = "-1000.0"; + roomHF = "-400"; + roomLF = "0"; + decayTime = "17.23"; + decayHFRatio = "0.56"; + decayLFRatio = "1.0"; + reflections = "-1713"; + reflectionsDelay = "0.02"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "-613"; + reverbDelay = "0.03"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "1.0"; + modulationTime = "0.81"; + modulationDepth = "0.31"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x1f; +}; + +singleton SFXEnvironment( AudioEnvPsychotic ) +{ + envSize = "1.0"; + envDiffusion = "0.5"; + room = "-1000"; + roomHF = "-151"; + roomLF = "0"; + decayTime = "7.56"; + decayHFRatio = "0.91"; + decayLFRatio = "1.0"; + reflections = "-626"; + reflectionsDelay = "0.02"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "774"; + reverbDelay = "0.03"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "4.0"; + modulationDepth = "1.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x1f; +}; diff --git a/Templates/Empty/game/core/scripts/client/audioStates.cs b/Templates/Empty/game/core/scripts/client/audioStates.cs new file mode 100644 index 000000000..3ab55cf78 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/audioStates.cs @@ -0,0 +1,158 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Some state presets. + + +/// Return the first active SFXState in the given SimSet/SimGroup. +function sfxGetActiveStateInGroup( %group ) +{ + %count = %group.getCount(); + for( %i = 0; %i < %count; %i ++ ) + { + %obj = %group.getObject( %i ); + if( !%obj.isMemberOfClass( "SFXState" ) ) + continue; + + if( %obj.isActive() ) + return %obj; + } + + return 0; +} + + +//----------------------------------------------------------------------------- +// Special audio state that will always and only be active when no other +// state is active. Useful for letting slots apply specifically when no +// other slot in a list applies. + +singleton SFXState( AudioStateNone ) {}; + +AudioStateNone.activate(); + +function SFXState::onActivate( %this ) +{ + if( %this.getId() != AudioStateNone.getId() ) + AudioStateNone.disable(); +} + +function SFXState::onDeactivate( %this ) +{ + if( %this.getId() != AudioStateNone.getId() ) + AudioStateNone.enable(); +} + +//----------------------------------------------------------------------------- +// AudioStateExclusive class. +// +// Automatically deactivates sibling SFXStates in its parent SimGroup +// when activated. + +function AudioStateExclusive::onActivate( %this ) +{ + Parent::onActivate( %this ); + + %group = %this.parentGroup; + %count = %group.getCount(); + + for( %i = 0; %i < %count; %i ++ ) + { + %obj = %group.getObject( %i ); + + if( %obj != %this && %obj.isMemberOfClass( "SFXState" ) && %obj.isActive() ) + %obj.deactivate(); + } +} + +//----------------------------------------------------------------------------- +// Location-dependent states. + +singleton SimGroup( AudioLocation ); + +/// State when the listener is outside. +singleton SFXState( AudioLocationOutside ) +{ + parentGroup = AudioLocation; + className = "AudioStateExclusive"; +}; + +/// State when the listener is submerged. +singleton SFXState( AudioLocationUnderwater ) +{ + parentGroup = AudioLocation; + className = "AudioStateExclusive"; +}; + +/// State when the listener is indoors. +singleton SFXState( AudioLocationInside ) +{ + parentGroup = AudioLocation; + className = "AudioStateExclusive"; +}; + +/// Return the currently active SFXState in AudioLocation. +function sfxGetLocation() +{ + return sfxGetActiveStateInGroup( AudioLocation ); +} + +//----------------------------------------------------------------------------- +// Mood-dependent states. + +singleton SimGroup( AudioMood ); + +singleton SFXState( AudioMoodNeutral ) +{ + parentGroup = AudioMood; + className = "AudioStateExclusive"; +}; + +singleton SFXState( AudioMoodAggressive ) +{ + parentGroup = AudioMood; + className = "AudioStateExclusive"; +}; + +singleton SFXState( AudioMoodTense ) +{ + parentGroup = AudioMood; + className = "AudioStateExclusive"; +}; + +singleton SFXState( AudioMoodVictory ) +{ + parentGroup = AudioMood; + className = "AudioStateExclusive"; +}; + +singleton SFXState( AudioMoodCalm ) +{ + parentGroup = AudioMood; + className = "AudioStateExclusive"; +}; + +/// Return the currently active SFXState in AudioMood. +function sfxGetMood() +{ + return sfxGetActiveStateInGroup( AudioMood ); +} diff --git a/Templates/Empty/game/core/scripts/client/canvas.cs b/Templates/Empty/game/core/scripts/client/canvas.cs new file mode 100644 index 000000000..69dd6da71 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/canvas.cs @@ -0,0 +1,188 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//--------------------------------------------------------------------------------------------- +// initializeCanvas +// Constructs and initializes the default canvas window. +//--------------------------------------------------------------------------------------------- +$canvasCreated = false; + +function configureCanvas() +{ + // Setup a good default if we don't have one already. + if ($pref::Video::mode $= "") + $pref::Video::mode = "800 600 false 32 60 0"; + + %resX = getWord($pref::Video::mode, $WORD::RES_X); + %resY = getWord($pref::Video::mode, $WORD::RES_Y); + %fs = getWord($pref::Video::mode, $WORD::FULLSCREEN); + %bpp = getWord($pref::Video::mode, $WORD::BITDEPTH); + %rate = getWord($pref::Video::mode, $WORD::REFRESH); + %fsaa = getWord($pref::Video::mode, $WORD::AA); + + echo("--------------"); + echo("Attempting to set resolution to \"" @ $pref::Video::mode @ "\""); + + %deskRes = getDesktopResolution(); + %deskResX = getWord(%deskRes, $WORD::RES_X); + %deskResY = getWord(%deskRes, $WORD::RES_Y); + %deskResBPP = getWord(%deskRes, 2); + + // We shouldn't be getting this any more but just in case... + if (%bpp $= "Default") + %bpp = %deskResBPP; + + // Make sure we are running at a valid resolution + if (%fs $= "0" || %fs $= "false") + { + // Windowed mode has to use the same bit depth as the desktop + %bpp = %deskResBPP; + + // Windowed mode also has to run at a smaller resolution than the desktop + if ((%resX >= %deskResX) || (%resY >= %deskResY)) + { + warn("Warning: The requested windowed resolution is equal to or larger than the current desktop resolution. Attempting to find a better resolution"); + + %resCount = Canvas.getModeCount(); + for (%i = (%resCount - 1); %i >= 0; %i--) + { + %testRes = Canvas.getMode(%i); + %testResX = getWord(%testRes, $WORD::RES_X); + %testResY = getWord(%testRes, $WORD::RES_Y); + %testBPP = getWord(%testRes, $WORD::BITDEPTH); + + if (%testBPP != %bpp) + continue; + + if ((%testResX < %deskResX) && (%testResY < %deskResY)) + { + // This will work as our new resolution + %resX = %testResX; + %resY = %testResY; + + warn("Warning: Switching to \"" @ %resX SPC %resY SPC %bpp @ "\""); + + break; + } + } + } + } + + $pref::Video::mode = %resX SPC %resY SPC %fs SPC %bpp SPC %rate SPC %fsaa; + + if (%fs == 1 || %fs $= "true") + %fsLabel = "Yes"; + else + %fsLabel = "No"; + + echo("Accepted Mode: " NL + "--Resolution : " @ %resX SPC %resY NL + "--Full Screen : " @ %fsLabel NL + "--Bits Per Pixel : " @ %bpp NL + "--Refresh Rate : " @ %rate NL + "--FSAA Level : " @ %fsaa NL + "--------------"); + + // Actually set the new video mode + Canvas.setVideoMode(%resX, %resY, %fs, %bpp, %rate, %fsaa); + + // FXAA piggybacks on the FSAA setting in $pref::Video::mode. + if ( isObject( FXAA_PostEffect ) ) + FXAA_PostEffect.isEnabled = ( %fsaa > 0 ) ? true : false; + + //if ( $pref::Video::autoDetect ) + // GraphicsQualityAutodetect(); +} + +function initializeCanvas() +{ + // Don't duplicate the canvas. + if($canvasCreated) + { + error("Cannot instantiate more than one canvas!"); + return; + } + + if (!createCanvas()) + { + error("Canvas creation failed. Shutting down."); + quit(); + } + + $canvasCreated = true; +} + +//--------------------------------------------------------------------------------------------- +// resetCanvas +// Forces the canvas to redraw itself. +//--------------------------------------------------------------------------------------------- +function resetCanvas() +{ + if (isObject(Canvas)) + Canvas.repaint(); +} + +//--------------------------------------------------------------------------------------------- +// Callbacks for window events. +//--------------------------------------------------------------------------------------------- + +function GuiCanvas::onLoseFocus(%this) +{ +} + +//--------------------------------------------------------------------------------------------- +// Full screen handling +//--------------------------------------------------------------------------------------------- + +function GuiCanvas::attemptFullscreenToggle(%this) +{ + // If the Editor is running then we cannot enter full screen mode + if ( EditorIsActive() && !%this.isFullscreen() ) + { + MessageBoxOK("Windowed Mode Required", "Please exit the Mission Editor to switch to full screen."); + return; + } + + // If the GUI Editor is running then we cannot enter full screen mode + if ( GuiEditorIsActive() && !%this.isFullscreen() ) + { + MessageBoxOK("Windowed Mode Required", "Please exit the GUI Editor to switch to full screen."); + return; + } + + %this.toggleFullscreen(); +} + +//--------------------------------------------------------------------------------------------- +// Editor Checking +// Needs to be outside of the tools directory so these work in non-tools builds +//--------------------------------------------------------------------------------------------- + +function EditorIsActive() +{ + return ( isObject(EditorGui) && Canvas.getContent() == EditorGui.getId() ); +} + +function GuiEditorIsActive() +{ + return ( isObject(GuiEditorGui) && Canvas.getContent() == GuiEditorGui.getId() ); +} diff --git a/Templates/Empty/game/core/scripts/client/centerPrint.cs b/Templates/Empty/game/core/scripts/client/centerPrint.cs new file mode 100644 index 000000000..846afdbd8 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/centerPrint.cs @@ -0,0 +1,95 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +$centerPrintActive = 0; +$bottomPrintActive = 0; + +// Selectable window sizes +$CenterPrintSizes[1] = 20; +$CenterPrintSizes[2] = 36; +$CenterPrintSizes[3] = 56; + +// time is specified in seconds +function clientCmdCenterPrint( %message, %time, %size ) +{ + // if centerprint already visible, reset text and time. + if ($centerPrintActive) { + if (centerPrintDlg.removePrint !$= "") + cancel(centerPrintDlg.removePrint); + } + else { + CenterPrintDlg.visible = 1; + $centerPrintActive = 1; + } + + CenterPrintText.setText( "" @ %message ); + CenterPrintDlg.extent = firstWord(CenterPrintDlg.extent) @ " " @ $CenterPrintSizes[%size]; + + if (%time > 0) + centerPrintDlg.removePrint = schedule( ( %time * 1000 ), 0, "clientCmdClearCenterPrint" ); +} + +// time is specified in seconds +function clientCmdBottomPrint( %message, %time, %size ) +{ + // if bottomprint already visible, reset text and time. + if ($bottomPrintActive) { + if( bottomPrintDlg.removePrint !$= "") + cancel(bottomPrintDlg.removePrint); + } + else { + bottomPrintDlg.setVisible(true); + $bottomPrintActive = 1; + } + + bottomPrintText.setText( "" @ %message ); + bottomPrintDlg.extent = firstWord(bottomPrintDlg.extent) @ " " @ $CenterPrintSizes[%size]; + + if (%time > 0) + bottomPrintDlg.removePrint = schedule( ( %time * 1000 ), 0, "clientCmdClearbottomPrint" ); +} + +function BottomPrintText::onResize(%this, %width, %height) +{ + %this.position = "0 0"; +} + +function CenterPrintText::onResize(%this, %width, %height) +{ + %this.position = "0 0"; +} + +//------------------------------------------------------------------------------------------------------- + +function clientCmdClearCenterPrint() +{ + $centerPrintActive = 0; + CenterPrintDlg.visible = 0; + CenterPrintDlg.removePrint = ""; +} + +function clientCmdClearBottomPrint() +{ + $bottomPrintActive = 0; + BottomPrintDlg.visible = 0; + BottomPrintDlg.removePrint = ""; +} diff --git a/Templates/Empty/game/core/scripts/client/client.cs b/Templates/Empty/game/core/scripts/client/client.cs new file mode 100644 index 000000000..4c8810e77 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/client.cs @@ -0,0 +1,62 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function initBaseClient() +{ + // Base client functionality + exec( "./message.cs" ); + exec( "./mission.cs" ); + exec( "./missionDownload.cs" ); + exec( "./actionMap.cs" ); + exec( "./renderManager.cs" ); + exec( "./lighting.cs" ); + + initRenderManager(); + initLightingSystems(); +} + +/// A helper function which will return the ghosted client object +/// from a server object when connected to a local server. +function serverToClientObject( %serverObject ) +{ + assert( isObject( LocalClientConnection ), "serverToClientObject() - No local client connection found!" ); + assert( isObject( ServerConnection ), "serverToClientObject() - No server connection found!" ); + + %ghostId = LocalClientConnection.getGhostId( %serverObject ); + if ( %ghostId == -1 ) + return 0; + + return ServerConnection.resolveGhostID( %ghostId ); +} + +//---------------------------------------------------------------------------- +// Debug commands +//---------------------------------------------------------------------------- + +function netSimulateLag( %msDelay, %packetLossPercent ) +{ + if ( %packetLossPercent $= "" ) + %packetLossPercent = 0; + + commandToServer( 'NetSimulateLag', %msDelay, %packetLossPercent ); +} + diff --git a/Templates/Empty/game/core/scripts/client/clouds.cs b/Templates/Empty/game/core/scripts/client/clouds.cs new file mode 100644 index 000000000..2763ce182 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/clouds.cs @@ -0,0 +1,51 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +// CloudLayer +//------------------------------------------------------------------------------ + +singleton ShaderData( CloudLayerShader ) +{ + DXVertexShaderFile = "shaders/common/cloudLayerV.hlsl"; + DXPixelShaderFile = "shaders/common/cloudLayerP.hlsl"; + + OGLVertexShaderFile = "shaders/common/gl/cloudLayerV.glsl"; + OGLPixelShaderFile = "shaders/common/gl/cloudLayerP.glsl"; + + pixVersion = 2.0; +}; + +//------------------------------------------------------------------------------ +// BasicClouds +//------------------------------------------------------------------------------ + +singleton ShaderData( BasicCloudsShader ) +{ + DXVertexShaderFile = "shaders/common/basicCloudsV.hlsl"; + DXPixelShaderFile = "shaders/common/basicCloudsP.hlsl"; + + //OGLVertexShaderFile = "shaders/common/gl/basicCloudsV.glsl"; + //OGLPixelShaderFile = "shaders/common/gl/basicCloudsP.glsl"; + + pixVersion = 2.0; +}; diff --git a/Templates/Empty/game/core/scripts/client/commands.cs b/Templates/Empty/game/core/scripts/client/commands.cs new file mode 100644 index 000000000..28c45007d --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/commands.cs @@ -0,0 +1,28 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Sync the Camera and the EditorGui +function clientCmdSyncEditorGui() +{ + if (isObject(EditorGui)) + EditorGui.syncCameraGui(); +} \ No newline at end of file diff --git a/Templates/Empty/game/core/scripts/client/commonMaterialData.cs b/Templates/Empty/game/core/scripts/client/commonMaterialData.cs new file mode 100644 index 000000000..c5d8ef5bc --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/commonMaterialData.cs @@ -0,0 +1,79 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Anim flag settings - must match material.h +// These cannot be enumed through script becuase it cannot +// handle the "|" operation for combining them together +// ie. Scroll | Wave does not work. +//----------------------------------------------------------------------------- +$scroll = 1; +$rotate = 2; +$wave = 4; +$scale = 8; +$sequence = 16; + + +// Common stateblock definitions +new GFXSamplerStateData(SamplerClampLinear) +{ + textureColorOp = GFXTOPModulate; + addressModeU = GFXAddressClamp; + addressModeV = GFXAddressClamp; + addressModeW = GFXAddressClamp; + magFilter = GFXTextureFilterLinear; + minFilter = GFXTextureFilterLinear; + mipFilter = GFXTextureFilterLinear; +}; + +new GFXSamplerStateData(SamplerClampPoint) +{ + textureColorOp = GFXTOPModulate; + addressModeU = GFXAddressClamp; + addressModeV = GFXAddressClamp; + addressModeW = GFXAddressClamp; + magFilter = GFXTextureFilterPoint; + minFilter = GFXTextureFilterPoint; + mipFilter = GFXTextureFilterPoint; +}; + +new GFXSamplerStateData(SamplerWrapLinear) +{ + textureColorOp = GFXTOPModulate; + addressModeU = GFXTextureAddressWrap; + addressModeV = GFXTextureAddressWrap; + addressModeW = GFXTextureAddressWrap; + magFilter = GFXTextureFilterLinear; + minFilter = GFXTextureFilterLinear; + mipFilter = GFXTextureFilterLinear; +}; + +new GFXSamplerStateData(SamplerWrapPoint) +{ + textureColorOp = GFXTOPModulate; + addressModeU = GFXTextureAddressWrap; + addressModeV = GFXTextureAddressWrap; + addressModeW = GFXTextureAddressWrap; + magFilter = GFXTextureFilterPoint; + minFilter = GFXTextureFilterPoint; + mipFilter = GFXTextureFilterPoint; +}; diff --git a/Templates/Empty/game/core/scripts/client/core.cs b/Templates/Empty/game/core/scripts/client/core.cs new file mode 100644 index 000000000..fef2df7d2 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/core.cs @@ -0,0 +1,275 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//--------------------------------------------------------------------------------------------- +// initializeCore +// Initializes core game functionality. +//--------------------------------------------------------------------------------------------- +function initializeCore() +{ + // Not Reentrant + if( $coreInitialized == true ) + return; + + // Core keybindings. + GlobalActionMap.bind(keyboard, tilde, toggleConsole); + GlobalActionMap.bind(keyboard, "ctrl p", doScreenShot); + GlobalActionMap.bindcmd(keyboard, "alt enter", "Canvas.attemptFullscreenToggle();",""); + GlobalActionMap.bindcmd(keyboard, "alt k", "cls();", ""); +// GlobalActionMap.bindCmd(keyboard, "escape", "", "handleEscape();"); + + + + // Very basic functions used by everyone. + exec("./audio.cs"); + exec("./canvas.cs"); + exec("./cursor.cs"); + exec("./persistenceManagerTest.cs"); + + // Content. + exec("~/art/gui/profiles.cs"); + exec("~/scripts/gui/cursors.cs"); + + exec( "./audioEnvironments.cs" ); + exec( "./audioDescriptions.cs" ); + exec( "./audioStates.cs" ); + exec( "./audioAmbiences.cs" ); + + // Seed the random number generator. + setRandomSeed(); + + // Set up networking. + setNetPort(0); + + // Initialize the canvas. + initializeCanvas(); + + // Start processing file change events. + startFileChangeNotifications(); + + // Core Guis. + exec("~/art/gui/remapDlg.gui"); + exec("~/art/gui/console.gui"); + exec("~/art/gui/consoleVarDlg.gui"); + exec("~/art/gui/netGraphGui.gui"); + + // Gui Helper Scripts. + exec("~/scripts/gui/help.cs"); + + // Random Scripts. + exec("~/scripts/client/screenshot.cs"); + exec("~/scripts/client/scriptDoc.cs"); + //exec("~/scripts/client/keybindings.cs"); + exec("~/scripts/client/helperfuncs.cs"); + exec("~/scripts/client/commands.cs"); + + // Client scripts + exec("~/scripts/client/devHelpers.cs"); + exec("~/scripts/client/metrics.cs"); + exec("~/scripts/client/recordings.cs"); + exec("~/scripts/client/centerPrint.cs"); + + // Materials and Shaders for rendering various object types + loadCoreMaterials(); + + exec("~/scripts/client/commonMaterialData.cs"); + exec("~/scripts/client/shaders.cs"); + exec("~/scripts/client/materials.cs"); + exec("~/scripts/client/terrainBlock.cs"); + exec("~/scripts/client/water.cs"); + exec("~/scripts/client/imposter.cs"); + exec("~/scripts/client/scatterSky.cs"); + exec("~/scripts/client/clouds.cs"); + + // Initialize all core post effects. + exec("~/scripts/client/postFx.cs"); + initPostEffects(); + + // Initialize the post effect manager. + exec("~/scripts/client/postFx/postFXManager.gui"); + exec("~/scripts/client/postFx/postFXManager.gui.cs"); + exec("~/scripts/client/postFx/postFXManager.gui.settings.cs"); + exec("~/scripts/client/postFx/postFXManager.persistance.cs"); + + PostFXManager.settingsApplyDefaultPreset(); // Get the default preset settings + + // Set a default cursor. + Canvas.setCursor(DefaultCursor); + + loadKeybindings(); + + $coreInitialized = true; +} + +//--------------------------------------------------------------------------------------------- +// shutdownCore +// Shuts down core game functionality. +//--------------------------------------------------------------------------------------------- +function shutdownCore() +{ + // Stop file change events. + stopFileChangeNotifications(); + + sfxShutdown(); +} + +//--------------------------------------------------------------------------------------------- +// dumpKeybindings +// Saves of all keybindings. +//--------------------------------------------------------------------------------------------- +function dumpKeybindings() +{ + // Loop through all the binds. + for (%i = 0; %i < $keybindCount; %i++) + { + // If we haven't dealt with this map yet... + if (isObject($keybindMap[%i])) + { + // Save and delete. + $keybindMap[%i].save(getPrefsPath("bind.cs"), %i == 0 ? false : true); + $keybindMap[%i].delete(); + } + } +} + +function handleEscape() +{ + + if (isObject(EditorGui)) + { + if (Canvas.getContent() == EditorGui.getId()) + { + EditorGui.handleEscape(); + return; + } + else if ( EditorIsDirty() ) + { + MessageBoxYesNoCancel( "Level Modified", "Level has been modified in the Editor. Save?", + "EditorDoExitMission(1);", + "EditorDoExitMission();", + ""); + return; + } + } + + if (isObject(GuiEditor)) + { + if (GuiEditor.isAwake()) + { + GuiEditCanvas.quit(); + return; + } + } + + if (PlayGui.isAwake()) + escapeFromGame(); +} + +//----------------------------------------------------------------------------- +// loadMaterials - load all materials.cs files +//----------------------------------------------------------------------------- +function loadCoreMaterials() +{ + // Load any materials files for which we only have DSOs. + + for( %file = findFirstFile( "core/materials.cs.dso" ); + %file !$= ""; + %file = findNextFile( "core/materials.cs.dso" )) + { + // Only execute, if we don't have the source file. + %csFileName = getSubStr( %file, 0, strlen( %file ) - 4 ); + if( !isFile( %csFileName ) ) + exec( %csFileName ); + } + + // Load all source material files. + + for( %file = findFirstFile( "core/materials.cs" ); + %file !$= ""; + %file = findNextFile( "core/materials.cs" )) + { + exec( %file ); + } +} + +function reloadCoreMaterials() +{ + reloadTextures(); + loadCoreMaterials(); + reInitMaterials(); +} + +//----------------------------------------------------------------------------- +// loadMaterials - load all materials.cs files +//----------------------------------------------------------------------------- +function loadMaterials() +{ + // Load any materials files for which we only have DSOs. + + for( %file = findFirstFile( "*/materials.cs.dso" ); + %file !$= ""; + %file = findNextFile( "*/materials.cs.dso" )) + { + // Only execute, if we don't have the source file. + %csFileName = getSubStr( %file, 0, strlen( %file ) - 4 ); + if( !isFile( %csFileName ) ) + exec( %csFileName ); + } + + // Load all source material files. + + for( %file = findFirstFile( "*/materials.cs" ); + %file !$= ""; + %file = findNextFile( "*/materials.cs" )) + { + exec( %file ); + } + + // Load all materials created by the material editor if + // the folder exists + if( IsDirectory( "materialEditor" ) ) + { + for( %file = findFirstFile( "materialEditor/*.cs.dso" ); + %file !$= ""; + %file = findNextFile( "materialEditor/*.cs.dso" )) + { + // Only execute, if we don't have the source file. + %csFileName = getSubStr( %file, 0, strlen( %file ) - 4 ); + if( !isFile( %csFileName ) ) + exec( %csFileName ); + } + + for( %file = findFirstFile( "materialEditor/*.cs" ); + %file !$= ""; + %file = findNextFile( "materialEditor/*.cs" )) + { + exec( %file ); + } + } +} + +function reloadMaterials() +{ + reloadTextures(); + loadMaterials(); + reInitMaterials(); +} \ No newline at end of file diff --git a/Templates/Empty/game/core/scripts/client/cursor.cs b/Templates/Empty/game/core/scripts/client/cursor.cs new file mode 100644 index 000000000..f71bc023a --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/cursor.cs @@ -0,0 +1,102 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//--------------------------------------------------------------------------------------------- +// Cursor toggle functions. +//--------------------------------------------------------------------------------------------- +$cursorControlled = true; +function showCursor() +{ + if ($cursorControlled) + lockMouse(false); + Canvas.cursorOn(); +} + +function hideCursor() +{ + if ($cursorControlled) + lockMouse(true); + Canvas.cursorOff(); +} + +//--------------------------------------------------------------------------------------------- +// In the CanvasCursor package we add some additional functionality to the built-in GuiCanvas +// class, of which the global Canvas object is an instance. In this case, the behavior we want +// is for the cursor to automatically display, except when the only guis visible want no +// cursor - usually the in game interface. +//--------------------------------------------------------------------------------------------- +package CanvasCursorPackage +{ + +//--------------------------------------------------------------------------------------------- +// checkCursor +// The checkCursor method iterates through all the root controls on the canvas checking each +// ones noCursor property. If the noCursor property exists as anything other than false or an +// empty string on every control, the cursor will be hidden. +//--------------------------------------------------------------------------------------------- +function GuiCanvas::checkCursor(%this) +{ + %count = %this.getCount(); + for(%i = 0; %i < %count; %i++) + { + %control = %this.getObject(%i); + if ((%control.noCursor $= "") || !%control.noCursor) + { + showCursor(); + return; + } + } + // If we get here, every control requested a hidden cursor, so we oblige. + hideCursor(); +} + +//--------------------------------------------------------------------------------------------- +// The following functions override the GuiCanvas defaults that involve changing the content +// of the Canvas. Basically, all we are doing is adding a call to checkCursor to each one. +//--------------------------------------------------------------------------------------------- +function GuiCanvas::setContent(%this, %ctrl) +{ + Parent::setContent(%this, %ctrl); + %this.checkCursor(); +} + +function GuiCanvas::pushDialog(%this, %ctrl, %layer, %center) +{ + Parent::pushDialog(%this, %ctrl, %layer, %center); + %this.checkCursor(); +} + +function GuiCanvas::popDialog(%this, %ctrl) +{ + Parent::popDialog(%this, %ctrl); + %this.checkCursor(); +} + +function GuiCanvas::popLayer(%this, %layer) +{ + Parent::popLayer(%this, %layer); + %this.checkCursor(); +} + +}; + +activatePackage(CanvasCursorPackage); diff --git a/Templates/Empty/game/core/scripts/client/defaults.cs b/Templates/Empty/game/core/scripts/client/defaults.cs new file mode 100644 index 000000000..87a77b295 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/defaults.cs @@ -0,0 +1,509 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// The master server is declared with the server defaults, which is +// loaded on both clients & dedicated servers. If the server mod +// is not loaded on a client, then the master must be defined. +// $pref::Master[0] = "2:master.garagegames.com:28002"; + +$pref::Player::Name = "Visitor"; +$pref::Player::defaultFov = 65; +$pref::Player::zoomSpeed = 0; + +$pref::Net::LagThreshold = 400; +$pref::Net::Port = 28000; + +$pref::HudMessageLogSize = 40; +$pref::ChatHudLength = 1; + +$pref::Input::LinkMouseSensitivity = 1; +// DInput keyboard, mouse, and joystick prefs +$pref::Input::KeyboardEnabled = 1; +$pref::Input::MouseEnabled = 1; +$pref::Input::JoystickEnabled = 0; +$pref::Input::KeyboardTurnSpeed = 0.1; + +$sceneLighting::cacheSize = 20000; +$sceneLighting::purgeMethod = "lastCreated"; +$sceneLighting::cacheLighting = 1; + +$pref::Video::displayDevice = "D3D9"; +$pref::Video::disableVerticalSync = 1; +$pref::Video::mode = "1024 768 false 32 60 4"; +$pref::Video::defaultFenceCount = 0; +$pref::Video::screenShotSession = 0; +$pref::Video::screenShotFormat = "PNG"; + +/// This disables the hardware FSAA/MSAA so that +/// we depend completely on the FXAA post effect +/// which works on all cards and in deferred mode. +/// +/// Note the new Intel Hybrid graphics on laptops +/// will fail to initialize when hardware AA is +/// enabled... so you've been warned. +/// +$pref::Video::disableHardwareAA = true; + +$pref::Video::disableNormalmapping = false; + +$pref::Video::disablePixSpecular = false; + +$pref::Video::disableCubemapping = false; + +/// +$pref::Video::disableParallaxMapping = false; + +$pref::Video::Gamma = 1.0; + +// Console-friendly defaults +if($platform $= "xenon") +{ + // Save some fillrate on the X360, and take advantage of the HW scaling + $pref::Video::Resolution = "1152 640"; + $pref::Video::mode = $pref::Video::Resolution SPC "true 32 60 0"; + $pref::Video::fullScreen = 1; +} + +/// This is the path used by ShaderGen to cache procedural +/// shaders. If left blank ShaderGen will only cache shaders +/// to memory and not to disk. +$shaderGen::cachePath = "shaders/procedural"; + +/// The perfered light manager to use at startup. If blank +/// or if the selected one doesn't work on this platfom it +/// will try the defaults below. +$pref::lightManager = ""; + +/// This is the default list of light managers ordered from +/// most to least desirable for initialization. +$lightManager::defaults = "Advanced Lighting" NL "Basic Lighting"; + +/// A scale to apply to the camera view distance +/// typically used for tuning performance. +$pref::camera::distanceScale = 1.0; + +/// Causes the system to do a one time autodetect +/// of an SFX provider and device at startup if the +/// provider is unset. +$pref::SFX::autoDetect = true; + +/// The sound provider to select at startup. Typically +/// this is DirectSound, OpenAL, or XACT. There is also +/// a special Null provider which acts normally, but +/// plays no sound. +$pref::SFX::provider = ""; + +/// The sound device to select from the provider. Each +/// provider may have several different devices. +$pref::SFX::device = "OpenAL"; + +/// If true the device will try to use hardware buffers +/// and sound mixing. If not it will use software. +$pref::SFX::useHardware = false; + +/// If you have a software device you have a +/// choice of how many software buffers to +/// allow at any one time. More buffers cost +/// more CPU time to process and mix. +$pref::SFX::maxSoftwareBuffers = 16; + +/// This is the playback frequency for the primary +/// sound buffer used for mixing. Although most +/// providers will reformat on the fly, for best +/// quality and performance match your sound files +/// to this setting. +$pref::SFX::frequency = 44100; + +/// This is the playback bitrate for the primary +/// sound buffer used for mixing. Although most +/// providers will reformat on the fly, for best +/// quality and performance match your sound files +/// to this setting. +$pref::SFX::bitrate = 32; + +/// The overall system volume at startup. Note that +/// you can only scale volume down, volume does not +/// get louder than 1. +$pref::SFX::masterVolume = 0.8; + +/// The startup sound channel volumes. These are +/// used to control the overall volume of different +/// classes of sounds. +$pref::SFX::channelVolume1 = 1; +$pref::SFX::channelVolume2 = 1; +$pref::SFX::channelVolume3 = 1; +$pref::SFX::channelVolume4 = 1; +$pref::SFX::channelVolume5 = 1; +$pref::SFX::channelVolume6 = 1; +$pref::SFX::channelVolume7 = 1; +$pref::SFX::channelVolume8 = 1; + +$pref::PostEffect::PreferedHDRFormat = "GFXFormatR8G8B8A8"; + +/// This is an scalar which can be used to reduce the +/// reflection textures on all objects to save fillrate. +$pref::Reflect::refractTexScale = 1.0; + +/// This is the total frame in milliseconds to budget for +/// reflection rendering. If your CPU bound and have alot +/// of smaller reflection surfaces try reducing this time. +$pref::Reflect::frameLimitMS = 10; + +/// Set true to force all water objects to use static cubemap reflections. +$pref::Water::disableTrueReflections = false; + +// A global LOD scalar which can reduce the overall density of placed GroundCover. +$pref::GroundCover::densityScale = 1.0; + +/// An overall scaler on the lod switching between DTS models. +/// Smaller numbers makes the lod switch sooner. +$pref::TS::detailAdjust = 1.0; + +/// +$pref::Decals::enabled = true; + +/// +$pref::Decals::lifeTimeScale = "1"; + +/// The number of mipmap levels to drop on loaded textures +/// to reduce video memory usage. +/// +/// It will skip any textures that have been defined as not +/// allowing down scaling. +/// +$pref::Video::textureReductionLevel = 0; + +/// +$pref::Shadows::textureScalar = 1.0; + +/// +$pref::Shadows::disable = false; + +/// Sets the shadow filtering mode. +/// +/// None - Disables filtering. +/// +/// SoftShadow - Does a simple soft shadow +/// +/// SoftShadowHighQuality +/// +$pref::Shadows::filterMode = "SoftShadow"; + +/// +$pref::Video::defaultAnisotropy = 1; + +/// Radius in meters around the camera that ForestItems are affected by wind. +/// Note that a very large number with a large number of items is not cheap. +$pref::windEffectRadius = 25; + +/// AutoDetect graphics quality levels the next startup. +$pref::Video::autoDetect = 1; + +//----------------------------------------------------------------------------- +// Graphics Quality Groups +//----------------------------------------------------------------------------- + +// The graphics quality groups are used by the options dialog to +// control the state of the $prefs. You should overload these in +// your game specific defaults.cs file if they need to be changed. + +if ( isObject( MeshQualityGroup ) ) + MeshQualityGroup.delete(); +if ( isObject( TextureQualityGroup ) ) + TextureQualityGroup.delete(); +if ( isObject( LightingQualityGroup ) ) + LightingQualityGroup.delete(); +if ( isObject( ShaderQualityGroup ) ) + ShaderQualityGroup.delete(); + +new SimGroup( MeshQualityGroup ) +{ + new ArrayObject( [Lowest] ) + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + key["$pref::TS::detailAdjust"] = 0.5; + key["$pref::TS::skipRenderDLs"] = 1; + key["$pref::Terrain::lodScale"] = 2.0; + key["$pref::decalMgr::enabled"] = false; + key["$pref::GroundCover::densityScale"] = 0.5; + }; + + new ArrayObject( [Low] ) + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + key["$pref::TS::detailAdjust"] = 0.75; + key["$pref::TS::skipRenderDLs"] = 0; + key["$pref::Terrain::lodScale"] = 1.5; + key["$pref::decalMgr::enabled"] = true; + key["$pref::GroundCover::densityScale"] = 0.75; + }; + + new ArrayObject( [Normal] ) + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + key["$pref::TS::detailAdjust"] = 1.0; + key["$pref::TS::skipRenderDLs"] = 0; + key["$pref::Terrain::lodScale"] = 1.0; + key["$pref::decalMgr::enabled"] = true; + key["$pref::GroundCover::densityScale"] = 1.0; + }; + + new ArrayObject( [High] ) + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + key["$pref::TS::detailAdjust"] = 1.5; + key["$pref::TS::skipRenderDLs"] = 0; + key["$pref::Terrain::lodScale"] = 0.75; + key["$pref::decalMgr::enabled"] = true; + key["$pref::GroundCover::densityScale"] = 1.0; + }; +}; + + +new SimGroup( TextureQualityGroup ) +{ + new ArrayObject( [Lowest] ) + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + key["$pref::Video::textureReductionLevel"] = 2; + key["$pref::Reflect::refractTexScale"] = 0.5; + key["$pref::Terrain::detailScale"] = 0.5; + }; + + new ArrayObject( [Low] ) + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + key["$pref::Video::textureReductionLevel"] = 1; + key["$pref::Reflect::refractTexScale"] = 0.75; + key["$pref::Terrain::detailScale"] = 0.75; + }; + + new ArrayObject( [Normal] ) + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + key["$pref::Video::textureReductionLevel"] = 0; + key["$pref::Reflect::refractTexScale"] = 1; + key["$pref::Terrain::detailScale"] = 1; + }; + + new ArrayObject( [High] ) + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + key["$pref::Video::textureReductionLevel"] = 0; + key["$pref::Reflect::refractTexScale"] = 1.25; + key["$pref::Terrain::detailScale"] = 1.5; + }; +}; + +function TextureQualityGroup::onApply( %this, %level ) +{ + // Note that this can be a slow operation. + reloadTextures(); +} + + +new SimGroup( LightingQualityGroup ) +{ + new ArrayObject( [Lowest] ) + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + key["$pref::lightManager"] = "Basic Lighting"; + key["$pref::Shadows::disable"] = false; + key["$pref::Shadows::textureScalar"] = 0.5; + key["$pref::Shadows::filterMode"] = "None"; + }; + + new ArrayObject( [Low] ) + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + key["$pref::lightManager"] = "Advanced Lighting"; + key["$pref::Shadows::disable"] = false; + key["$pref::Shadows::textureScalar"] = 0.5; + key["$pref::Shadows::filterMode"] = "SoftShadow"; + }; + + new ArrayObject( [Normal] ) + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + key["$pref::lightManager"] = "Advanced Lighting"; + key["$pref::Shadows::disable"] = false; + key["$pref::Shadows::textureScalar"] = 1.0; + key["$pref::Shadows::filterMode"] = "SoftShadowHighQuality"; + }; + + new ArrayObject( [High] ) + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + key["$pref::lightManager"] = "Advanced Lighting"; + key["$pref::Shadows::disable"] = false; + key["$pref::Shadows::textureScalar"] = 2.0; + key["$pref::Shadows::filterMode"] = "SoftShadowHighQuality"; + }; +}; + +function LightingQualityGroup::onApply( %this, %level ) +{ + // Set the light manager. This should do nothing + // if its already set or if its not compatible. + setLightManager( $pref::lightManager ); +} + + +// TODO: Reduce shader complexity of water and the scatter sky here! +new SimGroup( ShaderQualityGroup ) +{ + new ArrayObject( [Lowest] ) + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + key["$pref::Video::disablePixSpecular"] = true; + key["$pref::Video::disableNormalmapping"] = true; + key["$pref::Video::disableParallaxMapping"] = true; + key["$pref::Water::disableTrueReflections"] = true; + }; + + new ArrayObject( [Low] ) + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + key["$pref::Video::disablePixSpecular"] = false; + key["$pref::Video::disableNormalmapping"] = false; + key["$pref::Video::disableParallaxMapping"] = true; + key["$pref::Water::disableTrueReflections"] = true; + }; + + new ArrayObject( [Normal] ) + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + key["$pref::Video::disablePixSpecular"] = false; + key["$pref::Video::disableNormalmapping"] = false; + key["$pref::Video::disableParallaxMapping"] = false; + key["$pref::Water::disableTrueReflections"] = false; + }; + + new ArrayObject( [High] ) + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + key["$pref::Video::disablePixSpecular"] = false; + key["$pref::Video::disableNormalmapping"] = false; + key["$pref::Video::disableParallaxMapping"] = false; + key["$pref::Water::disableTrueReflections"] = false; + }; +}; + + +function GraphicsQualityAutodetect() +{ + $pref::Video::autoDetect = false; + + %shaderVer = getPixelShaderVersion(); + %intel = ( strstr( strupr( getDisplayDeviceInformation() ), "INTEL" ) != -1 ) ? true : false; + %videoMem = GFXCardProfilerAPI::getVideoMemoryMB(); + + return GraphicsQualityAutodetect_Apply( %shaderVer, %intel, %videoMem ); +} + +function GraphicsQualityAutodetect_Apply( %shaderVer, %intel, %videoMem ) +{ + if ( %shaderVer < 2.0 ) + { + return "Your video card does not meet the minimum requirment of shader model 2.0."; + } + + if ( %shaderVer < 3.0 || %intel ) + { + // Allow specular and normals for 2.0a and 2.0b + if ( %shaderVer > 2.0 ) + { + MeshQualityGroup-->Lowest.apply(); + TextureQualityGroup-->Lowest.apply(); + LightingQualityGroup-->Lowest.apply(); + ShaderQualityGroup-->Low.apply(); + } + else + { + MeshQualityGroup-->Lowest.apply(); + TextureQualityGroup-->Lowest.apply(); + LightingQualityGroup-->Lowest.apply(); + ShaderQualityGroup-->Lowest.apply(); + } + } + else + { + if ( %videoMem > 1000 ) + { + MeshQualityGroup-->High.apply(); + TextureQualityGroup-->High.apply(); + LightingQualityGroup-->High.apply(); + ShaderQualityGroup-->High.apply(); + } + else if ( %videoMem > 400 || %videoMem == 0 ) + { + MeshQualityGroup-->Normal.apply(); + TextureQualityGroup-->Normal.apply(); + LightingQualityGroup-->Normal.apply(); + ShaderQualityGroup-->Normal.apply(); + + if ( %videoMem == 0 ) + return "Torque was unable to detect available video memory. Applying 'Normal' quality."; + } + else + { + MeshQualityGroup-->Low.apply(); + TextureQualityGroup-->Low.apply(); + LightingQualityGroup-->Low.apply(); + ShaderQualityGroup-->Low.apply(); + } + } + + return "Graphics quality settings have been auto detected."; +} \ No newline at end of file diff --git a/Templates/Empty/game/core/scripts/client/devHelpers.cs b/Templates/Empty/game/core/scripts/client/devHelpers.cs new file mode 100644 index 000000000..6af00d21c --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/devHelpers.cs @@ -0,0 +1,43 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +/// Shortcut for typing dbgSetParameters with the default values torsion uses. +function dbgTorsion() +{ + dbgSetParameters( 6060, "password", false ); +} + +/// Reset the input state to a default of all-keys-up. +/// A helpful remedy for when Torque misses a button up event do to your breakpoints +/// and can't stop shooting / jumping / strafing. +function mvReset() +{ + for ( %i = 0; %i < 6; %i++ ) + setVariable( "mvTriggerCount" @ %i, 0 ); + + $mvUpAction = 0; + $mvDownAction = 0; + $mvLeftAction = 0; + $mvRightAction = 0; + + // There are others. +} \ No newline at end of file diff --git a/Templates/Empty/game/core/scripts/client/helperfuncs.cs b/Templates/Empty/game/core/scripts/client/helperfuncs.cs new file mode 100644 index 000000000..785ab2577 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/helperfuncs.cs @@ -0,0 +1,278 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function validateDatablockName(%name) +{ + // remove whitespaces at beginning and end + %name = trim( %name ); + + // remove numbers at the beginning + %numbers = "0123456789"; + while( strlen(%name) > 0 ) + { + // the first character + %firstChar = getSubStr( %name, 0, 1 ); + // if the character is a number remove it + if( strpos( %numbers, %firstChar ) != -1 ) + { + %name = getSubStr( %name, 1, strlen(%name) -1 ); + %name = ltrim( %name ); + } + else + break; + } + + // replace whitespaces with underscores + %name = strreplace( %name, " ", "_" ); + + // remove any other invalid characters + %invalidCharacters = "-+*/%$&§=()[].?\"#,;!~<>|°^{}"; + %name = stripChars( %name, %invalidCharacters ); + + if( %name $= "" ) + %name = "Unnamed"; + + return %name; +} + +//-------------------------------------------------------------------------- +// Finds location of %word in %text, starting at %start. Works just like strPos +//-------------------------------------------------------------------------- + +function wordPos(%text, %word, %start) +{ + if (%start $= "") %start = 0; + + if (strpos(%text, %word, 0) == -1) return -1; + %count = getWordCount(%text); + if (%start >= %count) return -1; + for (%i = %start; %i < %count; %i++) + { + if (getWord( %text, %i) $= %word) return %i; + } + return -1; +} + +//-------------------------------------------------------------------------- +// Finds location of %field in %text, starting at %start. Works just like strPos +//-------------------------------------------------------------------------- + +function fieldPos(%text, %field, %start) +{ + if (%start $= "") %start = 0; + + if (strpos(%text, %field, 0) == -1) return -1; + %count = getFieldCount(%text); + if (%start >= %count) return -1; + for (%i = %start; %i < %count; %i++) + { + if (getField( %text, %i) $= %field) return %i; + } + return -1; +} + +//-------------------------------------------------------------------------- +// returns the text in a file with "\n" at the end of each line +//-------------------------------------------------------------------------- + +function loadFileText( %file) +{ + %fo = new FileObject(); + %fo.openForRead(%file); + %text = ""; + while(!%fo.isEOF()) + { + %text = %text @ %fo.readLine(); + if (!%fo.isEOF()) %text = %text @ "\n"; + } + + %fo.delete(); + return %text; +} + +function setValueSafe(%dest, %val) +{ + %cmd = %dest.command; + %alt = %dest.altCommand; + %dest.command = ""; + %dest.altCommand = ""; + + %dest.setValue(%val); + + %dest.command = %cmd; + %dest.altCommand = %alt; +} + +function shareValueSafe(%source, %dest) +{ + setValueSafe(%dest, %source.getValue()); +} + +function shareValueSafeDelay(%source, %dest, %delayMs) +{ + schedule(%delayMs, 0, shareValueSafe, %source, %dest); +} + + +//------------------------------------------------------------------------------ +// An Aggregate Control is a plain GuiControl that contains other controls, +// which all share a single job or represent a single value. +//------------------------------------------------------------------------------ + +// AggregateControl.setValue( ) propagates the value to any control that has an +// internal name. +function AggregateControl::setValue(%this, %val, %child) +{ + for(%i = 0; %i < %this.getCount(); %i++) + { + %obj = %this.getObject(%i); + if( %obj == %child ) + continue; + + if(%obj.internalName !$= "") + setValueSafe(%obj, %val); + } +} + +// AggregateControl.getValue() uses the value of the first control that has an +// internal name, if it has not cached a value via .setValue +function AggregateControl::getValue(%this) +{ + for(%i = 0; %i < %this.getCount(); %i++) + { + %obj = %this.getObject(%i); + if(%obj.internalName !$= "") + { + //error("obj = " @ %obj.getId() @ ", " @ %obj.getName() @ ", " @ %obj.internalName ); + //error(" value = " @ %obj.getValue()); + return %obj.getValue(); + } + } +} + +// AggregateControl.updateFromChild( ) is called by child controls to propagate +// a new value, and to trigger the onAction() callback. +function AggregateControl::updateFromChild(%this, %child) +{ + %val = %child.getValue(); + if(%val == mCeil(%val)){ + %val = mCeil(%val); + }else{ + if ( %val <= -100){ + %val = mCeil(%val); + }else if ( %val <= -10){ + %val = mFloatLength(%val, 1); + }else if ( %val < 0){ + %val = mFloatLength(%val, 2); + }else if ( %val >= 1000){ + %val = mCeil(%val); + }else if ( %val >= 100){ + %val = mFloatLength(%val, 1); + }else if ( %val >= 10){ + %val = mFloatLength(%val, 2); + }else if ( %val > 0){ + %val = mFloatLength(%val, 3); + } + } + %this.setValue(%val, %child); + %this.onAction(); +} + +// default onAction stub, here only to prevent console spam warnings. +function AggregateControl::onAction(%this) +{ +} + +// call a method on all children that have an internalName and that implement the method. +function AggregateControl::callMethod(%this, %method, %args) +{ + for(%i = 0; %i < %this.getCount(); %i++) + { + %obj = %this.getObject(%i); + if(%obj.internalName !$= "" && %obj.isMethod(%method)) + eval(%obj @ "." @ %method @ "( " @ %args @ " );"); + } + +} + +// A function used in order to easily parse the MissionGroup for classes . I'm pretty +// sure at this point the function can be easily modified to search the any group as well. +function parseMissionGroup( %className, %childGroup ) +{ + if( getWordCount( %childGroup ) == 0) + %currentGroup = "MissionGroup"; + else + %currentGroup = %childGroup; + + for(%i = 0; %i < (%currentGroup).getCount(); %i++) + { + if( (%currentGroup).getObject(%i).getClassName() $= %className ) + return true; + + if( (%currentGroup).getObject(%i).getClassName() $= "SimGroup" ) + { + if( parseMissionGroup( %className, (%currentGroup).getObject(%i).getId() ) ) + return true; + } + } +} + +// A variation of the above used to grab ids from the mission group based on classnames +function parseMissionGroupForIds( %className, %childGroup ) +{ + if( getWordCount( %childGroup ) == 0) + %currentGroup = "MissionGroup"; + else + %currentGroup = %childGroup; + + for(%i = 0; %i < (%currentGroup).getCount(); %i++) + { + if( (%currentGroup).getObject(%i).getClassName() $= %className ) + %classIds = %classIds @ (%currentGroup).getObject(%i).getId() @ " "; + + if( (%currentGroup).getObject(%i).getClassName() $= "SimGroup" ) + %classIds = %classIds @ parseMissionGroupForIds( %className, (%currentGroup).getObject(%i).getId()); + } + return %classIds; +} + +//------------------------------------------------------------------------------ +// Altered Version of TGB's QuickEditDropDownTextEditCtrl +//------------------------------------------------------------------------------ + +function QuickEditDropDownTextEditCtrl::onRenameItem( %this ) +{ +} + +function QuickEditDropDownTextEditCtrl::updateFromChild( %this, %ctrl ) +{ + if( %ctrl.internalName $= "PopUpMenu" ) + { + %this->TextEdit.setText( %ctrl.getText() ); + } + else if ( %ctrl.internalName $= "TextEdit" ) + { + %popup = %this->PopupMenu; + %popup.changeTextById( %popup.getSelected(), %ctrl.getText() ); + %this.onRenameItem(); + } +} diff --git a/Templates/Empty/game/core/scripts/client/imposter.cs b/Templates/Empty/game/core/scripts/client/imposter.cs new file mode 100644 index 000000000..08ebf6866 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/imposter.cs @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +function imposterMetricsCallback() +{ + return " | IMPOSTER |" @ + " Rendered: " @ $ImposterStats::rendered @ + " Batches: " @ $ImposterStats::batches @ + " DrawCalls: " @ $ImposterStats::drawCalls @ + " Polys: " @ $ImposterStats::polyCount @ + " RtChanges: " @ $ImposterStats::rtChanges; +} \ No newline at end of file diff --git a/Templates/Empty/game/core/scripts/client/lighting.cs b/Templates/Empty/game/core/scripts/client/lighting.cs new file mode 100644 index 000000000..231b44d17 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/lighting.cs @@ -0,0 +1,98 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +//--------------------------------------------------------------------------------------------- + +function initLightingSystems() +{ + echo( "\n--------- Initializing Lighting Systems ---------" ); + + // First exec the scripts for the different light managers + // in the lighting folder. + + %pattern = "./lighting/*/init.cs"; + %file = findFirstFile( %pattern ); + if ( %file $= "" ) + { + // Try for DSOs next. + %pattern = "./lighting/*/init.cs.dso"; + %file = findFirstFile( %pattern ); + } + + while( %file !$= "" ) + { + exec( %file ); + %file = findNextFile( %pattern ); + } + + // Try the perfered one first. + %success = setLightManager( $pref::lightManager ); + if ( !%success ) + { + // The perfered one fell thru... so go thru the default + // light managers until we find one that works. + %lmCount = getFieldCount( $lightManager::defaults ); + for ( %i = 0; %i < %lmCount; %i++ ) + { + %lmName = getField( $lightManager::defaults, %i ); + %success = setLightManager( %lmName ); + if ( %success ) + break; + } + } + + // Did we completely fail to initialize a light manager? + if ( !%success ) + { + // If we completely failed to initialize a light + // manager then the 3d scene cannot be rendered. + quitWithErrorMessage( "Failed to set a light manager!" ); + } + + echo( "\n" ); +} + +//--------------------------------------------------------------------------------------------- + +function onLightManagerActivate( %lmName ) +{ + $pref::lightManager = %lmName; + echo( "Using " @ $pref::lightManager ); + + // Call activation callbacks. + + %activateNewFn = "onActivate" @ getWord( %lmName, 0 ) @ "LM"; + if( isFunction( %activateNewFn ) ) + eval( %activateNewFn @ "();" ); +} + +//--------------------------------------------------------------------------------------------- + +function onLightManagerDeactivate( %lmName ) +{ + // Call deactivation callback. + + %deactivateOldFn = "onDeactivate" @ getWord( %lmName, 0 ) @ "LM"; + if( isFunction( %deactivateOldFn ) ) + eval( %deactivateOldFn @ "();" ); +} diff --git a/Templates/Empty/game/core/scripts/client/lighting/advanced/depthviz.png b/Templates/Empty/game/core/scripts/client/lighting/advanced/depthviz.png new file mode 100644 index 000000000..12991ed5c Binary files /dev/null and b/Templates/Empty/game/core/scripts/client/lighting/advanced/depthviz.png differ diff --git a/Templates/Empty/game/core/scripts/client/lighting/advanced/init.cs b/Templates/Empty/game/core/scripts/client/lighting/advanced/init.cs new file mode 100644 index 000000000..2c78e9ca4 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/lighting/advanced/init.cs @@ -0,0 +1,73 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +/////////////////////////////////////////////////////////////////////////////// +// Default Prefs + +/* +$pref::LightManager::sgAtlasMaxDynamicLights = "16"; +$pref::LightManager::sgDynamicShadowDetailSize = "0"; +$pref::LightManager::sgDynamicShadowQuality = "0"; +$pref::LightManager::sgLightingProfileAllowShadows = "1"; +$pref::LightManager::sgLightingProfileQuality = "0"; +$pref::LightManager::sgMaxBestLights = "10"; +$pref::LightManager::sgMultipleDynamicShadows = "1"; +$pref::LightManager::sgShowCacheStats = "0"; +$pref::LightManager::sgUseBloom = ""; +$pref::LightManager::sgUseDRLHighDynamicRange = "0"; +$pref::LightManager::sgUseDynamicRangeLighting = "0"; +$pref::LightManager::sgUseDynamicShadows = "1"; +$pref::LightManager::sgUseToneMapping = ""; +*/ + +exec( "./shaders.cs" ); +exec( "./lightViz.cs" ); +exec( "./shadowViz.cs" ); +exec( "./shadowViz.gui" ); + +function onActivateAdvancedLM() +{ + // Don't allow the offscreen target on OSX. + if ( $platform $= "macos" ) + return; + + // On the Xbox360 we know what will be enabled so don't do any trickery to + // disable MSAA + if ( $platform $= "xenon" ) + return; + + // Enable the offscreen target so that AL will work + // with MSAA back buffers and for HDR rendering. + AL_FormatToken.enable(); +} + +function onDeactivateAdvancedLM() +{ + // Disable the offscreen render target. + AL_FormatToken.disable(); +} + +function setAdvancedLighting() +{ + setLightManager( "Advanced Lighting" ); +} + diff --git a/Templates/Empty/game/core/scripts/client/lighting/advanced/lightViz.cs b/Templates/Empty/game/core/scripts/client/lighting/advanced/lightViz.cs new file mode 100644 index 000000000..9cb797bb9 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/lighting/advanced/lightViz.cs @@ -0,0 +1,248 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +new GFXStateBlockData( AL_DepthVisualizeState ) +{ + zDefined = true; + zEnable = false; + zWriteEnable = false; + + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; // depth + samplerStates[1] = SamplerClampLinear; // viz color lookup +}; + +new GFXStateBlockData( AL_DefaultVisualizeState ) +{ + blendDefined = true; + blendEnable = true; + blendSrc = GFXBlendSrcAlpha; + blendDest = GFXBlendInvSrcAlpha; + + zDefined = true; + zEnable = false; + zWriteEnable = false; + + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; // #prepass + samplerStates[1] = SamplerClampLinear; // depthviz +}; + +new ShaderData( AL_DepthVisualizeShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/lighting/advanced/dbgDepthVisualizeP.hlsl"; + + OGLVertexShaderFile = "shaders/common/postFx/postFxV.glsl"; + OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/dbgDepthVisualizeP.glsl"; + + samplerNames[0] = "prepassBuffer"; + samplerNames[1] = "depthViz"; + + pixVersion = 2.0; +}; + +singleton PostEffect( AL_DepthVisualize ) +{ + shader = AL_DepthVisualizeShader; + stateBlock = AL_DefaultVisualizeState; + texture[0] = "#prepass"; + texture[1] = "depthviz"; + target = "$backBuffer"; + renderPriority = 9999; +}; + +function AL_DepthVisualize::onEnabled( %this ) +{ + AL_NormalsVisualize.disable(); + AL_LightColorVisualize.disable(); + AL_LightSpecularVisualize.disable(); + $AL_NormalsVisualizeVar = false; + $AL_LightColorVisualizeVar = false; + $AL_LightSpecularVisualizeVar = false; + + return true; +} + + +new ShaderData( AL_NormalsVisualizeShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/lighting/advanced/dbgNormalVisualizeP.hlsl"; + + OGLVertexShaderFile = "shaders/common/postFx/postFxV.glsl"; + OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/dbgNormalVisualizeP.glsl"; + + samplerNames[0] = "prepassTex"; + + pixVersion = 2.0; +}; + +singleton PostEffect( AL_NormalsVisualize ) +{ + shader = AL_NormalsVisualizeShader; + stateBlock = AL_DefaultVisualizeState; + texture[0] = "#prepass"; + target = "$backBuffer"; + renderPriority = 9999; +}; + +function AL_NormalsVisualize::onEnabled( %this ) +{ + AL_DepthVisualize.disable(); + AL_LightColorVisualize.disable(); + AL_LightSpecularVisualize.disable(); + $AL_DepthVisualizeVar = false; + $AL_LightColorVisualizeVar = false; + $AL_LightSpecularVisualizeVar = false; + + return true; +} + + + +new ShaderData( AL_LightColorVisualizeShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/lighting/advanced/dbgLightColorVisualizeP.hlsl"; + + OGLVertexShaderFile = "shaders/common/postFx/postFxV.glsl"; + OGLPixelShaderFile = "shaders/common/lighting/advanced/dl/dbgLightColorVisualizeP.glsl"; + + samplerNames[0] = "lightInfoBuffer"; + + pixVersion = 2.0; +}; + +singleton PostEffect( AL_LightColorVisualize ) +{ + shader = AL_LightColorVisualizeShader; + stateBlock = AL_DefaultVisualizeState; + texture[0] = "#lightinfo"; + target = "$backBuffer"; + renderPriority = 9999; +}; + +function AL_LightColorVisualize::onEnabled( %this ) +{ + AL_NormalsVisualize.disable(); + AL_DepthVisualize.disable(); + AL_LightSpecularVisualize.disable(); + $AL_NormalsVisualizeVar = false; + $AL_DepthVisualizeVar = false; + $AL_LightSpecularVisualizeVar = false; + + return true; +} + + +new ShaderData( AL_LightSpecularVisualizeShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/lighting/advanced/dbgLightSpecularVisualizeP.hlsl"; + + OGLVertexShaderFile = "shaders/common/postFx/postFxV.glsl"; + OGLPixelShaderFile = "shaders/common/lighting/advanced/dl/dbgLightSpecularVisualizeP.glsl"; + + samplerNames[0] = "lightInfoBuffer"; + + pixVersion = 2.0; +}; + +singleton PostEffect( AL_LightSpecularVisualize ) +{ + shader = AL_LightSpecularVisualizeShader; + stateBlock = AL_DefaultVisualizeState; + texture[0] = "#lightinfo"; + target = "$backBuffer"; + renderPriority = 9999; +}; + +function AL_LightSpecularVisualize::onEnabled( %this ) +{ + AL_NormalsVisualize.disable(); + AL_DepthVisualize.disable(); + AL_LightColorVisualize.disable(); + $AL_NormalsVisualizeVar = false; + $AL_DepthVisualizeVar = false; + $AL_LightColorVisualizeVar = false; + + return true; +} + +/// Toggles the visualization of the AL depth buffer. +function toggleDepthViz( %enable ) +{ + if ( %enable $= "" ) + { + $AL_DepthVisualizeVar = AL_DepthVisualize.isEnabled() ? false : true; + AL_DepthVisualize.toggle(); + } + else if ( %enable ) + AL_DepthVisualize.enable(); + else if ( !%enable ) + AL_DepthVisualize.disable(); +} + +/// Toggles the visualization of the AL normals buffer. +function toggleNormalsViz( %enable ) +{ + if ( %enable $= "" ) + { + $AL_NormalsVisualizeVar = AL_NormalsVisualize.isEnabled() ? false : true; + AL_NormalsVisualize.toggle(); + } + else if ( %enable ) + AL_NormalsVisualize.enable(); + else if ( !%enable ) + AL_NormalsVisualize.disable(); +} + +/// Toggles the visualization of the AL lighting color buffer. +function toggleLightColorViz( %enable ) +{ + if ( %enable $= "" ) + { + $AL_LightColorVisualizeVar = AL_LightColorVisualize.isEnabled() ? false : true; + AL_LightColorVisualize.toggle(); + } + else if ( %enable ) + AL_LightColorVisualize.enable(); + else if ( !%enable ) + AL_LightColorVisualize.disable(); +} + +/// Toggles the visualization of the AL lighting specular power buffer. +function toggleLightSpecularViz( %enable ) +{ + if ( %enable $= "" ) + { + $AL_LightSpecularVisualizeVar = AL_LightSpecularVisualize.isEnabled() ? false : true; + AL_LightSpecularVisualize.toggle(); + } + else if ( %enable ) + AL_LightSpecularVisualize.enable(); + else if ( !%enable ) + AL_LightSpecularVisualize.disable(); +} + diff --git a/Templates/Empty/game/core/scripts/client/lighting/advanced/shaders.cs b/Templates/Empty/game/core/scripts/client/lighting/advanced/shaders.cs new file mode 100644 index 000000000..fef6c5652 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/lighting/advanced/shaders.cs @@ -0,0 +1,226 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +// Vector Light State +new GFXStateBlockData( AL_VectorLightState ) +{ + blendDefined = true; + blendEnable = true; + blendSrc = GFXBlendOne; + blendDest = GFXBlendOne; + blendOp = GFXBlendOpAdd; + + zDefined = true; + zEnable = false; + zWriteEnable = false; + + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; // G-buffer + samplerStates[1] = SamplerClampPoint; // Shadow Map (Do not change this to linear, as all cards can not filter equally.) + samplerStates[2] = SamplerClampLinear; // SSAO Mask + samplerStates[3] = SamplerWrapPoint; // Random Direction Map + + cullDefined = true; + cullMode = GFXCullNone; + + stencilDefined = true; + stencilEnable = true; + stencilFailOp = GFXStencilOpKeep; + stencilZFailOp = GFXStencilOpKeep; + stencilPassOp = GFXStencilOpKeep; + stencilFunc = GFXCmpLess; + stencilRef = 0; +}; + +// Vector Light Material +new ShaderData( AL_VectorLightShader ) +{ + DXVertexShaderFile = "shaders/common/lighting/advanced/farFrustumQuadV.hlsl"; + DXPixelShaderFile = "shaders/common/lighting/advanced/vectorLightP.hlsl"; + + OGLVertexShaderFile = "shaders/common/lighting/advanced/gl/farFrustumQuadV.glsl"; + OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/vectorLightP.glsl"; + + pixVersion = 3.0; +}; + +new CustomMaterial( AL_VectorLightMaterial ) +{ + shader = AL_VectorLightShader; + stateBlock = AL_VectorLightState; + + sampler["prePassBuffer"] = "#prepass"; + sampler["ShadowMap"] = "$dynamiclight"; + sampler["ssaoMask"] = "#ssaoMask"; + + target = "lightinfo"; + + pixVersion = 3.0; +}; + +//------------------------------------------------------------------------------ + +// Convex-geometry light states +new GFXStateBlockData( AL_ConvexLightState ) +{ + blendDefined = true; + blendEnable = true; + blendSrc = GFXBlendOne; + blendDest = GFXBlendOne; + blendOp = GFXBlendOpAdd; + + zDefined = true; + zEnable = true; + zWriteEnable = false; + zFunc = GFXCmpGreaterEqual; + + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; // G-buffer + samplerStates[1] = SamplerClampPoint; // Shadow Map (Do not use linear, these are perspective projections) + samplerStates[2] = SamplerClampLinear; // Cookie Map + samplerStates[3] = SamplerWrapPoint; // Random Direction Map + + cullDefined = true; + cullMode = GFXCullCW; + + stencilDefined = true; + stencilEnable = true; + stencilFailOp = GFXStencilOpKeep; + stencilZFailOp = GFXStencilOpKeep; + stencilPassOp = GFXStencilOpKeep; + stencilFunc = GFXCmpLess; + stencilRef = 0; +}; + +// Point Light Material +new ShaderData( AL_PointLightShader ) +{ + DXVertexShaderFile = "shaders/common/lighting/advanced/convexGeometryV.hlsl"; + DXPixelShaderFile = "shaders/common/lighting/advanced/pointLightP.hlsl"; + + OGLVertexShaderFile = "shaders/common/lighting/advanced/gl/convexGeometryV.glsl"; + OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/pointLightP.glsl"; + + pixVersion = 3.0; +}; + +new CustomMaterial( AL_PointLightMaterial ) +{ + shader = AL_PointLightShader; + stateBlock = AL_ConvexLightState; + + sampler["prePassBuffer"] = "#prepass"; + sampler["shadowMap"] = "$dynamiclight"; + sampler["cookieTex"] = "$dynamiclightmask"; + + target = "lightinfo"; + + pixVersion = 3.0; +}; + +// Spot Light Material +new ShaderData( AL_SpotLightShader ) +{ + DXVertexShaderFile = "shaders/common/lighting/advanced/convexGeometryV.hlsl"; + DXPixelShaderFile = "shaders/common/lighting/advanced/spotLightP.hlsl"; + + OGLVertexShaderFile = "shaders/common/lighting/advanced/gl/convexGeometryV.glsl"; + OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/spotLightP.glsl"; + + pixVersion = 3.0; +}; + +new CustomMaterial( AL_SpotLightMaterial ) +{ + shader = AL_SpotLightShader; + stateBlock = AL_ConvexLightState; + + sampler["prePassBuffer"] = "#prepass"; + sampler["shadowMap"] = "$dynamiclight"; + sampler["cookieTex"] = "$dynamiclightmask"; + + target = "lightinfo"; + + pixVersion = 3.0; +}; + +/// This material is used for generating prepass +/// materials for objects that do not have materials. +new Material( AL_DefaultPrePassMaterial ) +{ + // We need something in the first pass else it + // won't create a proper material instance. + // + // We use color here because some objects may not + // have texture coords in their vertex format... + // for example like terrain. + // + diffuseColor[0] = "1 1 1 1"; +}; + +/// This material is used for generating shadow +/// materials for objects that do not have materials. +new Material( AL_DefaultShadowMaterial ) +{ + // We need something in the first pass else it + // won't create a proper material instance. + // + // We use color here because some objects may not + // have texture coords in their vertex format... + // for example like terrain. + // + diffuseColor[0] = "1 1 1 1"; + + // This is here mostly for terrain which uses + // this material to create its shadow material. + // + // At sunset/sunrise the sun is looking thru + // backsides of the terrain which often are not + // closed. By changing the material to be double + // sided we avoid holes in the shadowed geometry. + // + doubleSided = true; +}; + +// Particle System Point Light Material +new ShaderData( AL_ParticlePointLightShader ) +{ + DXVertexShaderFile = "shaders/common/lighting/advanced/particlePointLightV.hlsl"; + DXPixelShaderFile = "shaders/common/lighting/advanced/particlePointLightP.hlsl"; + + OGLVertexShaderFile = "shaders/common/lighting/advanced/gl/convexGeometryV.glsl"; + OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/pointLightP.glsl"; + + pixVersion = 3.0; +}; + +new CustomMaterial( AL_ParticlePointLightMaterial ) +{ + shader = AL_ParticlePointLightShader; + stateBlock = AL_ConvexLightState; + + sampler["prePassBuffer"] = "#prepass"; + target = "lightinfo"; + + pixVersion = 3.0; +}; diff --git a/Templates/Empty/game/core/scripts/client/lighting/advanced/shadowViz.cs b/Templates/Empty/game/core/scripts/client/lighting/advanced/shadowViz.cs new file mode 100644 index 000000000..88b2d7f4a --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/lighting/advanced/shadowViz.cs @@ -0,0 +1,113 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +new ShaderData( AL_ShadowVisualizeShader ) +{ + DXVertexShaderFile = "shaders/common/guiMaterialV.hlsl"; + DXPixelShaderFile = "shaders/common/lighting/advanced/dbgShadowVisualizeP.hlsl"; + + OGLVertexShaderFile = "shaders/common/gl/guiMaterialV.glsl"; + OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/dbgShadowVisualizeP.glsl"; + + pixVersion = 2.0; +}; + +new CustomMaterial( AL_ShadowVisualizeMaterial ) +{ + shader = AL_ShadowVisualizeShader; + stateBlock = AL_DepthVisualizeState; + + sampler["shadowMap"] = "#AL_ShadowVizTexture"; + sampler["depthViz"] = "depthviz"; + + pixVersion = 2.0; +}; + +singleton GuiControlProfile( AL_ShadowLabelTextProfile ) +{ + fontColor = "0 0 0"; + autoSizeWidth = true; + autoSizeHeight = true; + justify = "left"; + fontSize = 14; +}; + +/// Toggles the visualization of the pre-pass lighting buffer. +function toggleShadowViz() +{ + if ( AL_ShadowVizOverlayCtrl.isAwake() ) + { + setShadowVizLight( 0 ); + Canvas.popDialog( AL_ShadowVizOverlayCtrl ); + } + else + { + Canvas.pushDialog( AL_ShadowVizOverlayCtrl, 100 ); + _setShadowVizLight( EWorldEditor.getSelectedObject( 0 ) ); + } +} + +/// Called from the WorldEditor when an object is selected. +function _setShadowVizLight( %light, %force ) +{ + if ( !AL_ShadowVizOverlayCtrl.isAwake() ) + return; + + if ( AL_ShadowVizOverlayCtrl.isLocked && !%force ) + return; + + // Resolve the object to the client side. + if ( isObject( %light ) ) + { + %clientLight = serverToClientObject( %light ); + %sizeAndAspect = setShadowVizLight( %clientLight ); + } + + AL_ShadowVizOverlayCtrl-->MatCtrl.setMaterial( "AL_ShadowVisualizeMaterial" ); + + %text = "ShadowViz"; + if ( isObject( %light ) ) + %text = %text @ " : " @ getWord( %sizeAndAspect, 0 ) @ " x " @ getWord( %sizeAndAspect, 1 ); + + AL_ShadowVizOverlayCtrl-->WindowCtrl.text = %text; +} + +/// For convenience, push the viz dialog and set the light manually from the console. +function showShadowVizForLight( %light ) +{ + if ( !AL_ShadowVizOverlayCtrl.isAwake() ) + Canvas.pushDialog( AL_ShadowVizOverlayCtrl, 100 ); + _setShadowVizLight( %light, true ); +} + +// Prevent shadowViz from changing lights in response to editor selection +// events until unlock is called. The only way a vis light will change while locked +// is if showShadowVizForLight is explicitly called by the user. +function lockShadowViz() +{ + AL_ShadowVizOverlayCtrl.islocked = true; +} + +function unlockShadowViz() +{ + AL_ShadowVizOverlayCtrl.islocked = false; +} \ No newline at end of file diff --git a/Templates/Empty/game/core/scripts/client/lighting/advanced/shadowViz.gui b/Templates/Empty/game/core/scripts/client/lighting/advanced/shadowViz.gui new file mode 100644 index 000000000..05c1a8926 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/lighting/advanced/shadowViz.gui @@ -0,0 +1,78 @@ +//--------------------------------------------------------------------------------------------- +// Torque 3D +// Copyright (C) GarageGames.com, Inc. +//--------------------------------------------------------------------------------------------- + +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AL_ShadowVizOverlayCtrl) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiModelessDialogProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + noCursor = true; + + new GuiWindowCtrl() { + internalName = "WindowCtrl"; + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "50 50"; + Extent = "347 209"; + MinExtent = "150 100"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "1"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "ShadowViz"; + closeCommand = "toggleShadowViz();"; + + new GuiMaterialCtrl() { + internalName = "MatCtrl"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "3 23"; + Extent = "341 181"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "2 2 2 2"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + materialName = "AL_ShadowVisualizeMaterial"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/core/scripts/client/lighting/basic/init.cs b/Templates/Empty/game/core/scripts/client/lighting/basic/init.cs new file mode 100644 index 000000000..fd77adb8b --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/lighting/basic/init.cs @@ -0,0 +1,90 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +exec( "./shadowFilter.cs" ); + +singleton GFXStateBlockData( BL_ProjectedShadowSBData ) +{ + blendDefined = true; + blendEnable = true; + blendSrc = GFXBlendDestColor; + blendDest = GFXBlendZero; + + zDefined = true; + zEnable = true; + zWriteEnable = false; + + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; + vertexColorEnable = true; +}; + +singleton ShaderData( BL_ProjectedShadowShaderData ) +{ + DXVertexShaderFile = "shaders/common/projectedShadowV.hlsl"; + DXPixelShaderFile = "shaders/common/projectedShadowP.hlsl"; + + OGLVertexShaderFile = "shaders/common/gl/projectedShadowV.glsl"; + OGLPixelShaderFile = "shaders/common/gl/projectedShadowP.glsl"; + + pixVersion = 2.0; +}; + +singleton CustomMaterial( BL_ProjectedShadowMaterial ) +{ + sampler["inputTex"] = "$miscbuff"; + + shader = BL_ProjectedShadowShaderData; + stateBlock = BL_ProjectedShadowSBData; + version = 2.0; + forwardLit = true; +}; + +function onActivateBasicLM() +{ + // If HDR is enabled... enable the special format token. + if ( $platform !$= "macos" && HDRPostFx.isEnabled ) + AL_FormatToken.enable(); + + // Create render pass for projected shadow. + new RenderPassManager( BL_ProjectedShadowRPM ); + + // Create the mesh bin and add it to the manager. + %meshBin = new RenderMeshMgr(); + BL_ProjectedShadowRPM.addManager( %meshBin ); + + // Add both to the root group so that it doesn't + // end up in the MissionCleanup instant group. + RootGroup.add( BL_ProjectedShadowRPM ); + RootGroup.add( %meshBin ); +} + +function onDeactivateBasicLM() +{ + // Delete the pass manager which also deletes the bin. + BL_ProjectedShadowRPM.delete(); +} + +function setBasicLighting() +{ + setLightManager( "Basic Lighting" ); +} diff --git a/Templates/Empty/game/core/scripts/client/lighting/basic/shadowFilter.cs b/Templates/Empty/game/core/scripts/client/lighting/basic/shadowFilter.cs new file mode 100644 index 000000000..30a6db6d6 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/lighting/basic/shadowFilter.cs @@ -0,0 +1,76 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +singleton ShaderData( BL_ShadowFilterShaderV ) +{ + DXVertexShaderFile = "shaders/common/lighting/basic/shadowFilterV.hlsl"; + DXPixelShaderFile = "shaders/common/lighting/basic/shadowFilterP.hlsl"; + + OGLVertexShaderFile = "shaders/common/lighting/basic/gl/shadowFilterV.glsl"; + OGLPixelShaderFile = "shaders/common/lighting/basic/gl/shadowFilterP.glsl"; + + samplerNames[0] = "$diffuseMap"; + + defines = "BLUR_DIR=float2(1.0,0.0)"; + + pixVersion = 2.0; +}; + +singleton ShaderData( BL_ShadowFilterShaderH : BL_ShadowFilterShaderV ) +{ + defines = "BLUR_DIR=float2(0.0,1.0)"; +}; + + +singleton GFXStateBlockData( BL_ShadowFilterSB : PFX_DefaultStateBlock ) +{ + colorWriteDefined=true; + colorWriteRed=false; + colorWriteGreen=false; + colorWriteBlue=false; + blendDefined = true; + blendEnable = true; +}; + +// NOTE: This is ONLY used in Basic Lighting, and +// only directly by the ProjectedShadow. It is not +// meant to be manually enabled like other PostEffects. +singleton PostEffect( BL_ShadowFilterPostFx ) +{ + // Blur vertically + shader = BL_ShadowFilterShaderV; + stateBlock = PFX_DefaultStateBlock; + targetClear = "PFXTargetClear_OnDraw"; + targetClearColor = "0 0 0 0"; + texture[0] = "$inTex"; + target = "$outTex"; + + // Blur horizontal + new PostEffect() + { + shader = BL_ShadowFilterShaderH; + stateBlock = PFX_DefaultStateBlock; + texture[0] = "$inTex"; + target = "$outTex"; + }; +}; diff --git a/Templates/Empty/game/core/scripts/client/lighting/shadowMaps/init.cs b/Templates/Empty/game/core/scripts/client/lighting/shadowMaps/init.cs new file mode 100644 index 000000000..b815ac265 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/lighting/shadowMaps/init.cs @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +new ShaderData(BlurDepthShader) +{ + DXVertexShaderFile = "shaders/common/lighting/shadowMap/boxFilterV.hlsl"; + DXPixelShaderFile = "shaders/common/lighting/shadowMap/boxFilterP.hlsl"; + + OGLVertexShaderFile = "shaders/common/lighting/shadowMap/gl/boxFilterV.glsl"; + OGLPixelShaderFile = "shaders/common/lighting/shadowMap/gl/boxFilterP.glsl"; + pixVersion = 2.0; +}; diff --git a/Templates/Empty/game/core/scripts/client/materials.cs b/Templates/Empty/game/core/scripts/client/materials.cs new file mode 100644 index 000000000..ea47690c2 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/materials.cs @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +singleton Material( WarningMaterial ) +{ + diffuseMap[0] = "~/art/warnMat"; + emissive[0] = false; + translucent = false; +}; + + +singleton CubemapData( WarnMatCubeMap ) +{ + cubeFace[0] = "~/art/warnMat"; + cubeFace[1] = "~/art/warnMat"; + cubeFace[2] = "~/art/warnMat"; + cubeFace[3] = "~/art/warnMat"; + cubeFace[4] = "~/art/warnMat"; + cubeFace[5] = "~/art/warnMat"; +}; diff --git a/Templates/Empty/game/core/scripts/client/message.cs b/Templates/Empty/game/core/scripts/client/message.cs new file mode 100644 index 000000000..2dbb3c949 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/message.cs @@ -0,0 +1,109 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +// Functions that process commands sent from the server. + + +// This function is for chat messages only; it is invoked on the client when +// the server does a commandToClient with the tag ChatMessage. (Cf. the +// functions chatMessage* in core/scripts/server/message.cs.) + +// This just invokes onChatMessage, which the mod code must define. + +function clientCmdChatMessage(%sender, %voice, %pitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10) +{ + onChatMessage(detag(%msgString), %voice, %pitch); +} + + +// Game event descriptions, which may or may not include text messages, can be +// sent using the message* functions in core/scripts/server/message.cs. Those +// functions do commandToClient with the tag ServerMessage, which invokes the +// function below. + +// For ServerMessage messages, the client can install callbacks that will be +// run, according to the "type" of the message. + +function clientCmdServerMessage(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10) +{ + // Get the message type; terminates at any whitespace. + %tag = getWord(%msgType, 0); + + // First see if there is a callback installed that doesn't have a type; + // if so, that callback is always executed when a message arrives. + for (%i = 0; (%func = $MSGCB["", %i]) !$= ""; %i++) { + call(%func, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10); + } + + // Next look for a callback for this particular type of ServerMessage. + if (%tag !$= "") { + for (%i = 0; (%func = $MSGCB[%tag, %i]) !$= ""; %i++) { + call(%func, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10); + } + } +} + +// Called by the client to install a callback for a particular type of +// ServerMessage. +function addMessageCallback(%msgType, %func) +{ + for (%i = 0; (%afunc = $MSGCB[%msgType, %i]) !$= ""; %i++) { + // If it already exists as a callback for this type, + // nothing to do. + if (%afunc $= %func) { + return; + } + } + // Set it up. + $MSGCB[%msgType, %i] = %func; +} + + + +// The following is the callback that will be executed for every ServerMessage, +// because we're going to install it without a specified type. Any type- +// specific callbacks will be executed afterward. + +// This just invokes onServerMessage, which can be overridden by the game +function onServerMessage(%a, %b, %c, %d, %e, %f, %g, %h, %i) +{ + echo("onServerMessage: "); + if(%a !$= "") echo(" +- a: " @ %a); + if(%b !$= "") echo(" +- b: " @ %b); + if(%c !$= "") echo(" +- c: " @ %c); + if(%d !$= "") echo(" +- d: " @ %d); + if(%e !$= "") echo(" +- e: " @ %e); + if(%f !$= "") echo(" +- f: " @ %f); + if(%g !$= "") echo(" +- g: " @ %g); + if(%h !$= "") echo(" +- h: " @ %h); + if(%i !$= "") echo(" +- i: " @ %i); +} + +function defaultMessageCallback(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10) +{ + onServerMessage(detag(%msgString)); +} + +// Register that default message handler now. +addMessageCallback("", defaultMessageCallback); diff --git a/Templates/Empty/game/core/scripts/client/metrics.cs b/Templates/Empty/game/core/scripts/client/metrics.cs new file mode 100644 index 000000000..75f8c8972 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/metrics.cs @@ -0,0 +1,253 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// load gui used to display various metric outputs +exec("~/art/gui/FrameOverlayGui.gui"); + +// Note: To implement your own metrics overlay +// just add a function with a name in the form +// XXXXMetricsCallback which can be enabled via +// metrics( XXXX ) + +function fpsMetricsCallback() +{ + return " | FPS |" @ + " " @ $fps::real @ + " max: " @ $fps::realMax @ + " min: " @ $fps::realMin @ + " mspf: " @ 1000 / $fps::real; +} + +function gfxMetricsCallback() +{ + return " | GFX |" @ + " PolyCount: " @ $GFXDeviceStatistics::polyCount @ + " DrawCalls: " @ $GFXDeviceStatistics::drawCalls @ + " RTChanges: " @ $GFXDeviceStatistics::renderTargetChanges; + +} + +function terrainMetricsCallback() +{ + return " | Terrain |" @ + " Cells: " @ $TerrainBlock::cellsRendered @ + " Override Cells: " @ $TerrainBlock::overrideCells @ + " DrawCalls: " @ $TerrainBlock::drawCalls; +} + +function netMetricsCallback() +{ + return " | Net |" @ + " BitsSent: " @ $Stats::netBitsSent @ + " BitsRcvd: " @ $Stats::netBitsReceived @ + " GhostUpd: " @ $Stats::netGhostUpdates; +} + +function groundCoverMetricsCallback() +{ + return " | GroundCover |" @ + " Cells: " @ $GroundCover::renderedCells @ + " Billboards: " @ $GroundCover::renderedBillboards @ + " Batches: " @ $GroundCover::renderedBatches @ + " Shapes: " @ $GroundCover::renderedShapes; +} + +function forestMetricsCallback() +{ + return " | Forest |" @ + " Cells: " @ $Forest::totalCells @ + " Cells Meshed: " @ $Forest::cellsRendered @ + " Cells Billboarded: " @ $Forest::cellsBatched @ + " Meshes: " @ $Forest::cellItemsRendered @ + " Billboards: " @ $Forest::cellItemsBatched; +} + +function sfxMetricsCallback() +{ + return " | SFX |" @ + " Sounds: " @ $SFX::numSounds @ + " Lists: " @ ( $SFX::numSources - $SFX::numSounds - $SFX::Device::fmodNumEventSource ) @ + " Events: " @ $SFX::fmodNumEventSources @ + " Playing: " @ $SFX::numPlaying @ + " Culled: " @ $SFX::numCulled @ + " Voices: " @ $SFX::numVoices @ + " Buffers: " @ $SFX::Device::numBuffers @ + " Memory: " @ ( $SFX::Device::numBufferBytes / 1024.0 / 1024.0 ) @ " MB" @ + " Time/S: " @ $SFX::sourceUpdateTime @ + " Time/P: " @ $SFX::parameterUpdateTime @ + " Time/A: " @ $SFX::ambientUpdateTime; +} + +function sfxSourcesMetricsCallback() +{ + return sfxDumpSourcesToString(); +} + +function sfxStatesMetricsCallback() +{ + return " | SFXStates |" @ sfxGetActiveStates(); +} + +function timeMetricsCallback() +{ + return " | Time |" @ + " Sim Time: " @ getSimTime() @ + " Mod: " @ getSimTime() % 32; +} + +function reflectMetricsCallback() +{ + return " | REFLECT |" @ + " Objects: " @ $Reflect::numObjects @ + " Visible: " @ $Reflect::numVisible @ + " Occluded: " @ $Reflect::numOccluded @ + " Updated: " @ $Reflect::numUpdated @ + " Elapsed: " @ $Reflect::elapsed NL + + " Allocated: " @ $Reflect::renderTargetsAllocated @ + " Pooled: " @ $Reflect::poolSize NL + + " " @ getWord( $Reflect::textureStats, 1 ) TAB + " " @ getWord( $Reflect::textureStats, 2 ) @ "MB" TAB + " " @ getWord( $Reflect::textureStats, 0 ); +} + +function decalMetricsCallback() +{ + return " | DECAL |" @ + " Batches: " @ $Decal::Batches @ + " Buffers: " @ $Decal::Buffers @ + " DecalsRendered: " @ $Decal::DecalsRendered; +} + +function renderMetricsCallback() +{ + return " | Render |" @ + " Int: " @ $RenderMetrics::RIT_Interior @ + " IntDL: " @ $RenderMetrics::RIT_InteriorDynamicLighting @ + " Mesh: " @ $RenderMetrics::RIT_Mesh @ + " MeshDL: " @ $RenderMetrics::RIT_MeshDynamicLighting @ + " Shadow: " @ $RenderMetrics::RIT_Shadow @ + " Sky: " @ $RenderMetrics::RIT_Sky @ + " Obj: " @ $RenderMetrics::RIT_Object @ + " ObjT: " @ $RenderMetrics::RIT_ObjectTranslucent @ + " Decal: " @ $RenderMetrics::RIT_Decal @ + " Water: " @ $RenderMetrics::RIT_Water @ + " Foliage: " @ $RenderMetrics::RIT_Foliage @ + " Trans: " @ $RenderMetris::RIT_Translucent @ + " Custom: " @ $RenderMetrics::RIT_Custom; +} + +function shadowMetricsCallback() +{ + return " | Shadow |" @ + " Active: " @ $ShadowStats::activeMaps @ + " Updated: " @ $ShadowStats::updatedMaps @ + " PolyCount: " @ $ShadowStats::polyCount @ + " DrawCalls: " @ $ShadowStats::drawCalls @ + " RTChanges: " @ $ShadowStats::rtChanges @ + " PoolTexCount: " @ $ShadowStats::poolTexCount @ + " PoolTexMB: " @ $ShadowStats::poolTexMemory @ "MB"; +} + +function basicShadowMetricsCallback() +{ + return " | Shadow |" @ + " Active: " @ $BasicLightManagerStats::activePlugins @ + " Updated: " @ $BasicLightManagerStats::shadowsUpdated @ + " Elapsed Ms: " @ $BasicLightManagerStats::elapsedUpdateMs; +} + +function lightMetricsCallback() +{ + return " | Deferred Lights |" @ + " Active: " @ $lightMetrics::activeLights @ + " Culled: " @ $lightMetrics::culledLights; +} + +function particleMetricsCallback() +{ + return " | Particles |" @ + " # Simulated " @ $particle::numSimulated; +} +function partMetricsCallback() +{ + return particleMetricsCallback(); +} + + +// alias +function audioMetricsCallback() +{ + return sfxMetricsCallback(); +} + +// alias +function videoMetricsCallback() +{ + return gfxMetricsCallback(); +} + +// Add a metrics HUD. %expr can be a vector of names where each element +// must have a corresponding 'MetricsCallback()' function defined +// that will be called on each update of the GUI control. The results +// of each function are stringed together. +// +// Example: metrics( "fps gfx" ); + +function metrics( %expr ) +{ + %metricsExpr = ""; + if( %expr !$= "" ) + { + for( %i = 0;; %i ++ ) + { + %name = getWord( %expr, %i ); + if( %name $= "" ) + break; + else + { + %cb = %name @ "MetricsCallback"; + if( !isFunction( %cb ) ) + error( "metrics - undefined callback: " @ %cb ); + else + { + %cb = %cb @ "()"; + if( %i > 0 ) + %metricsExpr = %metricsExpr @ " NL "; + %metricsExpr = %metricsExpr @ %cb; + } + } + } + + if( %metricsExpr !$= "" ) + %metricsExpr = %metricsExpr @ " @ \" \""; + } + + if( %metricsExpr !$= "" ) + { + Canvas.pushDialog( FrameOverlayGui, 1000 ); + TextOverlayControl.setValue( %metricsExpr ); + } + else + Canvas.popDialog(FrameOverlayGui); +} diff --git a/Templates/Empty/game/core/scripts/client/mission.cs b/Templates/Empty/game/core/scripts/client/mission.cs new file mode 100644 index 000000000..89b5ef2a7 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/mission.cs @@ -0,0 +1,145 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +// Whether the local client is currently running a mission. +$Client::missionRunning = false; + +// Sequence number for currently running mission. +$Client::missionSeq = -1; + + +// Called when mission is started. +function clientStartMission() +{ + // The client recieves a mission start right before + // being dropped into the game. + physicsStartSimulation( "client" ); + + // Start game audio effects channels. + + AudioChannelEffects.play(); + + // Create client mission cleanup group. + + new SimGroup( ClientMissionCleanup ); + + // Done. + + $Client::missionRunning = true; +} + +// Called when mission is ended (either through disconnect or +// mission end client command). +function clientEndMission() +{ + // Stop physics simulation on client. + physicsStopSimulation( "client" ); + + // Stop game audio effects channels. + + AudioChannelEffects.stop(); + + // Delete all the decals. + decalManagerClear(); + + // Delete client mission cleanup group. + if( isObject( ClientMissionCleanup ) ) + ClientMissionCleanup.delete(); + + clearClientPaths(); + + // Done. + $Client::missionRunning = false; +} + +//---------------------------------------------------------------------------- +// Mission start / end events sent from the server +//---------------------------------------------------------------------------- + +function clientCmdMissionStart(%seq) +{ + clientStartMission(); + $Client::missionSeq = %seq; +} + +function clientCmdMissionEnd( %seq ) +{ + if( $Client::missionRunning && $Client::missionSeq == %seq ) + { + clientEndMission(); + $Client::missionSeq = -1; + } +} + +/// Expands the name of a mission into the full +/// mission path and extension. +function expandMissionFileName( %missionFile ) +{ + // Expand any escapes in it. + %missionFile = expandFilename( %missionFile ); + + // If the mission file doesn't exist... try to fix up the string. + if ( !isFile( %missionFile ) ) + { + // Does it need a .mis? + if ( strStr( %missionFile, ".mis" ) == -1 ) + %newMission = %missionFile @ ".mis"; + + if ( !isFile( %newMission ) ) + { + // Attach a path to it. + %newMission = expandFilename( "levels/" @ %newMission ); + if ( !isFile( %newMission ) ) + { + warn( "The mission file '" @ %missionFile @ "' was not found!" ); + return ""; + } + } + + %missionFile = %newMission; + } + + return %missionFile; +} + +/// Load a single player level on the local server. +function loadLevel( %missionNameOrFile ) +{ + // Expand the mission name... this allows you to enter + // just the name and not the full path and extension. + %missionFile = expandMissionFileName( %missionNameOrFile ); + if ( %missionFile $= "" ) + return false; + + // Show the loading screen immediately. + if ( isObject( LoadingGui ) ) + { + Canvas.setContent("LoadingGui"); + LoadingProgress.setValue(1); + LoadingProgressTxt.setValue("LOADING MISSION FILE"); + Canvas.repaint(); + } + + // Prepare and launch the server. + return createAndConnectToLocalServer( "SinglePlayer", %missionFile ); +} diff --git a/Templates/Empty/game/core/scripts/client/missionDownload.cs b/Templates/Empty/game/core/scripts/client/missionDownload.cs new file mode 100644 index 000000000..78abee79f --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/missionDownload.cs @@ -0,0 +1,133 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +// Mission Loading +// Server download handshaking. This produces a number of onPhaseX +// calls so the game scripts can update the game's GUI. +// +// Loading Phases: +// Phase 1: Download Datablocks +// Phase 2: Download Ghost Objects +// Phase 3: Scene Lighting +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +// Phase 1 +//---------------------------------------------------------------------------- + +function clientCmdMissionStartPhase1(%seq, %missionName, %musicTrack) +{ + // These need to come after the cls. + echo ("*** New Mission: " @ %missionName); + echo ("*** Phase 1: Download Datablocks & Targets"); + onMissionDownloadPhase1(%missionName, %musicTrack); + commandToServer('MissionStartPhase1Ack', %seq); +} + +function onDataBlockObjectReceived(%index, %total) +{ + onPhase1Progress(%index / %total); +} + +//---------------------------------------------------------------------------- +// Phase 2 +//---------------------------------------------------------------------------- + +function clientCmdMissionStartPhase2(%seq,%missionName) +{ + onPhase1Complete(); + echo ("*** Phase 2: Download Ghost Objects"); + onMissionDownloadPhase2(%missionName); + commandToServer('MissionStartPhase2Ack', %seq, $pref::Player:PlayerDB); +} + +function onGhostAlwaysStarted(%ghostCount) +{ + $ghostCount = %ghostCount; + $ghostsRecvd = 0; +} + +function onGhostAlwaysObjectReceived() +{ + $ghostsRecvd++; + onPhase2Progress($ghostsRecvd / $ghostCount); +} + +//---------------------------------------------------------------------------- +// Phase 3 +//---------------------------------------------------------------------------- + +function clientCmdMissionStartPhase3(%seq,%missionName) +{ + onPhase2Complete(); + StartClientReplication(); + StartFoliageReplication(); + + // Load the static mission decals. + decalManagerLoad( %missionName @ ".decals" ); + + echo ("*** Phase 3: Mission Lighting"); + $MSeq = %seq; + $Client::MissionFile = %missionName; + + // Need to light the mission before we are ready. + // The sceneLightingComplete function will complete the handshake + // once the scene lighting is done. + if (lightScene("sceneLightingComplete", "")) + { + echo("Lighting mission...."); + schedule(1, 0, "updateLightingProgress"); + onMissionDownloadPhase3(%missionName); + $lightingMission = true; + } +} + +function updateLightingProgress() +{ + onPhase3Progress($SceneLighting::lightingProgress); + if ($lightingMission) + $lightingProgressThread = schedule(1, 0, "updateLightingProgress"); +} + +function sceneLightingComplete() +{ + echo("Mission lighting done"); + onPhase3Complete(); + + // The is also the end of the mission load cycle. + onMissionDownloadComplete(); + commandToServer('MissionStartPhase3Ack', $MSeq); +} + +//---------------------------------------------------------------------------- +// Helper functions +//---------------------------------------------------------------------------- + +function connect(%server) +{ + %conn = new GameConnection(ServerConnection); + RootGroup.add(ServerConnection); + %conn.setConnectArgs($pref::Player::Name); + %conn.setJoinPassword($Client::Password); + %conn.connect(%server); +} diff --git a/Templates/Empty/game/core/scripts/client/persistenceManagerTest.cs b/Templates/Empty/game/core/scripts/client/persistenceManagerTest.cs new file mode 100644 index 000000000..a3ef4b84b --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/persistenceManagerTest.cs @@ -0,0 +1,335 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +new PersistenceManager(TestPManager); + +function runPManTest(%test) +{ + if (!isObject(TestPManager)) + return; + + if (%test $= "") + %test = 100; + + switch(%test) + { + case 0: + TestPManager.testFieldUpdates(); + case 1: + TestPManager.testObjectRename(); + case 2: + TestPManager.testNewObject(); + case 3: + TestPManager.testNewGroup(); + case 4: + TestPManager.testMoveObject(); + case 5: + TestPManager.testObjectRemove(); + case 100: + TestPManager.testFieldUpdates(); + TestPManager.testObjectRename(); + TestPManager.testNewObject(); + TestPManager.testNewGroup(); + TestPManager.testMoveObject(); + TestPManager.testObjectRemove(); + } +} + +function TestPManager::testFieldUpdates(%doNotSave) +{ + // Set some objects as dirty + TestPManager.setDirty(AudioGui); + TestPManager.setDirty(AudioSim); + TestPManager.setDirty(AudioMessage); + + // Alter some of the existing fields + AudioEffect.isLooping = true; + AudioMessage.isLooping = true; + AudioEffect.is3D = true; + + // Test removing a field + TestPManager.removeField(AudioGui, "isLooping"); + + // Alter some of the persistent fields + AudioGui.referenceDistance = 0.8; + AudioMessage.referenceDistance = 0.8; + + // Add some new dynamic fields + AudioGui.foo = "bar"; + AudioEffect.foo = "bar"; + + // Remove an object from the dirty list + // It shouldn't get updated in the file + TestPManager.removeDirty(AudioEffect); + + // Dirty an object in another file as well + TestPManager.setDirty(WarningMaterial); + + // Update a field that doesn't exist + WarningMaterial.glow[0] = true; + + // Drity another object to test for crashes + // when a dirty object is deleted + TestPManager.setDirty(SFXPausedSet); + + // Delete the object + SFXPausedSet.delete(); + + // Unless %doNotSave is set (by a batch/combo test) + // then go ahead and save now + if (!%doNotSave) + TestPManager.saveDirty(); +} + +function TestPManager::testObjectRename(%doNotSave) +{ + // Flag an object as dirty + if (isObject(AudioGui)) + TestPManager.setDirty(AudioGui); + else if (isObject(AudioGuiFoo)) + TestPManager.setDirty(AudioGuiFoo); + + // Rename it + if (isObject(AudioGui)) + AudioGui.setName(AudioGuiFoo); + else if (isObject(AudioGuiFoo)) + AudioGuiFoo.setName(AudioGui); + + // Unless %doNotSave is set (by a batch/combo test) + // then go ahead and save now + if (!%doNotSave) + TestPManager.saveDirty(); +} + +function TestPManager::testNewObject(%doNotSave) +{ + // Test adding a new named object + new SFXDescription(AudioNew) + { + volume = 0.5; + isLooping = true; + channel = $GuiAudioType; + foo = 2; + }; + + // Flag it as dirty + TestPManager.setDirty(AudioNew, "core/scripts/client/audio.cs"); + + // Test adding a new unnamed object + %obj = new SFXDescription() + { + volume = 0.75; + isLooping = true; + bar = 3; + }; + + // Flag it as dirty + TestPManager.setDirty(%obj, "core/scripts/client/audio.cs"); + + // Test adding an "empty" object + new SFXDescription(AudioEmpty); + + TestPManager.setDirty(AudioEmpty, "core/scripts/client/audio.cs"); + + // Unless %doNotSave is set (by a batch/combo test) + // then go ahead and save now + if (!%doNotSave) + TestPManager.saveDirty(); +} + +function TestPManager::testNewGroup(%doNotSave) +{ + // Test adding a new named SimGroup + new SimGroup(TestGroup) + { + foo = "bar"; + + new SFXDescription(TestObject) + { + volume = 0.5; + isLooping = true; + channel = $GuiAudioType; + foo = 1; + }; + new SimGroup(SubGroup) + { + foo = 2; + + new SFXDescription(SubObject) + { + volume = 0.5; + isLooping = true; + channel = $GuiAudioType; + foo = 3; + }; + }; + }; + + // Flag this as dirty + TestPManager.setDirty(TestGroup, "core/scripts/client/audio.cs"); + + // Test adding a new unnamed SimGroup + %group = new SimGroup() + { + foo = "bar"; + + new SFXDescription() + { + volume = 0.75; + channel = $GuiAudioType; + foo = 4; + }; + new SimGroup() + { + foo = 5; + + new SFXDescription() + { + volume = 0.75; + isLooping = true; + channel = $GuiAudioType; + foo = 6; + }; + }; + }; + + // Flag this as dirty + TestPManager.setDirty(%group, "core/scripts/client/audio.cs"); + + // Test adding a new unnamed SimSet + %set = new SimSet() + { + foo = "bar"; + + new SFXDescription() + { + volume = 0.75; + channel = $GuiAudioType; + foo = 7; + }; + new SimGroup() + { + foo = 8; + + new SFXDescription() + { + volume = 0.75; + isLooping = true; + channel = $GuiAudioType; + foo = 9; + }; + }; + }; + + // Flag this as dirty + TestPManager.setDirty(%set, "core/scripts/client/audio.cs"); + + // Unless %doNotSave is set (by a batch/combo test) + // then go ahead and save now + if (!%doNotSave) + TestPManager.saveDirty(); +} + +function TestPManager::testMoveObject(%doNotSave) +{ + // First add a couple of groups to the file + new SimGroup(MoveGroup1) + { + foo = "bar"; + + new SFXDescription(MoveObject1) + { + volume = 0.5; + isLooping = true; + channel = $GuiAudioType; + foo = 1; + }; + + new SimSet(SubGroup1) + { + new SFXDescription(SubObject1) + { + volume = 0.75; + isLooping = true; + channel = $GuiAudioType; + foo = 2; + }; + }; + }; + + // Flag this as dirty + TestPManager.setDirty(MoveGroup1, "core/scripts/client/audio.cs"); + + new SimGroup(MoveGroup2) + { + foo = "bar"; + + new SFXDescription(MoveObject2) + { + volume = 0.5; + isLooping = true; + channel = $GuiAudioType; + foo = 3; + }; + }; + + // Flag this as dirty + TestPManager.setDirty(MoveGroup2, "core/scripts/client/audio.cs"); + + // Unless %doNotSave is set (by a batch/combo test) + // then go ahead and save now + if (!%doNotSave) + TestPManager.saveDirty(); + + // Set them as dirty again + TestPManager.setDirty(MoveGroup1); + TestPManager.setDirty(MoveGroup2); + + // Give the subobject an new value + MoveObject1.foo = 4; + + // Move it into the other group + MoveGroup1.add(MoveObject2); + + // Switch the other subobject + MoveGroup2.add(MoveObject1); + + // Also add a new unnamed object to one of the groups + %obj = new SFXDescription() + { + volume = 0.75; + isLooping = true; + bar = 5; + }; + + MoveGroup1.add(%obj); + + // Unless %doNotSave is set (by a batch/combo test) + // then go ahead and save now + if (!%doNotSave) + TestPManager.saveDirty(); +} + +function TestPManager::testObjectRemove(%doNotSave) +{ + TestPManager.removeObjectFromFile(AudioSim); +} diff --git a/Templates/Empty/game/core/scripts/client/postFx.cs b/Templates/Empty/game/core/scripts/client/postFx.cs new file mode 100644 index 000000000..bbb0794bb --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/postFx.cs @@ -0,0 +1,95 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +singleton GFXStateBlockData( PFX_DefaultStateBlock ) +{ + zDefined = true; + zEnable = false; + zWriteEnable = false; + + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; +}; + +singleton ShaderData( PFX_PassthruShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/passthruP.hlsl"; + +// OGLVertexShaderFile = "shaders/common/postFx/gl//postFxV.glsl"; +// OGLPixelShaderFile = "shaders/common/postFx/gl/passthruP.glsl"; + + samplerNames[0] = "$inputTex"; + + pixVersion = 2.0; +}; + +function initPostEffects() +{ + // First exec the scripts for the different light managers + // in the lighting folder. + + %pattern = "./postFx/*.cs"; + %file = findFirstFile( %pattern ); + if ( %file $= "" ) + { + // Try for DSOs next. + %pattern = "./postFx/*.cs.dso"; + %file = findFirstFile( %pattern ); + } + + while( %file !$= "" ) + { + exec( %file ); + %file = findNextFile( %pattern ); + } +} + +function PostEffect::inspectVars( %this ) +{ + %name = %this.getName(); + %globals = "$" @ %name @ "::*"; + inspectVars( %globals ); +} + +function PostEffect::viewDisassembly( %this ) +{ + %file = %this.dumpShaderDisassembly(); + + if ( %file $= "" ) + { + echo( "PostEffect::viewDisassembly - no shader disassembly found." ); + } + else + { + echo( "PostEffect::viewDisassembly - shader disassembly file dumped ( " @ %file @ " )." ); + openFile( %file ); + } +} + +// Return true if we really want the effect enabled. +// By default this is the case. +function PostEffect::onEnabled( %this ) +{ + return true; +} \ No newline at end of file diff --git a/Templates/Empty/game/core/scripts/client/postFx/AreaMap33.dds b/Templates/Empty/game/core/scripts/client/postFx/AreaMap33.dds new file mode 100644 index 000000000..e01982a94 Binary files /dev/null and b/Templates/Empty/game/core/scripts/client/postFx/AreaMap33.dds differ diff --git a/Templates/Empty/game/core/scripts/client/postFx/GammaPostFX.cs b/Templates/Empty/game/core/scripts/client/postFx/GammaPostFX.cs new file mode 100644 index 000000000..a9738c57c --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/postFx/GammaPostFX.cs @@ -0,0 +1,42 @@ +singleton ShaderData( GammaShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/gammaP.hlsl"; + + pixVersion = 2.0; +}; + +singleton GFXStateBlockData( GammaStateBlock : PFX_DefaultStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; + samplerStates[1] = SamplerClampLinear; +}; + +singleton PostEffect( GammaPostFX ) +{ + isEnabled = true; + allowReflectPass = false; + + renderTime = "PFXBeforeBin"; + renderBin = "EditorBin"; + renderPriority = 9999; + + shader = GammaShader; + stateBlock = GammaStateBlock; + + texture[0] = "$backBuffer"; + texture[1] = $HDRPostFX::colorCorrectionRamp; +}; + +function GammaPostFX::preProcess( %this ) +{ + if ( %this.texture[1] !$= $HDRPostFX::colorCorrectionRamp ) + %this.setTexture( 1, $HDRPostFX::colorCorrectionRamp ); +} + +function GammaPostFX::setShaderConsts( %this ) +{ + %clampedGamma = mClamp( $pref::Video::Gamma, 0.001, 2.2); + %this.setShaderConst( "$OneOverGamma", 1 / %clampedGamma ); +} \ No newline at end of file diff --git a/Templates/Empty/game/core/scripts/client/postFx/MLAA.cs b/Templates/Empty/game/core/scripts/client/postFx/MLAA.cs new file mode 100644 index 000000000..47156970b --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/postFx/MLAA.cs @@ -0,0 +1,176 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// An implementation of "Practical Morphological Anti-Aliasing" from +// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria, +// Fernando Navarro, and Diego Gutierrez. +// +// http://www.iryoku.com/mlaa/ + +// NOTE: This is currently disabled in favor of FXAA. See +// core\scripts\client\canvas.cs if you want to re-enable it. + +singleton GFXStateBlockData( MLAA_EdgeDetectStateBlock : PFX_DefaultStateBlock ) +{ + // Mark the edge pixels in stencil. + stencilDefined = true; + stencilEnable = true; + stencilPassOp = GFXStencilOpReplace; + stencilFunc = GFXCmpAlways; + stencilRef = 1; + + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; +}; + +singleton ShaderData( MLAA_EdgeDetectionShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/mlaa/offsetV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/mlaa/edgeDetectionP.hlsl"; + + samplerNames[0] = "$colorMapG"; + + pixVersion = 3.0; +}; + +singleton GFXStateBlockData( MLAA_BlendWeightCalculationStateBlock : PFX_DefaultStateBlock ) +{ + // Here we want to process only marked pixels. + stencilDefined = true; + stencilEnable = true; + stencilPassOp = GFXStencilOpKeep; + stencilFunc = GFXCmpEqual; + stencilRef = 1; + + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; + samplerStates[1] = SamplerClampLinear; + samplerStates[2] = SamplerClampPoint; +}; + +singleton ShaderData( MLAA_BlendWeightCalculationShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/mlaa/passthruV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/mlaa/blendWeightCalculationP.hlsl"; + + samplerNames[0] = "$edgesMap"; + samplerNames[1] = "$edgesMapL"; + samplerNames[2] = "$areaMap"; + + pixVersion = 3.0; +}; + +singleton GFXStateBlockData( MLAA_NeighborhoodBlendingStateBlock : PFX_DefaultStateBlock ) +{ + // Here we want to process only marked pixels too. + stencilDefined = true; + stencilEnable = true; + stencilPassOp = GFXStencilOpKeep; + stencilFunc = GFXCmpEqual; + stencilRef = 1; + + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; + samplerStates[1] = SamplerClampLinear; + samplerStates[2] = SamplerClampPoint; +}; + +singleton ShaderData( MLAA_NeighborhoodBlendingShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/mlaa/offsetV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/mlaa/neighborhoodBlendingP.hlsl"; + + samplerNames[0] = "$blendMap"; + samplerNames[1] = "$colorMapL"; + samplerNames[2] = "$colorMap"; + + pixVersion = 3.0; +}; + + +singleton PostEffect( MLAAFx ) +{ + isEnabled = false; + + allowReflectPass = false; + renderTime = "PFXAfterDiffuse"; + + texture[0] = "$backBuffer"; //colorMapG + texture[1] = "#prepass"; // Used for depth detection + + target = "$outTex"; + targetClear = PFXTargetClear_OnDraw; + targetClearColor = "0 0 0 0"; + + stateBlock = MLAA_EdgeDetectStateBlock; + shader = MLAA_EdgeDetectionShader; + + // The luma calculation weights which can be user adjustable + // per-scene if nessasary. The default value of... + // + // 0.2126 0.7152 0.0722 + // + // ... is the HDTV ITU-R Recommendation BT. 709. + lumaCoefficients = "0.2126 0.7152 0.0722"; + + // The tweakable color threshold used to select + // the range of edge pixels to blend. + threshold = 0.1; + + // The depth delta threshold used to select + // the range of edge pixels to blend. + depthThreshold = 0.01; + + new PostEffect() + { + internalName = "blendingWeightsCalculation"; + + target = "$outTex"; + targetClear = PFXTargetClear_OnDraw; + + shader = MLAA_BlendWeightCalculationShader; + stateBlock = MLAA_BlendWeightCalculationStateBlock; + + texture[0] = "$inTex"; // Edges mask + texture[1] = "$inTex"; // Edges mask + texture[2] = "AreaMap33.dds"; + }; + + new PostEffect() + { + internalName = "neighborhoodBlending"; + + shader = MLAA_NeighborhoodBlendingShader; + stateBlock = MLAA_NeighborhoodBlendingStateBlock; + + texture[0] = "$inTex"; // Blend weights + texture[1] = "$backBuffer"; + texture[2] = "$backBuffer"; + }; +}; + +function MLAAFx::setShaderConsts(%this) +{ + %this.setShaderConst("$lumaCoefficients", %this.lumaCoefficients); + %this.setShaderConst("$threshold", %this.threshold); + %this.setShaderConst("$depthThreshold", %this.depthThreshold); +} \ No newline at end of file diff --git a/Templates/Empty/game/core/scripts/client/postFx/chromaticLens.cs b/Templates/Empty/game/core/scripts/client/postFx/chromaticLens.cs new file mode 100644 index 000000000..cf24c5702 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/postFx/chromaticLens.cs @@ -0,0 +1,71 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +/// +$CAPostFx::enabled = false; + +/// The lens distortion coefficient. +$CAPostFx::distCoeffecient = -0.05; + +/// The cubic distortion value. +$CAPostFx::cubeDistortionFactor = -0.1; + +/// The amount and direction of the maxium shift for +/// the red, green, and blue channels. +$CAPostFx::colorDistortionFactor = "0.005 -0.005 0.01"; + + +singleton GFXStateBlockData( PFX_DefaultChromaticLensStateBlock ) +{ + zDefined = true; + zEnable = false; + zWriteEnable = false; + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; +}; + +singleton ShaderData( PFX_ChromaticLensShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/chromaticLens.hlsl"; + pixVersion = 3.0; +}; + +singleton PostEffect( ChromaticLensPostFX ) +{ + renderTime = "PFXAfterDiffuse"; + renderPriority = 0.2; + isEnabled = false; + allowReflectPass = false; + + shader = PFX_ChromaticLensShader; + stateBlock = PFX_DefaultChromaticLensStateBlock; + texture[0] = "$backBuffer"; + target = "$backBuffer"; +}; + +function ChromaticLensPostFX::setShaderConsts( %this ) +{ + %this.setShaderConst( "$distCoeff", $CAPostFx::distCoeffecient ); + %this.setShaderConst( "$cubeDistort", $CAPostFx::cubeDistortionFactor ); + %this.setShaderConst( "$colorDistort", $CAPostFx::colorDistortionFactor ); +} diff --git a/Templates/Empty/game/core/scripts/client/postFx/default.postfxpreset.cs b/Templates/Empty/game/core/scripts/client/postFx/default.postfxpreset.cs new file mode 100644 index 000000000..35843b249 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/postFx/default.postfxpreset.cs @@ -0,0 +1,62 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +$PostFXManager::Settings::DOF::BlurCurveFar = ""; +$PostFXManager::Settings::DOF::BlurCurveNear = ""; +$PostFXManager::Settings::DOF::BlurMax = ""; +$PostFXManager::Settings::DOF::BlurMin = ""; +$PostFXManager::Settings::DOF::EnableAutoFocus = ""; +$PostFXManager::Settings::DOF::EnableDOF = ""; +$PostFXManager::Settings::DOF::FocusRangeMax = ""; +$PostFXManager::Settings::DOF::FocusRangeMin = ""; +$PostFXManager::Settings::HDR::adaptRate = "2"; +$PostFXManager::Settings::HDR::blueShiftColor = "1.05 0.97 1.27"; +$PostFXManager::Settings::HDR::brightPassThreshold = "1"; +$PostFXManager::Settings::HDR::enableBloom = "1"; +$PostFXManager::Settings::HDR::enableBlueShift = "0"; +$PostFXManager::Settings::HDR::enableToneMapping = "1"; +$PostFXManager::Settings::HDR::gaussMean = "0"; +$PostFXManager::Settings::HDR::gaussMultiplier = "0.3"; +$PostFXManager::Settings::HDR::gaussStdDev = "0.8"; +$PostFXManager::Settings::HDR::keyValue = "0.18"; +$PostFXManager::Settings::HDR::minLuminace = "0.001"; +$PostFXManager::Settings::HDR::whiteCutoff = "1"; +$PostFXManager::Settings::LightRays::brightScalar = "0.75"; +$PostFXManager::Settings::SSAO::blurDepthTol = "0.001"; +$PostFXManager::Settings::SSAO::blurNormalTol = "0.95"; +$PostFXManager::Settings::SSAO::lDepthMax = "2"; +$PostFXManager::Settings::SSAO::lDepthMin = "0.2"; +$PostFXManager::Settings::SSAO::lDepthPow = "0.2"; +$PostFXManager::Settings::SSAO::lNormalPow = "2"; +$PostFXManager::Settings::SSAO::lNormalTol = "-0.5"; +$PostFXManager::Settings::SSAO::lRadius = "1"; +$PostFXManager::Settings::SSAO::lStrength = "10"; +$PostFXManager::Settings::SSAO::overallStrength = "2"; +$PostFXManager::Settings::SSAO::quality = "0"; +$PostFXManager::Settings::SSAO::sDepthMax = "1"; +$PostFXManager::Settings::SSAO::sDepthMin = "0.1"; +$PostFXManager::Settings::SSAO::sDepthPow = "1"; +$PostFXManager::Settings::SSAO::sNormalPow = "1"; +$PostFXManager::Settings::SSAO::sNormalTol = "0"; +$PostFXManager::Settings::SSAO::sRadius = "0.1"; +$PostFXManager::Settings::SSAO::sStrength = "6"; +$PostFXManager::Settings::ColorCorrectionRamp = "core/scripts/client/postFx/null_color_ramp.png"; \ No newline at end of file diff --git a/Templates/Empty/game/core/scripts/client/postFx/dof.cs b/Templates/Empty/game/core/scripts/client/postFx/dof.cs new file mode 100644 index 000000000..1b20e44c5 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/postFx/dof.cs @@ -0,0 +1,564 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +/* + +================================================================================ + The DOFPostEffect API +================================================================================ + +DOFPostEffect::setFocalDist( %dist ) + +@summary +This method is for manually controlling the focus distance. It will have no +effect if auto focus is currently enabled. Makes use of the parameters set by +setFocusParams. + +@param dist +float distance in meters + +-------------------------------------------------------------------------------- + +DOFPostEffect::setAutoFocus( %enabled ) + +@summary +This method sets auto focus enabled or disabled. Makes use of the parameters set +by setFocusParams. When auto focus is enabled it determines the focal depth +by performing a raycast at the screen-center. + +@param enabled +bool + +-------------------------------------------------------------------------------- + +DOFPostEffect::setFocusParams( %nearBlurMax, %farBlurMax, %minRange, %maxRange, %nearSlope, %farSlope ) + +Set the parameters that control how the near and far equations are calculated +from the focal distance. If you are not using auto focus you will need to call +setFocusParams PRIOR to calling setFocalDist. + +@param nearBlurMax +float between 0.0 and 1.0 +The max allowed value of near blur. + +@param farBlurMax +float between 0.0 and 1.0 +The max allowed value of far blur. + +@param minRange/maxRange +float in meters +The distance range around the focal distance that remains in focus is a lerp +between the min/maxRange using the normalized focal distance as the parameter. +The point is to allow the focal range to expand as you focus farther away since this is +visually appealing. + +Note: since min/maxRange are lerped by the "normalized" focal distance it is +dependant on the visible distance set in your level. + +@param nearSlope +float less than zero +The slope of the near equation. A small number causes bluriness to increase gradually +at distances closer than the focal distance. A large number causes bluriness to +increase quickly. + +@param farSlope +float greater than zero +The slope of the far equation. A small number causes bluriness to increase gradually +at distances farther than the focal distance. A large number causes bluriness to +increase quickly. + +Note: To rephrase, the min/maxRange parameters control how much area around the +focal distance is completely in focus where the near/farSlope parameters control +how quickly or slowly bluriness increases at distances outside of that range. + +================================================================================ + Examples +================================================================================ + +Example1: Turn on DOF while zoomed in with a weapon. + +NOTE: These are not real callbacks! Hook these up to your code where appropriate! + +function onSniperZoom() +{ + // Parameterize how you want DOF to look. + DOFPostEffect.setFocusParams( 0.3, 0.3, 50, 500, -5, 5 ); + + // Turn on auto focus + DOFPostEffect.setAutoFocus( true ); + + // Turn on the PostEffect + DOFPostEffect.enable(); +} + +function onSniperUnzoom() +{ + // Turn off the PostEffect + DOFPostEffect.disable(); +} + +Example2: Manually control DOF with the mouse wheel. + +// Somewhere on startup... + +// Parameterize how you want DOF to look. +DOFPostEffect.setFocusParams( 0.3, 0.3, 50, 500, -5, 5 ); + +// Turn off auto focus +DOFPostEffect.setAutoFocus( false ); + +// Turn on the PostEffect +DOFPostEffect.enable(); + + +NOTE: These are not real callbacks! Hook these up to your code where appropriate! + +function onMouseWheelUp() +{ + // Since setFocalDist is really just a wrapper to assign to the focalDist + // dynamic field we can shortcut and increment it directly. + DOFPostEffect.focalDist += 8; +} + +function onMouseWheelDown() +{ + DOFPostEffect.focalDist -= 8; +} +*/ + +/// This method is for manually controlling the focal distance. It will have no +/// effect if auto focus is currently enabled. Makes use of the parameters set by +/// setFocusParams. +function DOFPostEffect::setFocalDist( %this, %dist ) +{ + %this.focalDist = %dist; +} + +/// This method sets auto focus enabled or disabled. Makes use of the parameters set +/// by setFocusParams. When auto focus is enabled it determine the focal depth +/// by performing a raycast at the screen-center. +function DOFPostEffect::setAutoFocus( %this, %enabled ) +{ + %this.autoFocusEnabled = %enabled; +} + +/// Set the parameters that control how the near and far equations are calculated +/// from the focal distance. If you are not using auto focus you will need to call +/// setFocusParams PRIOR to calling setFocalDist. +function DOFPostEffect::setFocusParams( %this, %nearBlurMax, %farBlurMax, %minRange, %maxRange, %nearSlope, %farSlope ) +{ + %this.nearBlurMax = %nearBlurMax; + %this.farBlurMax = %farBlurMax; + %this.minRange = %minRange; + %this.maxRange = %maxRange; + %this.nearSlope = %nearSlope; + %this.farSlope = %farSlope; +} + +/* + +More information... + +This DOF technique is based on this paper: +http://http.developer.nvidia.com/GPUGems3/gpugems3_ch28.html + +================================================================================ +1. Overview of how we represent "Depth of Field" +================================================================================ + +DOF is expressed as an amount of bluriness per pixel according to its depth. +We represented this by a piecewise linear curve depicted below. + +Note: we also refer to "bluriness" as CoC ( circle of confusion ) which is the term +used in the basis paper and in photography. + + +X-axis (depth) +x = 0.0----------------------------------------------x = 1.0 + +Y-axis (bluriness) +y = 1.0 + | + | ____(x1,y1) (x4,y4)____ + | (ns,nb)\ <--Line1 line2---> /(fe,fb) + | \ / + | \(x2,y2) (x3,y3)/ + | (ne,0)------(fs,0) +y = 0.0 + + +I have labeled the "corners" of this graph with (Xn,Yn) to illustrate that +this is in fact a collection of line segments where the x/y of each point +corresponds to the key below. + +key: +ns - (n)ear blur (s)tart distance +nb - (n)ear (b)lur amount (max value) +ne - (n)ear blur (e)nd distance +fs - (f)ar blur (s)tart distance +fe - (f)ar blur (e)nd distance +fb - (f)ar (b)lur amount (max value) + +Of greatest importance in this graph is Line1 and Line2. Where... +L1 { (x1,y1), (x2,y2) } +L2 { (x3,y3), (x4,y4) } + +Line one represents the amount of "near" blur given a pixels depth and line two +represents the amount of "far" blur at that depth. + +Both these equations are evaluated for each pixel and then the larger of the two +is kept. Also the output blur (for each equation) is clamped between 0 and its +maximum allowable value. + +Therefore, to specify a DOF "qualify" you need to specify the near-blur-line, +far-blur-line, and maximum near and far blur value. + +================================================================================ +2. Abstracting a "focal depth" +================================================================================ + +Although the shader(s) work in terms of a near and far equation it is more +useful to express DOF as an adjustable focal depth and derive the other parameters +"under the hood". + +Given a maximum near/far blur amount and a near/far slope we can calculate the +near/far equations for any focal depth. We extend this to also support a range +of depth around the focal depth that is also in focus and for that range to +shrink or grow as the focal depth moves closer or farther. + +Keep in mind this is only one implementation and depending on the effect you +desire you may which to express the relationship between focal depth and +the shader paramaters different. + +*/ + +//----------------------------------------------------------------------------- +// GFXStateBlockData / ShaderData +//----------------------------------------------------------------------------- + +singleton GFXStateBlockData( PFX_DefaultDOFStateBlock ) +{ + zDefined = true; + zEnable = false; + zWriteEnable = false; + + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; + samplerStates[1] = SamplerClampPoint; +}; + +singleton GFXStateBlockData( PFX_DOFCalcCoCStateBlock ) +{ + zDefined = true; + zEnable = false; + zWriteEnable = false; + + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; + samplerStates[1] = SamplerClampLinear; +}; + +singleton GFXStateBlockData( PFX_DOFDownSampleStateBlock ) +{ + zDefined = true; + zEnable = false; + zWriteEnable = false; + + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; + samplerStates[1] = SamplerClampPoint; +}; + +singleton GFXStateBlockData( PFX_DOFBlurStateBlock ) +{ + zDefined = true; + zEnable = false; + zWriteEnable = false; + + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; +}; + +singleton GFXStateBlockData( PFX_DOFFinalStateBlock ) +{ + zDefined = true; + zEnable = false; + zWriteEnable = false; + + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; + samplerStates[1] = SamplerClampLinear; + samplerStates[2] = SamplerClampLinear; + samplerStates[3] = SamplerClampPoint; + + blendDefined = true; + blendEnable = true; + blendDest = GFXBlendInvSrcAlpha; + blendSrc = GFXBlendOne; +}; + +singleton ShaderData( PFX_DOFDownSampleShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/dof/DOF_DownSample_V.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/dof/DOF_DownSample_P.hlsl"; + pixVersion = 3.0; +}; + +singleton ShaderData( PFX_DOFBlurYShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/dof/DOF_Gausian_V.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/dof/DOF_Gausian_P.hlsl"; + pixVersion = 2.0; + defines = "BLUR_DIR=float2(0.0,1.0)"; +}; + +singleton ShaderData( PFX_DOFBlurXShader : PFX_DOFBlurYShader ) +{ + defines = "BLUR_DIR=float2(1.0,0.0)"; +}; + +singleton ShaderData( PFX_DOFCalcCoCShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/dof/DOF_CalcCoC_V.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/dof/DOF_CalcCoC_P.hlsl"; + pixVersion = 3.0; +}; + +singleton ShaderData( PFX_DOFSmallBlurShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/dof/DOF_SmallBlur_V.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/dof/DOF_SmallBlur_P.hlsl"; + pixVersion = 3.0; +}; + +singleton ShaderData( PFX_DOFFinalShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/dof/DOF_Final_V.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/dof/DOF_Final_P.hlsl"; + pixVersion = 3.0; +}; + +//----------------------------------------------------------------------------- +// PostEffects +//----------------------------------------------------------------------------- + +function DOFPostEffect::onAdd( %this ) +{ + // The weighted distribution of CoC value to the three blur textures + // in the order small, medium, large. Most likely you will not need to + // change this value. + %this.setLerpDist( 0.2, 0.3, 0.5 ); + + // Fill out some default values but DOF really should not be turned on + // without actually specifying your own parameters! + %this.autoFocusEnabled = false; + %this.focalDist = 0.0; + %this.nearBlurMax = 0.5; + %this.farBlurMax = 0.5; + %this.minRange = 50; + %this.maxRange = 500; + %this.nearSlope = -5.0; + %this.farSlope = 5.0; +} + +function DOFPostEffect::setLerpDist( %this, %d0, %d1, %d2 ) +{ + %this.lerpScale = -1.0 / %d0 SPC -1.0 / %d1 SPC -1.0 / %d2 SPC 1.0 / %d2; + %this.lerpBias = 1.0 SPC ( 1.0 - %d2 ) / %d1 SPC 1.0 / %d2 SPC ( %d2 - 1.0 ) / %d2; +} + +singleton PostEffect( DOFPostEffect ) +{ + renderTime = "PFXAfterBin"; + renderBin = "GlowBin"; + renderPriority = 0.1; + + shader = PFX_DOFDownSampleShader; + stateBlock = PFX_DOFDownSampleStateBlock; + texture[0] = "$backBuffer"; + texture[1] = "#prepass"; + target = "#shrunk"; + targetScale = "0.25 0.25"; + + isEnabled = false; +}; + +singleton PostEffect( DOFBlurY ) +{ + shader = PFX_DOFBlurYShader; + stateBlock = PFX_DOFBlurStateBlock; + texture[0] = "#shrunk"; + target = "$outTex"; +}; + +DOFPostEffect.add( DOFBlurY ); + +singleton PostEffect( DOFBlurX ) +{ + shader = PFX_DOFBlurXShader; + stateBlock = PFX_DOFBlurStateBlock; + texture[0] = "$inTex"; + target = "#largeBlur"; +}; + +DOFPostEffect.add( DOFBlurX ); + +singleton PostEffect( DOFCalcCoC ) +{ + shader = PFX_DOFCalcCoCShader; + stateBlock = PFX_DOFCalcCoCStateBlock; + texture[0] = "#shrunk"; + texture[1] = "#largeBlur"; + target = "$outTex"; +}; + +DOFPostEffect.add( DOFCalcCoc ); + +singleton PostEffect( DOFSmallBlur ) +{ + shader = PFX_DOFSmallBlurShader; + stateBlock = PFX_DefaultDOFStateBlock; + texture[0] = "$inTex"; + target = "$outTex"; +}; + +DOFPostEffect.add( DOFSmallBlur ); + +singleton PostEffect( DOFFinalPFX ) +{ + shader = PFX_DOFFinalShader; + stateBlock = PFX_DOFFinalStateBlock; + texture[0] = "$backBuffer"; + texture[1] = "$inTex"; + texture[2] = "#largeBlur"; + texture[3] = "#prepass"; + target = "$backBuffer"; +}; + +DOFPostEffect.add( DOFFinalPFX ); + + +//----------------------------------------------------------------------------- +// Scripts +//----------------------------------------------------------------------------- + +function DOFPostEffect::setShaderConsts( %this ) +{ + if ( %this.autoFocusEnabled ) + %this.autoFocus(); + + %fd = %this.focalDist / $Param::FarDist; + + %range = mLerp( %this.minRange, %this.maxRange, %fd ) / $Param::FarDist * 0.5; + + // We work in "depth" space rather than real-world units for the + // rest of this method... + + // Given the focal distance and the range around it we want in focus + // we can determine the near-end-distance and far-start-distance + + %ned = getMax( %fd - %range, 0.0 ); + %fsd = getMin( %fd + %range, 1.0 ); + + // near slope + %nsl = %this.nearSlope; + + // Given slope of near blur equation and the near end dist and amount (x2,y2) + // solve for the y-intercept + // y = mx + b + // so... + // y - mx = b + + %b = 0.0 - %nsl * %ned; + + %eqNear = %nsl SPC %b SPC 0.0; + + // Do the same for the far blur equation... + + %fsl = %this.farSlope; + + %b = 0.0 - %fsl * %fsd; + + %eqFar = %fsl SPC %b SPC 1.0; + + %this.setShaderConst( "$dofEqWorld", %eqNear ); + DOFFinalPFX.setShaderConst( "$dofEqFar", %eqFar ); + + %this.setShaderConst( "$maxWorldCoC", %this.nearBlurMax ); + DOFFinalPFX.setShaderConst( "$maxFarCoC", %this.farBlurMax ); + + DOFFinalPFX.setShaderConst( "$dofLerpScale", %this.lerpScale ); + DOFFinalPFX.setShaderConst( "$dofLerpBias", %this.lerpBias ); +} + +function DOFPostEffect::autoFocus( %this ) +{ + if ( !isObject( ServerConnection ) || + !isObject( ServerConnection.getCameraObject() ) ) + { + return; + } + + %mask = $TypeMasks::StaticObjectType | $TypeMasks::TerrainObjectType; + %control = ServerConnection.getCameraObject(); + + %fvec = %control.getEyeVector(); + %start = %control.getEyePoint(); + + %end = VectorAdd( %start, VectorScale( %fvec, $Param::FarDist ) ); + + // Use the client container for this ray cast. + %result = containerRayCast( %start, %end, %mask, %control, true ); + + %hitPos = getWords( %result, 1, 3 ); + + if ( %hitPos $= "" ) + %focDist = $Param::FarDist; + else + %focDist = VectorDist( %hitPos, %start ); + + // For debuging + //$DOF::debug_dist = %focDist; + //$DOF::debug_depth = %focDist / $Param::FarDist; + //echo( "F: " @ %focDist SPC "D: " @ %delta ); + + %this.focalDist = %focDist; +} + + +// For debugging +/* +function reloadDOF() +{ + exec( "./dof.cs" ); + DOFPostEffect.reload(); + DOFPostEffect.disable(); + DOFPostEffect.enable(); +} + +function dofMetricsCallback() +{ + return " | DOF |" @ + " Dist: " @ $DOF::debug_dist @ + " Depth: " @ $DOF::debug_depth; +} +*/ \ No newline at end of file diff --git a/Templates/Empty/game/core/scripts/client/postFx/edgeAA.cs b/Templates/Empty/game/core/scripts/client/postFx/edgeAA.cs new file mode 100644 index 000000000..2735df855 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/postFx/edgeAA.cs @@ -0,0 +1,112 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +singleton GFXStateBlockData( PFX_DefaultEdgeAAStateBlock ) +{ + zDefined = true; + zEnable = false; + zWriteEnable = false; + + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; + //samplerStates[1] = SamplerWrapPoint; +}; + +singleton ShaderData( PFX_EdgeAADetectShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/edgeaa/edgeDetectP.hlsl"; + + //OGLVertexShaderFile = "shaders/common/postFx/gl//postFxV.glsl"; + //OGLPixelShaderFile = "shaders/common/postFx/gl/passthruP.glsl"; + + samplerNames[0] = "$inputTex"; + + pixVersion = 3.0; +}; + +singleton ShaderData( PFX_EdgeAAShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/edgeaa/edgeAAV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/edgeaa/edgeAAP.hlsl"; + + //OGLVertexShaderFile = "shaders/common/postFx/gl//postFxV.glsl"; + //OGLPixelShaderFile = "shaders/common/postFx/gl/passthruP.glsl"; + + samplerNames[0] = "$inputTex"; + + pixVersion = 3.0; +}; + +singleton ShaderData( PFX_EdgeAADebugShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/edgeaa/dbgEdgeDisplayP.hlsl"; + + //OGLVertexShaderFile = "shaders/common/postFx/gl//postFxV.glsl"; + //OGLPixelShaderFile = "shaders/common/postFx/gl/passthruP.glsl"; + + samplerNames[0] = "$inputTex"; + + pixVersion = 3.0; +}; + +singleton PostEffect( EdgeDetectPostEffect ) +{ + renderTime = "PFXBeforeBin"; + renderBin = "ObjTranslucentBin"; + //renderPriority = 0.1; + targetScale = "0.5 0.5"; + + shader = PFX_EdgeAADetectShader; + stateBlock = PFX_DefaultEdgeAAStateBlock; + texture[0] = "#prepass"; + target = "#edge"; + + isEnabled = false; +}; + +singleton PostEffect( EdgeAAPostEffect ) +{ + renderTime = "PFXAfterDiffuse"; + //renderBin = "ObjTranslucentBin"; + //renderPriority = 0.1; + + shader = PFX_EdgeAAShader; + stateBlock = PFX_DefaultEdgeAAStateBlock; + texture[0] = "#edge"; + texture[1] = "$backBuffer"; + target = "$backBuffer"; +}; + +singleton PostEffect( Debug_EdgeAAPostEffect ) +{ + renderTime = "PFXAfterDiffuse"; + //renderBin = "ObjTranslucentBin"; + //renderPriority = 0.1; + + shader = PFX_EdgeAADebugShader; + stateBlock = PFX_DefaultEdgeAAStateBlock; + texture[0] = "#edge"; + target = "$backBuffer"; +}; \ No newline at end of file diff --git a/Templates/Empty/game/core/scripts/client/postFx/flash.cs b/Templates/Empty/game/core/scripts/client/postFx/flash.cs new file mode 100644 index 000000000..105a0de34 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/postFx/flash.cs @@ -0,0 +1,58 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +singleton ShaderData( PFX_FlashShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/flashP.hlsl"; + + defines = "WHITE_COLOR=float4(1.0,1.0,1.0,0.0);MUL_COLOR=float4(1.0,0.25,0.25,0.0)"; + + pixVersion = 2.0; +}; + +singleton PostEffect( FlashFx ) +{ + isEnabled = false; + allowReflectPass = false; + + renderTime = "PFXAfterDiffuse"; + + shader = PFX_FlashShader; + texture[0] = "$backBuffer"; + renderPriority = 10; + stateBlock = PFX_DefaultStateBlock; +}; + +function FlashFx::setShaderConsts( %this ) +{ + if ( isObject( ServerConnection ) ) + { + %this.setShaderConst( "$damageFlash", ServerConnection.getDamageFlash() ); + %this.setShaderConst( "$whiteOut", ServerConnection.getWhiteOut() ); + } + else + { + %this.setShaderConst( "$damageFlash", 0 ); + %this.setShaderConst( "$whiteOut", 0 ); + } +} diff --git a/Templates/Empty/game/core/scripts/client/postFx/fog.cs b/Templates/Empty/game/core/scripts/client/postFx/fog.cs new file mode 100644 index 000000000..44539cb0b --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/postFx/fog.cs @@ -0,0 +1,119 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +// Fog +//------------------------------------------------------------------------------ + +singleton ShaderData( FogPassShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/fogP.hlsl"; + +// OGLVertexShaderFile = "shaders/common/postFx/gl//postFxV.glsl"; +// OGLPixelShaderFile = "shaders/common/postFx/gl/fogP.glsl"; + + samplerNames[0] = "$prepassTex"; + + pixVersion = 2.0; +}; + + +singleton GFXStateBlockData( FogPassStateBlock : PFX_DefaultStateBlock ) +{ + blendDefined = true; + blendEnable = true; + blendSrc = GFXBlendSrcAlpha; + blendDest = GFXBlendInvSrcAlpha; +}; + + +singleton PostEffect( FogPostFx ) +{ + // We forward render the reflection pass + // so it does its own fogging. + allowReflectPass = false; + + renderTime = "PFXBeforeBin"; + renderBin = "ObjTranslucentBin"; + + shader = FogPassShader; + stateBlock = FogPassStateBlock; + texture[0] = "#prepass"; + + renderPriority = 5; + + isEnabled = true; +}; + + +//------------------------------------------------------------------------------ +// UnderwaterFog +//------------------------------------------------------------------------------ + +singleton ShaderData( UnderwaterFogPassShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/underwaterFogP.hlsl"; + +// OGLVertexShaderFile = "shaders/common/postFx/gl/postFxV.glsl"; +// OGLPixelShaderFile = "shaders/common/postFx/gl/fogP.glsl"; + + samplerNames[0] = "$prepassTex"; + + pixVersion = 2.0; +}; + + +singleton GFXStateBlockData( UnderwaterFogPassStateBlock : PFX_DefaultStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; + samplerStates[1] = SamplerClampPoint; + samplerStates[2] = SamplerClampLinear; +}; + + +singleton PostEffect( UnderwaterFogPostFx ) +{ + oneFrameOnly = true; + onThisFrame = false; + + // Let the fog effect render during the + // reflection pass. + allowReflectPass = true; + + renderTime = "PFXBeforeBin"; + renderBin = "ObjTranslucentBin"; + + shader = UnderwaterFogPassShader; + stateBlock = UnderwaterFogPassStateBlock; + texture[0] = "#prepass"; + texture[1] = "$backBuffer"; + texture[2] = "#waterDepthGradMap"; + + // Needs to happen after the FogPostFx + renderPriority = 4; + + isEnabled = true; +}; + diff --git a/Templates/Empty/game/core/scripts/client/postFx/fxaa.cs b/Templates/Empty/game/core/scripts/client/postFx/fxaa.cs new file mode 100644 index 000000000..7d1ac88c2 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/postFx/fxaa.cs @@ -0,0 +1,61 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// An implementation of "NVIDIA FXAA 3.11" by TIMOTHY LOTTES +// +// http://timothylottes.blogspot.com/ +// +// The shader is tuned for the defaul quality and good performance. +// See shaders\common\postFx\fxaa\fxaaP.hlsl to tweak the internal +// quality and performance settings. + +singleton GFXStateBlockData( FXAA_StateBlock : PFX_DefaultStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; +}; + +singleton ShaderData( FXAA_ShaderData ) +{ + DXVertexShaderFile = "shaders/common/postFx/fxaa/fxaaV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/fxaa/fxaaP.hlsl"; + + samplerNames[0] = "$colorTex"; + + pixVersion = 3.0; +}; + +singleton PostEffect( FXAA_PostEffect ) +{ + isEnabled = false; + + allowReflectPass = false; + renderTime = "PFXAfterDiffuse"; + + texture[0] = "$backBuffer"; + + target = "$backBuffer"; + + stateBlock = FXAA_StateBlock; + shader = FXAA_ShaderData; +}; + diff --git a/Templates/Empty/game/core/scripts/client/postFx/glow.cs b/Templates/Empty/game/core/scripts/client/postFx/glow.cs new file mode 100644 index 000000000..d8bb086f0 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/postFx/glow.cs @@ -0,0 +1,108 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +singleton ShaderData( PFX_GlowBlurVertShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/glowBlurV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/glowBlurP.hlsl"; + +// OGLVertexShaderFile = "shaders/common/postFx/glowBlurV.glsl"; +// OGLPixelShaderFile = "shaders/common/postFx/glowBlurP.glsl"; + + defines = "BLUR_DIR=float2(0.0,1.0)"; + + samplerNames[0] = "$diffuseMap"; + + pixVersion = 2.0; +}; + + +singleton ShaderData( PFX_GlowBlurHorzShader : PFX_GlowBlurVertShader ) +{ + defines = "BLUR_DIR=float2(1.0,0.0)"; +}; + + +singleton GFXStateBlockData( PFX_GlowCombineStateBlock : PFX_DefaultStateBlock ) +{ + // Use alpha test to save some fillrate + // on the non-glowing areas of the scene. + alphaDefined = true; + alphaTestEnable = true; + alphaTestRef = 1; + alphaTestFunc = GFXCmpGreaterEqual; + + // Do a one to one blend. + blendDefined = true; + blendEnable = true; + blendSrc = GFXBlendOne; + blendDest = GFXBlendOne; +}; + + +singleton PostEffect( GlowPostFx ) +{ + // Do not allow the glow effect to work in reflection + // passes by default so we don't do the extra drawing. + allowReflectPass = false; + + renderTime = "PFXAfterBin"; + renderBin = "GlowBin"; + renderPriority = 1; + + // First we down sample the glow buffer. + shader = PFX_PassthruShader; + stateBlock = PFX_DefaultStateBlock; + texture[0] = "#glowbuffer"; + target = "$outTex"; + targetScale = "0.5 0.5"; + + isEnabled = true; + + // Blur vertically + new PostEffect() + { + shader = PFX_GlowBlurVertShader; + stateBlock = PFX_DefaultStateBlock; + texture[0] = "$inTex"; + target = "$outTex"; + }; + + // Blur horizontally + new PostEffect() + { + shader = PFX_GlowBlurHorzShader; + stateBlock = PFX_DefaultStateBlock; + texture[0] = "$inTex"; + target = "$outTex"; + }; + + // Upsample and combine with the back buffer. + new PostEffect() + { + shader = PFX_PassthruShader; + stateBlock = PFX_GlowCombineStateBlock; + texture[0] = "$inTex"; + target = "$backBuffer"; + }; +}; diff --git a/Templates/Empty/game/core/scripts/client/postFx/hdr.cs b/Templates/Empty/game/core/scripts/client/postFx/hdr.cs new file mode 100644 index 000000000..92b3989e8 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/postFx/hdr.cs @@ -0,0 +1,472 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +/// Blends between the scene and the tone mapped scene. +$HDRPostFX::enableToneMapping = 1.0; + +/// The tone mapping middle grey or exposure value used +/// to adjust the overall "balance" of the image. +/// +/// 0.18 is fairly common value. +/// +$HDRPostFX::keyValue = 0.18; + +/// The minimum luninace value to allow when tone mapping +/// the scene. Is particularly useful if your scene very +/// dark or has a black ambient color in places. +$HDRPostFX::minLuminace = 0.001; + +/// The lowest luminance value which is mapped to white. This +/// is usually set to the highest visible luminance in your +/// scene. By setting this to smaller values you get a contrast +/// enhancement. +$HDRPostFX::whiteCutoff = 1.0; + +/// The rate of adaptation from the previous and new +/// average scene luminance. +$HDRPostFX::adaptRate = 2.0; + + +/// Blends between the scene and the blue shifted version +/// of the scene for a cinematic desaturated night effect. +$HDRPostFX::enableBlueShift = 0.0; + +/// The blue shift color value. +$HDRPostFX::blueShiftColor = "1.05 0.97 1.27"; + + +/// Blends between the scene and the bloomed scene. +$HDRPostFX::enableBloom = 1.0; + +/// The threshold luminace value for pixels which are +/// considered "bright" and need to be bloomed. +$HDRPostFX::brightPassThreshold = 1.0; + +/// These are used in the gaussian blur of the +/// bright pass for the bloom effect. +$HDRPostFX::gaussMultiplier = 0.3; +$HDRPostFX::gaussMean = 0.0; +$HDRPostFX::gaussStdDev = 0.8; + +/// The 1x255 color correction ramp texture used +/// by both the HDR shader and the GammaPostFx shader +/// for doing full screen color correction. +$HDRPostFX::colorCorrectionRamp = "core/scripts/client/postFx/null_color_ramp.png"; + + +singleton ShaderData( HDR_BrightPassShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/hdr/brightPassFilterP.hlsl"; + pixVersion = 3.0; +}; + +singleton ShaderData( HDR_DownScale4x4Shader ) +{ + DXVertexShaderFile = "shaders/common/postFx/hdr/downScale4x4V.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/hdr/downScale4x4P.hlsl"; + pixVersion = 2.0; +}; + +singleton ShaderData( HDR_BloomGaussBlurHShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/hdr/bloomGaussBlurHP.hlsl"; + pixVersion = 3.0; +}; + +singleton ShaderData( HDR_BloomGaussBlurVShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/hdr/bloomGaussBlurVP.hlsl"; + pixVersion = 3.0; +}; + +singleton ShaderData( HDR_SampleLumShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/hdr/sampleLumInitialP.hlsl"; + pixVersion = 3.0; +}; + +singleton ShaderData( HDR_DownSampleLumShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/hdr/sampleLumIterativeP.hlsl"; + pixVersion = 3.0; +}; + +singleton ShaderData( HDR_CalcAdaptedLumShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/hdr/calculateAdaptedLumP.hlsl"; + pixVersion = 3.0; +}; + +singleton ShaderData( HDR_CombineShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/hdr/finalPassCombineP.hlsl"; + pixVersion = 3.0; +}; + + +singleton GFXStateBlockData( HDR_SampleStateBlock : PFX_DefaultStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; + samplerStates[1] = SamplerClampPoint; +}; + +singleton GFXStateBlockData( HDR_DownSampleStateBlock : PFX_DefaultStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; + samplerStates[1] = SamplerClampLinear; +}; + +singleton GFXStateBlockData( HDR_CombineStateBlock : PFX_DefaultStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; + samplerStates[1] = SamplerClampLinear; + samplerStates[2] = SamplerClampLinear; + samplerStates[3] = SamplerClampLinear; +}; + +singleton GFXStateBlockData( HDRStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; + samplerStates[1] = SamplerClampLinear; + samplerStates[2] = SamplerClampLinear; + samplerStates[3] = SamplerClampLinear; + + blendDefined = true; + blendDest = GFXBlendOne; + blendSrc = GFXBlendZero; + + zDefined = true; + zEnable = false; + zWriteEnable = false; + + cullDefined = true; + cullMode = GFXCullNone; +}; + + +function HDRPostFX::setShaderConsts( %this ) +{ + %this.setShaderConst( "$brightPassThreshold", $HDRPostFX::brightPassThreshold ); + %this.setShaderConst( "$g_fMiddleGray", $HDRPostFX::keyValue ); + + %bloomH = %this-->bloomH; + %bloomH.setShaderConst( "$gaussMultiplier", $HDRPostFX::gaussMultiplier ); + %bloomH.setShaderConst( "$gaussMean", $HDRPostFX::gaussMean ); + %bloomH.setShaderConst( "$gaussStdDev", $HDRPostFX::gaussStdDev ); + + %bloomV = %this-->bloomV; + %bloomV.setShaderConst( "$gaussMultiplier", $HDRPostFX::gaussMultiplier ); + %bloomV.setShaderConst( "$gaussMean", $HDRPostFX::gaussMean ); + %bloomV.setShaderConst( "$gaussStdDev", $HDRPostFX::gaussStdDev ); + + %minLuminace = $HDRPostFX::minLuminace; + if ( %minLuminace <= 0.0 ) + { + // The min should never be pure zero else the + // log() in the shader will generate INFs. + %minLuminace = 0.00001; + } + %this-->adaptLum.setShaderConst( "$g_fMinLuminace", %minLuminace ); + + %this-->finalLum.setShaderConst( "$adaptRate", $HDRPostFX::adaptRate ); + + %combinePass = %this-->combinePass; + %combinePass.setShaderConst( "$g_fEnableToneMapping", $HDRPostFX::enableToneMapping ); + %combinePass.setShaderConst( "$g_fMiddleGray", $HDRPostFX::keyValue ); + %combinePass.setShaderConst( "$g_fBloomScale", $HDRPostFX::enableBloom ); + %combinePass.setShaderConst( "$g_fEnableBlueShift", $HDRPostFX::enableBlueShift ); + %combinePass.setShaderConst( "$g_fBlueShiftColor", $HDRPostFX::blueShiftColor ); + + %clampedGamma = mClamp( $pref::Video::Gamma, 0.001, 2.2); + %combinePass.setShaderConst( "$g_fOneOverGamma", 1 / %clampedGamma ); + + %whiteCutoff = ( $HDRPostFX::whiteCutoff * $HDRPostFX::whiteCutoff ) * + ( $HDRPostFX::whiteCutoff * $HDRPostFX::whiteCutoff ); + %combinePass.setShaderConst( "$g_fWhiteCutoff", %whiteCutoff ); +} + +function HDRPostFX::preProcess( %this ) +{ + %combinePass = %this-->combinePass; + + if ( %combinePass.texture[3] !$= $HDRPostFX::colorCorrectionRamp ) + %combinePass.setTexture( 3, $HDRPostFX::colorCorrectionRamp ); +} + +function HDRPostFX::onEnabled( %this ) +{ + // We don't allow hdr on OSX yet. + if ( $platform $= "macos" ) + return false; + + // See what HDR format would be best. + %format = getBestHDRFormat(); + if ( %format $= "" || %format $= "GFXFormatR8G8B8A8" ) + { + // We didn't get a valid HDR format... so fail. + return false; + } + + // HDR does it's own gamma calculation so + // disable this postFx. + GammaPostFX.disable(); + + // Set the right global shader define for HDR. + if ( %format $= "GFXFormatR10G10B10A2" ) + addGlobalShaderMacro( "TORQUE_HDR_RGB10" ); + else if ( %format $= "GFXFormatR16G16B16A16" ) + addGlobalShaderMacro( "TORQUE_HDR_RGB16" ); + + echo( "HDR FORMAT: " @ %format ); + + // Change the format of the offscreen surface + // to an HDR compatible format. + AL_FormatToken.format = %format; + setReflectFormat( %format ); + + // Reset the light manager which will ensure the new + // hdr encoding takes effect in all the shaders and + // that the offscreen surface is enabled. + resetLightManager(); + + return true; +} + +function HDRPostFX::onDisabled( %this ) +{ + // Enable a special GammaCorrection PostFX when this is disabled. + GammaPostFX.enable(); + + // Restore the non-HDR offscreen surface format. + %format = "GFXFormatR8G8B8A8"; + AL_FormatToken.format = %format; + setReflectFormat( %format ); + + removeGlobalShaderMacro( "TORQUE_HDR_RGB10" ); + removeGlobalShaderMacro( "TORQUE_HDR_RGB16" ); + + // Reset the light manager which will ensure the new + // hdr encoding takes effect in all the shaders. + resetLightManager(); +} + +singleton PostEffect( HDRPostFX ) +{ + isEnabled = false; + allowReflectPass = false; + + // Resolve the HDR before we render any editor stuff + // and before we resolve the scene to the backbuffer. + renderTime = "PFXBeforeBin"; + renderBin = "EditorBin"; + renderPriority = 9999; + + // The bright pass generates a bloomed version of + // the scene for pixels which are brighter than a + // fixed threshold value. + // + // This is then used in the final HDR combine pass + // at the end of this post effect chain. + // + + shader = HDR_BrightPassShader; + stateBlock = HDR_DownSampleStateBlock; + texture[0] = "$backBuffer"; + texture[1] = "#adaptedLum"; + target = "$outTex"; + targetFormat = "GFXFormatR16G16B16A16F"; + targetScale = "0.5 0.5"; + + new PostEffect() + { + shader = HDR_DownScale4x4Shader; + stateBlock = HDR_DownSampleStateBlock; + texture[0] = "$inTex"; + target = "$outTex"; + targetFormat = "GFXFormatR16G16B16A16F"; + targetScale = "0.25 0.25"; + }; + + new PostEffect() + { + internalName = "bloomH"; + + shader = HDR_BloomGaussBlurHShader; + stateBlock = HDR_DownSampleStateBlock; + texture[0] = "$inTex"; + target = "$outTex"; + targetFormat = "GFXFormatR16G16B16A16F"; + }; + + new PostEffect() + { + internalName = "bloomV"; + + shader = HDR_BloomGaussBlurVShader; + stateBlock = HDR_DownSampleStateBlock; + texture[0] = "$inTex"; + target = "#bloomFinal"; + targetFormat = "GFXFormatR16G16B16A16F"; + }; + + // BrightPass End + + // Now calculate the adapted luminance. + new PostEffect() + { + internalName = "adaptLum"; + + shader = HDR_SampleLumShader; + stateBlock = HDR_DownSampleStateBlock; + texture[0] = "$backBuffer"; + target = "$outTex"; + targetScale = "0.0625 0.0625"; // 1/16th + targetFormat = "GFXFormatR16F"; + + new PostEffect() + { + shader = HDR_DownSampleLumShader; + stateBlock = HDR_DownSampleStateBlock; + texture[0] = "$inTex"; + target = "$outTex"; + targetScale = "0.25 0.25"; // 1/4 + targetFormat = "GFXFormatR16F"; + }; + + new PostEffect() + { + shader = HDR_DownSampleLumShader; + stateBlock = HDR_DownSampleStateBlock; + texture[0] = "$inTex"; + target = "$outTex"; + targetScale = "0.25 0.25"; // 1/4 + targetFormat = "GFXFormatR16F"; + }; + + new PostEffect() + { + shader = HDR_DownSampleLumShader; + stateBlock = HDR_DownSampleStateBlock; + texture[0] = "$inTex"; + target = "$outTex"; + targetScale = "0.25 0.25"; // At this point the target should be 1x1. + targetFormat = "GFXFormatR16F"; + }; + + // Note that we're reading the adapted luminance + // from the previous frame when generating this new + // one... PostEffect takes care to manage that. + new PostEffect() + { + internalName = "finalLum"; + shader = HDR_CalcAdaptedLumShader; + stateBlock = HDR_DownSampleStateBlock; + texture[0] = "$inTex"; + texture[1] = "#adaptedLum"; + target = "#adaptedLum"; + targetFormat = "GFXFormatR16F"; + targetClear = "PFXTargetClear_OnCreate"; + targetClearColor = "1 1 1 1"; + }; + }; + + // Output the combined bloom and toned mapped + // version of the scene. + new PostEffect() + { + internalName = "combinePass"; + + shader = HDR_CombineShader; + stateBlock = HDR_CombineStateBlock; + texture[0] = "$backBuffer"; + texture[1] = "#adaptedLum"; + texture[2] = "#bloomFinal"; + texture[3] = $HDRPostFX::colorCorrectionRamp; + target = "$backBuffer"; + }; +}; + +singleton ShaderData( LuminanceVisShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/hdr/luminanceVisP.hlsl"; + pixVersion = 3.0; +}; + +singleton GFXStateBlockData( LuminanceVisStateBlock : PFX_DefaultStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; +}; + +function LuminanceVisPostFX::setShaderConsts( %this ) +{ + %this.setShaderConst( "$brightPassThreshold", $HDRPostFX::brightPassThreshold ); +} + +singleton PostEffect( LuminanceVisPostFX ) +{ + isEnabled = false; + allowReflectPass = false; + + // Render before we do any editor rendering. + renderTime = "PFXBeforeBin"; + renderBin = "EditorBin"; + renderPriority = 9999; + + shader = LuminanceVisShader; + stateBlock = LuminanceVisStateBlock; + texture[0] = "$backBuffer"; + target = "$backBuffer"; + //targetScale = "0.0625 0.0625"; // 1/16th + //targetFormat = "GFXFormatR16F"; +}; + +function LuminanceVisPostFX::onEnabled( %this ) +{ + if ( !HDRPostFX.isEnabled() ) + { + HDRPostFX.enable(); + } + + HDRPostFX.skip = true; + + return true; +} + +function LuminanceVisPostFX::onDisabled( %this ) +{ + HDRPostFX.skip = false; +} + diff --git a/Templates/Empty/game/core/scripts/client/postFx/lightRay.cs b/Templates/Empty/game/core/scripts/client/postFx/lightRay.cs new file mode 100644 index 000000000..b8b15adb7 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/postFx/lightRay.cs @@ -0,0 +1,97 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +$LightRayPostFX::brightScalar = 0.75; +$LightRayPostFX::numSamples = 40; +$LightRayPostFX::density = 0.94; +$LightRayPostFX::weight = 5.65; +$LightRayPostFX::decay = 1.0; +$LightRayPostFX::exposure = 0.0005; +$LightRayPostFX::resolutionScale = 1.0; + + +singleton ShaderData( LightRayOccludeShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/lightRay/lightRayOccludeP.hlsl"; + + pixVersion = 3.0; +}; + +singleton ShaderData( LightRayShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/lightRay/lightRayP.hlsl"; + + pixVersion = 3.0; +}; + +singleton GFXStateBlockData( LightRayStateBlock : PFX_DefaultStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; + samplerStates[1] = SamplerClampLinear; +}; + +singleton PostEffect( LightRayPostFX ) +{ + isEnabled = false; + allowReflectPass = false; + + renderTime = "PFXAfterDiffuse"; + renderPriority = 0.1; + + shader = LightRayOccludeShader; + stateBlock = LightRayStateBlock; + texture[0] = "$backBuffer"; + texture[1] = "#prepass"; + target = "$outTex"; + targetFormat = "GFXFormatR16G16B16A16F"; + + new PostEffect() + { + shader = LightRayShader; + stateBlock = LightRayStateBlock; + internalName = "final"; + texture[0] = "$inTex"; + texture[1] = "$backBuffer"; + target = "$backBuffer"; + }; +}; + +function LightRayPostFX::preProcess( %this ) +{ + %this.targetScale = $LightRayPostFX::resolutionScale SPC $LightRayPostFX::resolutionScale; +} + +function LightRayPostFX::setShaderConsts( %this ) +{ + %this.setShaderConst( "$brightScalar", $LightRayPostFX::brightScalar ); + + %pfx = %this-->final; + %pfx.setShaderConst( "$numSamples", $LightRayPostFX::numSamples ); + %pfx.setShaderConst( "$density", $LightRayPostFX::density ); + %pfx.setShaderConst( "$weight", $LightRayPostFX::weight ); + %pfx.setShaderConst( "$decay", $LightRayPostFX::decay ); + %pfx.setShaderConst( "$exposure", $LightRayPostFX::exposure ); +} diff --git a/Templates/Empty/game/core/scripts/client/postFx/noise.png b/Templates/Empty/game/core/scripts/client/postFx/noise.png new file mode 100644 index 000000000..ebff74256 Binary files /dev/null and b/Templates/Empty/game/core/scripts/client/postFx/noise.png differ diff --git a/Templates/Empty/game/core/scripts/client/postFx/null_color_ramp.png b/Templates/Empty/game/core/scripts/client/postFx/null_color_ramp.png new file mode 100644 index 000000000..5f5a52186 Binary files /dev/null and b/Templates/Empty/game/core/scripts/client/postFx/null_color_ramp.png differ diff --git a/Templates/Empty/game/core/scripts/client/postFx/postFXManager.gui b/Templates/Empty/game/core/scripts/client/postFx/postFXManager.gui new file mode 100644 index 000000000..0f7fae83b --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/postFx/postFXManager.gui @@ -0,0 +1,2482 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(PostFXManager) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiModelessDialogProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new DbgFileView() { + position = "0 0"; + extent = "8 2"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiWindowCtrl(ppOptionsWindow) { + text = "PostFX Manager"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + closeCommand = "Canvas.popDialog(PostFXManager);"; + edgeSnap = "0"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "306 216"; + extent = "411 336"; + minExtent = "8 8"; + horizSizing = "center"; + vertSizing = "center"; + profile = "GuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapBorderCtrl() { + position = "11 77"; + extent = "390 216"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabBorderProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTabBookCtrl(ppOptionsTabBook) { + tabPosition = "Top"; + tabMargin = "7"; + minTabWidth = "64"; + tabHeight = "20"; + allowReorder = "0"; + defaultPage = "-1"; + selectedPage = "1"; + frontTabPadding = "0"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "11 58"; + extent = "394 233"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabBookProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTabPageCtrl(ppOptionsSSAOTab) { + fitBook = "0"; + text = "SSAO"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 20"; + extent = "394 213"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Options for the Screen Space Ambient Occlusion postFX"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapBorderCtrl() { + position = "12 30"; + extent = "365 170"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabBorderProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTabBookCtrl(ppOptionsSSAOOptions) { + tabPosition = "Top"; + tabMargin = "7"; + minTabWidth = "64"; + tabHeight = "20"; + allowReorder = "0"; + defaultPage = "-1"; + selectedPage = "2"; + frontTabPadding = "0"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 11"; + extent = "362 185"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabBookProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTabPageCtrl(ppOptionsSSAOGeneralTab) { + fitBook = "0"; + text = "General"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 20"; + extent = "362 165"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Contains general overall settings for the SSAO postFX"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl(ppOptionsSSAOOverallStrengthLabel) { + text = "Overall Strength"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "31 57"; + extent = "77 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the overall strength of the Ambient Occlusion effect."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAOBlurDepthLabel) { + text = "Blur (Softness)"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "38 85"; + extent = "73 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the amount of softness in the SSAO, overall."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAOBlurNormalLabel) { + text = "Blur (Normal Maps)"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "19 112"; + extent = "92 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the amount of softness in the SSAO, in the normal maps."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(ppOptionsSSAOQuality) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "Low"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "120 28"; + extent = "211 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAOQualityLabel) { + text = "Quality"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "76 29"; + extent = "32 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAOOverallStrength) { + range = "0 50"; + ticks = "1000"; + snap = "0"; + value = "2"; + position = "120 56"; + extent = "211 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAOBlurDepth) { + range = "0 0.3"; + ticks = "1000"; + snap = "0"; + value = "0.001"; + position = "120 86"; + extent = "211 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAOBlurNormal) { + range = "0 1"; + ticks = "1000"; + snap = "0"; + value = "0.95"; + position = "119 113"; + extent = "212 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTabPageCtrl(ppOptionsSSAONearTab) { + fitBook = "0"; + text = "Near"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 20"; + extent = "362 165"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Contains settings for the near range ambient occlusion aspect of the SSAO postFX"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiSliderCtrl(ppOptionsSSAONearRadius) { + range = "0.001 5"; + ticks = "1000"; + snap = "0"; + value = "0.1"; + position = "122 17"; + extent = "221 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAONearDepthMin) { + range = "0 5"; + ticks = "1000"; + snap = "0"; + value = "0.1"; + position = "122 62"; + extent = "221 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAONearStrength) { + range = "0 20"; + ticks = "1000"; + snap = "0"; + value = "6"; + position = "122 39"; + extent = "221 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAONearRadiusLabel) { + text = "Radius"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "80 16"; + extent = "34 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the near/small radius SSAO reach."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAONearStrengthLabel) { + text = "Strength"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "73 38"; + extent = "41 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the near/small radius SSAO strength."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAONearDepthMinLabel) { + text = "Depth Min"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "66 61"; + extent = "48 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the near/small radius SSAO minimum depth value."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAONearDepthMaxLabel) { + text = "Depth Max"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "62 85"; + extent = "52 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the near/small radius SSAO maximum depth value."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAONearDepthMax) { + range = "0 50"; + ticks = "1000"; + snap = "0"; + value = "1"; + position = "122 86"; + extent = "221 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAONearToleranceNormal) { + range = "0 2"; + ticks = "1000"; + snap = "0"; + value = "0"; + position = "122 133"; + extent = "103 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAONearTolerancePower) { + range = "0 2"; + ticks = "1000"; + snap = "0"; + value = "1"; + position = "246 133"; + extent = "97 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAONearToleranceLabel2) { + text = "Tolerance / Power"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "24 132"; + extent = "92 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAONearToleranceLabel1) { + text = "Normal Maps : "; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "19 113"; + extent = "71 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTabPageCtrl(ppOptionsSSAOFarTab) { + fitBook = "0"; + text = "Far"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 20"; + extent = "362 165"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Contains settings for the far range ambient occlusion aspect of the SSAO postFX"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl(ppOptionsSSAOFarRadiusLabel) { + text = "Radius"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "80 16"; + extent = "34 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the far/large radius SSAO reach."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAOFarRadius) { + range = "0.001 5"; + ticks = "1000"; + snap = "0"; + value = "1"; + position = "122 17"; + extent = "221 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAOFarStrengthLabel) { + text = "Strength"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "73 38"; + extent = "41 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the far/large radius SSAO strength."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAOFarStrength) { + range = "0 20"; + ticks = "1000"; + snap = "0"; + value = "10"; + position = "122 39"; + extent = "221 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAOFarDepthMinLabel) { + text = "Depth Min"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "66 61"; + extent = "48 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the far/large radius SSAO minimum depth."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAOFarDepthMin) { + range = "0 5"; + ticks = "1000"; + snap = "0"; + value = "0.2"; + position = "122 62"; + extent = "221 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAOFarDepthMaxLabel) { + text = "Depth Max"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "62 85"; + extent = "52 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the far/large radius SSAO maximum."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAOFarDepthMax) { + range = "0 5"; + ticks = "1000"; + snap = "0"; + value = "2"; + position = "122 86"; + extent = "221 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAOFarToleranceLabel1) { + text = "Normal Maps :"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "6 113"; + extent = "72 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Tolerance / Power"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "24 132"; + extent = "90 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAOFarToleranceNormal) { + range = "0 2"; + ticks = "1000"; + snap = "0"; + value = "0"; + position = "122 133"; + extent = "100 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAOFarTolerancePower) { + range = "0 2"; + ticks = "1000"; + snap = "0"; + value = "2"; + position = "239 133"; + extent = "104 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiCheckBoxCtrl(ppOptionsEnableSSAO) { + useInactiveState = "0"; + text = "Enable"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "329 7"; + extent = "53 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enable/Disable the SSAO postFX"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTabPageCtrl(ppOptionsHDRTab) { + fitBook = "0"; + text = "HDR"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 20"; + extent = "394 213"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Options for the High Definition Range Lighting postFX"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapBorderCtrl() { + position = "12 30"; + extent = "363 172"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabBorderProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTabBookCtrl(ppOptionsHDROptions) { + tabPosition = "Top"; + tabMargin = "7"; + minTabWidth = "64"; + tabHeight = "20"; + allowReorder = "0"; + defaultPage = "-1"; + selectedPage = "0"; + frontTabPadding = "0"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 11"; + extent = "365 195"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabBookProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTabPageCtrl(ppOptionsHDRBrightnessTab) { + fitBook = "0"; + text = "Brightness"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 20"; + extent = "365 175"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Contains settings related to the brightness of the HDR postFX"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiSliderCtrl(ppOptionsHDRMinLuminance) { + range = "0 1"; + ticks = "1000"; + snap = "0"; + value = "0"; + position = "132 77"; + extent = "206 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Value : 0"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsHDRKeyValue) { + range = "0 1"; + ticks = "1000"; + snap = "0"; + value = "0.0459184"; + position = "132 50"; + extent = "206 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Value : 0.0459184"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsHDRKeyValueLabel) { + text = "Key Value"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "69 50"; + extent = "52 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "The tone mapping middle grey or exposure value used to adjust the overall \"balance\" of the image."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsHDRMinLuminanceLabel) { + text = "Minimum Luminance"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "25 77"; + extent = "96 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "The minimum luminance value to allow when tone mapping the scene. This is particularly useful if your scene is very dark or has a black ambient color in places."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsHDRWhiteCutoffLabel) { + text = "White Cutoff"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "56 104"; + extent = "65 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "The cutoff level for the white levels in the brightness."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsHDRWhiteCutoff) { + range = "0 1"; + ticks = "1000"; + snap = "0"; + value = "0.52551"; + position = "132 104"; + extent = "206 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Value : 0.52551"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsHDRBrightnessAdaptRate) { + range = "0.1 10"; + ticks = "1000"; + snap = "0"; + value = "2"; + position = "132 132"; + extent = "205 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsHDRBrightnessAdaptRateLabel) { + text = "Brightness Adapt Rate"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 132"; + extent = "109 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "The speed at which the view adjusts to the new lighting in the environment."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsHDRKeyValueLabel1) { + text = "Tone Mapping Contrast"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "10 24"; + extent = "111 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Tone mapping contrast is the amount of scene to blend, with the tone mapped HDR scene. Lower values are recommended but higher values give a strong contrasted darker shadowed look."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsHDRToneMappingAmount) { + range = "0 1"; + ticks = "1000"; + snap = "0"; + value = "0.265306"; + position = "132 24"; + extent = "206 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "value : 0.265306"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTabPageCtrl(ppOptionsHDRBloomTab) { + fitBook = "0"; + text = "Bloom"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 20"; + extent = "365 175"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Contains settings related to the blooming aspect of the HDR postFX"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiSliderCtrl(ppOptionsHDRBloomBlurMultiplier) { + range = "0 5"; + ticks = "1000"; + snap = "0"; + value = "0.502645"; + position = "132 70"; + extent = "199 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Value : 0.502645"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsHDRBloomBlurMean) { + range = "0 1"; + ticks = "1000"; + snap = "0"; + value = "0.510526"; + position = "132 97"; + extent = "200 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Value : 0.510526"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsHDRBloomBlurStdDev) { + range = "0 3"; + ticks = "1000"; + snap = "0"; + value = "1.4127"; + position = "132 123"; + extent = "199 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Value : 1.4127"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsHDRBlurMultiplierLabel) { + text = "Blur Multiplier"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "59 70"; + extent = "63 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "The amount of blur to apply to the bloomed areas in the HDR."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsHDRBlurMeanLabel) { + text = "Blur \"mean\" value"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "38 97"; + extent = "84 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsHDRBlurStandardDevianceLabel) { + text = "Blur \"Std Dev\" value"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "23 123"; + extent = "99 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsHDRBloomBrightPassThresholdLabel) { + text = "Bright pass threshold"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "19 43"; + extent = "103 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "The bright pass threshold controls how bright the brightest areas of the scene are in the HDR."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsHDRBloomBlurBrightPassThreshold) { + range = "0 5"; + ticks = "1000"; + snap = "0"; + value = "1.60526"; + position = "132 43"; + extent = "200 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Value : 1.60526"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(ppOptionsHDRBloom) { + useInactiveState = "0"; + text = " Enable Bloom"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "250 9"; + extent = "85 24"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enables or disables the bloom (glowing effect) of the HDR PostFX."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTabPageCtrl(ppOptionsHDRBloomEffectsTab) { + fitBook = "0"; + text = "Effects"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 20"; + extent = "365 175"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Contains settings related to the effects the HDR postFX can offer"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiCheckBoxCtrl(ppOptionsHDREffectsBlueShift) { + useInactiveState = "0"; + text = " Enable Color Shift"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "11 4"; + extent = "117 24"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enables a scene tinting/Blue shift based on the color selected below."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiColorPickerCtrl(ppOptionsHDREffectsBlueShiftColorBlend) { + baseColor = "1 0 0.0235294 1"; + pickColor = "0 0 0 1"; + selectorGap = "1"; + displayMode = "BlendColor"; + actionOnMove = "1"; + showReticle = "1"; + position = "10 29"; + extent = "344 110"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Select a color"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiColorPickerCtrl(ppOptionsHDREffectsBlueShiftColorBaseColor) { + baseColor = "1 0 0.0235294 1"; + pickColor = "0 0 0 1"; + selectorGap = "1"; + displayMode = "HorizColor"; + actionOnMove = "1"; + showReticle = "1"; + position = "10 142"; + extent = "343 21"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Select a color"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiCheckBoxCtrl(ppOptionsHDRToneMapping) { + useInactiveState = "0"; + text = " Enable Tone Mapping"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "18 8"; + extent = "120 24"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enables or disabled tone mapping on the HDR. The tone mapping balanced the brightness levels during the HDR process. Recommended"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(ppOptionsEnableHDR) { + useInactiveState = "0"; + text = "Enable"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "329 7"; + extent = "53 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enable/Disable the HDR postFX (takes some time to initialise, be patient)"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(ppOptionsEnableHDRDebug) { + useInactiveState = "0"; + text = "Debug"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "262 7"; + extent = "53 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTabPageCtrl(ppOptionsLightRaysTab) { + fitBook = "0"; + text = "Light Rays"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 20"; + extent = "394 213"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Options for the Light Rays postFX"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiSliderCtrl(ppOptionsLightRaysBrightScalar) { + range = "0 5"; + ticks = "1000"; + snap = "0"; + value = "0.75"; + position = "96 96"; + extent = "264 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsLightRaysBrightnessScalarLabel) { + text = "Brightness"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "26 98"; + extent = "87 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls how bright the rays and the object casting them are in the scene."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(ppOptionsEnableLightRays) { + useInactiveState = "0"; + text = "Enable"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "329 7"; + extent = "53 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enable/Disable the light rays postFX"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTabPageCtrl(ppOptionsDOFTab) { + fitBook = "0"; + text = "DOF"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 20"; + extent = "394 213"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Options for the Depth Of Field postFX"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapBorderCtrl() { + position = "14 28"; + extent = "362 170"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabBorderProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTabBookCtrl() { + tabPosition = "Top"; + tabMargin = "7"; + minTabWidth = "64"; + tabHeight = "20"; + allowReorder = "0"; + defaultPage = "-1"; + selectedPage = "1"; + frontTabPadding = "0"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "14 9"; + extent = "360 189"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabBookProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTabPageCtrl(ppOptionsDOFGeneralTab) { + fitBook = "0"; + text = "General"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 20"; + extent = "360 169"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Contains general settings related to the DOF system"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + //new GuiCheckBoxCtrl(ppOptionsDOFEnableDOF) { + //useInactiveState = "0"; + //text = "Enable DOF"; + //groupNum = "-1"; + //buttonType = "ToggleButton"; + //useMouseEvents = "0"; + //position = "31 43"; + //extent = "140 30"; + //minExtent = "8 2"; + //horizSizing = "right"; + //vertSizing = "bottom"; + //profile = "GuiCheckBoxProfile"; + //visible = "1"; + //active = "1"; + //tooltipProfile = "GuiToolTipProfile"; + //hovertime = "1000"; + //isContainer = "0"; + //canSave = "1"; + //canSaveDynamicFields = "0"; + //}; + new GuiCheckBoxCtrl(ppOptionsDOFEnableAutoFocus) { + useInactiveState = "0"; + text = "Enable Auto Focus"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "31 8"; + extent = "140 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTabPageCtrl(ppOptionsDOFAutoFocusTab) { + fitBook = "0"; + text = "Auto Focus"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 20"; + extent = "360 169"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Contains settings related to the fine control of the auto focus system"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl(ppOptionsDOFNearBlurMaxLabel) { + text = "Near Blur Max"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "36 8"; + extent = "67 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "The max allowed value of near blur"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsDOFFarBlurMinSlider) { + range = "0 1"; + ticks = "1000"; + snap = "0"; + value = "0"; + position = "120 8"; + extent = "224 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsDOFFarBlurMaxLabel) { + text = "Far Blur Max"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "43 34"; + extent = "60 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "The max allowed value of far blur"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsDOFFarBlurMaxSlider) { + range = "0 1"; + ticks = "1000"; + snap = "0"; + value = "0"; + position = "120 34"; + extent = "224 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsDOFFocusRangeMinLabel) { + text = "Focus Range (Min)"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "13 61"; + extent = "90 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "The distance range around the focal distance that remains in focus (in meters, minimum distance in focus) focal distance it is\r\ndependant on the visible distance set in your level"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsDOFFocusRangeMinSlider) { + range = "0.01 1e+003"; + ticks = "1000"; + snap = "0"; + value = "0.01"; + position = "120 61"; + extent = "224 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsDOFFocusRangeMaxLabel) { + text = "Focus Range (Max)"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "9 88"; + extent = "95 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "The distance range around the focal distance that remains in focus (in meters, maximum distance in focus) focal distance it is\r\ndependant on the visible distance set in your level"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsDOFFocusRangeMaxSlider) { + range = "0.01 1e+003"; + ticks = "1000"; + snap = "0"; + value = "0.01"; + position = "119 87"; + extent = "224 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsDOFBurCurveNearLabel) { + text = "Blur Curve Near"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "27 114"; + extent = "77 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "A small number causes bluriness to increase gradually\r\nat distances closer than the focal distance. A large number causes bluriness to \r\nincrease quickly"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsDOFBlurCurveNearSlider) { + range = "0 50"; + ticks = "1000"; + snap = "0"; + value = "0"; + position = "119 114"; + extent = "225 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsDOFBlurCurveFarLabel) { + text = "Blur Curve Far"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "33 139"; + extent = "70 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "A small number causes bluriness to increase gradually\r\nat distances closer than the focal distance. A large number causes bluriness to \r\nincrease quickly"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsDOFBlurCurveFarSlider) { + range = "0 50"; + ticks = "1000"; + snap = "0"; + value = "0"; + position = "119 141"; + extent = "224 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiCheckBoxCtrl(ppOptionsEnableDOF) { + useInactiveState = "0"; + text = "Enable"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "329 7"; + extent = "53 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enable/Disable the Depth of field postFX"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTabPageCtrl() { + fitBook = "0"; + text = "Color Correction"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "8 27"; + extent = "376 200"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "ColorCorrectionTab"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Color Correction Ramp"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "6 7"; + extent = "118 13"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "core/scripts/client/postFx/null_color_ramp.png"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "6 29"; + extent = "365 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + altCommand = "ppColorCorrection_selectFileHandler( $thisControl.getText() );"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "ColorCorrectionFileName"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Select..."; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "252 54"; + extent = "56 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "ppColorCorrection_selectFile();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "ColorCorrectionButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Reset"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "315 54"; + extent = "56 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "ppColorCorrection_selectFileHandler( \"\" );"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "ColorCorrectionReset"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiButtonCtrl(ppOptionsApply) { + text = "Apply"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "309 302"; + extent = "93 23"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "PostFXManager.settingsApplyAll(); Canvas.popDialog(PostFXManager);"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Apply the settings and close this dialog"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(ppOptionsSavePreset) { + text = "Save Preset..."; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "111 302"; + extent = "93 23"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "PostFXManager.savePresetFile();"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Save the preset to a file to disk for later use (use postfx::applyPreset)"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(ppOptionsLoadPreset) { + text = "Load Preset..."; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "12 302"; + extent = "93 23"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "PostFXManager.loadPresetFile();"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Load a post FX preset file from disk"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(ppOptionsEnable) { + useInactiveState = "0"; + text = "Enable PostFX System"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "13 24"; + extent = "127 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enable or Disable the postFX system"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(ppOptionsQuality) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "278 30"; + extent = "122 21"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Used to adjust the quality/performance settings of the PostFX system. Some PostFX may not adhere to the settings in this dialog."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsQualityLabel) { + text = "Quality"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "238 32"; + extent = "39 12"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Used to adjust the quality/performance settings of the PostFX system. Some PostFX may not adhere to the settings in this dialog."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(ppOptionsOk1) { + text = "Revert"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "210 302"; + extent = "93 23"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "postProcessOptionsDlg.applySettings(); Canvas.popDialog(postProcessOptionsDlg);"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Revert any changes made since opening the dialog"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/core/scripts/client/postFx/postFxManager.gui.cs b/Templates/Empty/game/core/scripts/client/postFx/postFxManager.gui.cs new file mode 100644 index 000000000..4f440684d --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/postFx/postFxManager.gui.cs @@ -0,0 +1,397 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +$PostFXManager::vebose = true; +function postVerbose(%string) +{ + if($PostFXManager::vebose == true) + { + echo(%string); + } +} + +function PostFXManager::onDialogPush( %this ) +{ + //Apply the settings to the controls + postVerbose("% - PostFX Manager - Loading GUI."); + + %this.settingsRefreshAll(); +} + +// :: Controls for the overall postFX manager dialog +function ppOptionsEnable::onAction(%this) +{ + //Disable / Enable all PostFX + + if(ppOptionsEnable.getValue()) + { + %toEnable = true; + } + else + { + %toEnable = false; + } + + PostFXManager.settingsSetEnabled(%toEnable); + +} + +function PostFXManager::getEnableResultFromControl(%this, %control) +{ + %toEnable = -1; + %bTest = %control.getValue(); + if(%bTest == 1) + { + %toEnable = true; + } + else + { + %toEnable = false; + } + + return %toEnable; +} + +function ppOptionsEnableSSAO::onAction(%this) +{ + %toEnable = PostFXManager.getEnableResultFromControl(%this); + PostFXManager.settingsEffectSetEnabled("SSAO", %toEnable); +} + +function ppOptionsEnableHDR::onAction(%this) +{ + %toEnable = PostFXManager.getEnableResultFromControl(%this); + PostFXManager.settingsEffectSetEnabled("HDR", %toEnable); +} + +function ppOptionsEnableLightRays::onAction(%this) +{ + %toEnable = PostFXManager.getEnableResultFromControl(%this); + PostFXManager.settingsEffectSetEnabled("LightRays", %toEnable); +} + +function ppOptionsEnableDOF::onAction(%this) +{ + %toEnable = PostFXManager.getEnableResultFromControl(%this); + PostFXManager.settingsEffectSetEnabled("DOF", %toEnable); +} + +function ppOptionsSavePreset::onClick(%this) +{ + //Stores the current settings into a preset file for loading and use later on +} + +function ppOptionsLoadPreset::onClick(%this) +{ + //Loads and applies the settings from a postfxpreset file +} + + +//Other controls, Quality dropdown +function ppOptionsSSAOQuality::onSelect( %this, %id, %text ) +{ + if(%id > -1 && %id < 3) + { + $SSAOPostFx::quality = %id; + } +} + +//SSAO Slider controls +//General Tab +function ppOptionsSSAOOverallStrength::onMouseDragged(%this) +{ + $SSAOPostFx::overallStrength = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsSSAOBlurDepth::onMouseDragged(%this) +{ + $SSAOPostFx::blurDepthTol = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsSSAOBlurNormal::onMouseDragged(%this) +{ + $SSAOPostFx::blurNormalTol = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +//Near Tab +function ppOptionsSSAONearRadius::onMouseDragged(%this) +{ + $SSAOPostFx::sRadius = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsSSAONearStrength::onMouseDragged(%this) +{ + $SSAOPostFx::sStrength = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsSSAONearDepthMin::onMouseDragged(%this) +{ + $SSAOPostFx::sDepthMin = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsSSAONearDepthMax::onMouseDragged(%this) +{ + $SSAOPostFx::sDepthMax = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsSSAONearToleranceNormal::onMouseDragged(%this) +{ + $SSAOPostFx::sNormalTol = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsSSAONearTolerancePower::onMouseDragged(%this) +{ + $SSAOPostFx::sNormalPow = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +//Far Tab +function ppOptionsSSAOFarRadius::onMouseDragged(%this) +{ + $SSAOPostFx::lRadius = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} +function ppOptionsSSAOFarStrength::onMouseDragged(%this) +{ + $SSAOPostFx::lStrength = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} +function ppOptionsSSAOFarDepthMin::onMouseDragged(%this) +{ + $SSAOPostFx::lDepthMin = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} +function ppOptionsSSAOFarDepthMax::onMouseDragged(%this) +{ + $SSAOPostFx::lDepthMax = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} +function ppOptionsSSAOFarToleranceNormal::onMouseDragged(%this) +{ + $SSAOPostFx::lNormalTol = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} +function ppOptionsSSAOFarTolerancePower::onMouseDragged(%this) +{ + $SSAOPostFx::lNormalPow = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +//HDR Slider Controls +//Brighness tab + +function ppOptionsHDRToneMappingAmount::onMouseDragged(%this) +{ + + $HDRPostFX::enableToneMapping = %this.value; + %this.ToolTip = "value : " @ %this.value; +} + +function ppOptionsHDRKeyValue::onMouseDragged(%this) +{ + $HDRPostFX::keyValue = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsHDRMinLuminance::onMouseDragged(%this) +{ + $HDRPostFX::minLuminace = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsHDRWhiteCutoff::onMouseDragged(%this) +{ + $HDRPostFX::whiteCutoff = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsHDRBrightnessAdaptRate::onMouseDragged(%this) +{ + $HDRPostFX::adaptRate = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +//Blur tab +function ppOptionsHDRBloomBlurBrightPassThreshold::onMouseDragged(%this) +{ + $HDRPostFX::brightPassThreshold = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsHDRBloomBlurMultiplier::onMouseDragged(%this) +{ + $HDRPostFX::gaussMultiplier = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsHDRBloomBlurMean::onMouseDragged(%this) +{ + $HDRPostFX::gaussMean = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsHDRBloomBlurStdDev::onMouseDragged(%this) +{ + $HDRPostFX::gaussStdDev = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsHDRBloom::onAction(%this) +{ + $HDRPostFX::enableBloom = %this.getValue(); +} + +function ppOptionsHDRToneMapping::onAction(%this) +{ + //$HDRPostFX::enableToneMapping = %this.getValue(); +} + +function ppOptionsHDREffectsBlueShift::onAction(%this) +{ + $HDRPostFX::enableBlueShift = %this.getValue(); +} + + +//Controls for color range in blue Shift dialog + +function ppOptionsHDREffectsBlueShiftColorBlend::onAction(%this) +{ + $HDRPostFX::blueShiftColor = %this.PickColor; + %this.ToolTip = "Color Values : " @ %this.PickColor; +} + +function ppOptionsHDREffectsBlueShiftColorBaseColor::onAction(%this) +{ + //This one feeds the one above + ppOptionsHDREffectsBlueShiftColorBlend.baseColor = %this.PickColor; + %this.ToolTip = "Color Values : " @ %this.PickColor; +} + + +//Light rays Slider Controls +function ppOptionsLightRaysBrightScalar::onMouseDragged(%this) +{ + $LightRayPostFX::brightScalar = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsUpdateDOFSettings() +{ + DOFPostEffect.setFocusParams( $DOFPostFx::BlurMin, $DOFPostFx::BlurMax, $DOFPostFx::FocusRangeMin, $DOFPostFx::FocusRangeMax, -($DOFPostFx::BlurCurveNear), $DOFPostFx::BlurCurveFar ); + + DOFPostEffect.setAutoFocus( $DOFPostFx::EnableAutoFocus ); + DOFPostEffect.setFocalDist(0); + + if($PostFXManager::PostFX::EnableDOF) + { + DOFPostEffect.enable(); + } + else + { + DOFPostEffect.disable(); + } +} + +//DOF General Tab +//DOF Toggles +function ppOptionsDOFEnableDOF::onAction(%this) +{ + $PostFXManager::PostFX::EnableDOF = %this.getValue(); + ppOptionsUpdateDOFSettings(); +} + + +function ppOptionsDOFEnableAutoFocus::onAction(%this) +{ + $DOFPostFx::EnableAutoFocus = %this.getValue(); + DOFPostEffect.setAutoFocus( %this.getValue() ); +} + +//DOF AutoFocus Slider controls +function ppOptionsDOFFarBlurMinSlider::onMouseDragged(%this) +{ + $DOFPostFx::BlurMin = %this.value; + ppOptionsUpdateDOFSettings(); +} + +function ppOptionsDOFFarBlurMaxSlider::onMouseDragged(%this) +{ + $DOFPostFx::BlurMax = %this.value; + ppOptionsUpdateDOFSettings(); +} + +function ppOptionsDOFFocusRangeMinSlider::onMouseDragged(%this) +{ + $DOFPostFx::FocusRangeMin = %this.value; + ppOptionsUpdateDOFSettings(); +} + +function ppOptionsDOFFocusRangeMaxSlider::onMouseDragged(%this) +{ + $DOFPostFx::FocusRangeMax = %this.value; + ppOptionsUpdateDOFSettings(); +} + +function ppOptionsDOFBlurCurveNearSlider::onMouseDragged(%this) +{ + $DOFPostFx::BlurCurveNear = %this.value; + ppOptionsUpdateDOFSettings(); +} + +function ppOptionsDOFBlurCurveFarSlider::onMouseDragged(%this) +{ + $DOFPostFx::BlurCurveFar = %this.value; + ppOptionsUpdateDOFSettings(); +} + +function ppOptionsEnableHDRDebug::onAction(%this) +{ + if ( %this.getValue() ) + LuminanceVisPostFX.enable(); + else + LuminanceVisPostFX.disable(); +} + +function ppColorCorrection_selectFile() +{ + %filter = "Image Files (*.png, *.jpg, *.dds, *.bmp, *.gif, *.jng. *.tga)|*.png;*.jpg;*.dds;*.bmp;*.gif;*.jng;*.tga|All Files (*.*)|*.*|"; + getLoadFilename( %filter, "ppColorCorrection_selectFileHandler"); +} + +function ppColorCorrection_selectFileHandler( %filename ) +{ + if ( %filename $= "" || !isFile( %filename ) ) + %filename = "core/scripts/client/postFx/null_color_ramp.png"; + else + %filename = makeRelativePath( %filename, getMainDotCsDir() ); + + $HDRPostFX::colorCorrectionRamp = %filename; + PostFXManager-->ColorCorrectionFileName.Text = %filename; +} \ No newline at end of file diff --git a/Templates/Empty/game/core/scripts/client/postFx/postFxManager.gui.settings.cs b/Templates/Empty/game/core/scripts/client/postFx/postFxManager.gui.settings.cs new file mode 100644 index 000000000..63c1b7424 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/postFx/postFxManager.gui.settings.cs @@ -0,0 +1,384 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +$PostFXManager::defaultPreset = "core/scripts/client/postFx/default.postfxpreset.cs"; + +function PostFXManager::settingsSetEnabled(%this, %bEnablePostFX) +{ + $PostFXManager::PostFX::Enabled = %bEnablePostFX; + + //if to enable the postFX, apply the ones that are enabled + if ( %bEnablePostFX ) + { + //SSAO, HDR, LightRays, DOF + + if ( $PostFXManager::PostFX::EnableSSAO ) + SSAOPostFx.enable(); + else + SSAOPostFx.disable(); + + if ( $PostFXManager::PostFX::EnableHDR ) + HDRPostFX.enable(); + else + HDRPostFX.disable(); + + if ( $PostFXManager::PostFX::EnableLightRays ) + LightRayPostFX.enable(); + else + LightRayPostFX.disable(); + + if ( $PostFXManager::PostFX::EnableDOF ) + DOFPostEffect.enable(); + else + DOFPostEffect.disable(); + + postVerbose("% - PostFX Manager - PostFX enabled"); + } + else + { + //Disable all postFX + + SSAOPostFx.disable(); + HDRPostFX.disable(); + LightRayPostFX.disable(); + DOFPostEffect.disable(); + + postVerbose("% - PostFX Manager - PostFX disabled"); + } +} + +function PostFXManager::settingsEffectSetEnabled(%this, %sName, %bEnable) +{ + %postEffect = 0; + + //Determine the postFX to enable, and apply the boolean + if(%sName $= "SSAO") + { + %postEffect = SSAOPostFx; + $PostFXManager::PostFX::EnableSSAO = %bEnable; + //$pref::PostFX::SSAO::Enabled = %bEnable; + } + else if(%sName $= "HDR") + { + %postEffect = HDRPostFX; + $PostFXManager::PostFX::EnableHDR = %bEnable; + //$pref::PostFX::HDR::Enabled = %bEnable; + } + else if(%sName $= "LightRays") + { + %postEffect = LightRayPostFX; + $PostFXManager::PostFX::EnableLightRays = %bEnable; + //$pref::PostFX::LightRays::Enabled = %bEnable; + } + else if(%sName $= "DOF") + { + %postEffect = DOFPostEffect; + $PostFXManager::PostFX::EnableDOF = %bEnable; + //$pref::PostFX::DOF::Enabled = %bEnable; + } + + // Apply the change + if ( %bEnable == true ) + { + %postEffect.enable(); + postVerbose("% - PostFX Manager - " @ %sName @ " enabled"); + } + else + { + %postEffect.disable(); + postVerbose("% - PostFX Manager - " @ %sName @ " disabled"); + } +} + +function PostFXManager::settingsRefreshSSAO(%this) +{ + //Apply the enabled flag + ppOptionsEnableSSAO.setValue($PostFXManager::PostFX::EnableSSAO); + + //Add the items we need to display + ppOptionsSSAOQuality.clear(); + ppOptionsSSAOQuality.add("Low", 0); + ppOptionsSSAOQuality.add("Medium", 1); + ppOptionsSSAOQuality.add("High", 2); + + //Set the selected, after adding the items! + ppOptionsSSAOQuality.setSelected($SSAOPostFx::quality); + + //SSAO - Set the values of the sliders, General Tab + ppOptionsSSAOOverallStrength.setValue($SSAOPostFx::overallStrength); + ppOptionsSSAOBlurDepth.setValue($SSAOPostFx::blurDepthTol); + ppOptionsSSAOBlurNormal.setValue($SSAOPostFx::blurNormalTol); + + //SSAO - Set the values for the near tab + ppOptionsSSAONearDepthMax.setValue($SSAOPostFx::sDepthMax); + ppOptionsSSAONearDepthMin.setValue($SSAOPostFx::sDepthMin); + ppOptionsSSAONearRadius.setValue($SSAOPostFx::sRadius); + ppOptionsSSAONearStrength.setValue($SSAOPostFx::sStrength); + ppOptionsSSAONearToleranceNormal.setValue($SSAOPostFx::sNormalTol); + ppOptionsSSAONearTolerancePower.setValue($SSAOPostFx::sNormalPow); + + //SSAO - Set the values for the far tab + ppOptionsSSAOFarDepthMax.setValue($SSAOPostFx::lDepthMax); + ppOptionsSSAOFarDepthMin.setValue($SSAOPostFx::lDepthMin); + ppOptionsSSAOFarRadius.setValue($SSAOPostFx::lRadius); + ppOptionsSSAOFarStrength.setValue($SSAOPostFx::lStrength); + ppOptionsSSAOFarToleranceNormal.setValue($SSAOPostFx::lNormalTol); + ppOptionsSSAOFarTolerancePower.setValue($SSAOPostFx::lNormalPow); +} + +function PostFXManager::settingsRefreshHDR(%this) +{ + //Apply the enabled flag + ppOptionsEnableHDR.setValue($PostFXManager::PostFX::EnableHDR); + + ppOptionsHDRBloom.setValue($HDRPostFX::enableBloom); + ppOptionsHDRBloomBlurBrightPassThreshold.setValue($HDRPostFX::brightPassThreshold); + ppOptionsHDRBloomBlurMean.setValue($HDRPostFX::gaussMean); + ppOptionsHDRBloomBlurMultiplier.setValue($HDRPostFX::gaussMultiplier); + ppOptionsHDRBloomBlurStdDev.setValue($HDRPostFX::gaussStdDev); + ppOptionsHDRBrightnessAdaptRate.setValue($HDRPostFX::adaptRate); + ppOptionsHDREffectsBlueShift.setValue($HDRPostFX::enableBlueShift); + ppOptionsHDREffectsBlueShiftColor.BaseColor = $HDRPostFX::blueShiftColor; + ppOptionsHDREffectsBlueShiftColor.PickColor = $HDRPostFX::blueShiftColor; + ppOptionsHDRKeyValue.setValue($HDRPostFX::keyValue); + ppOptionsHDRMinLuminance.setValue($HDRPostFX::minLuminace); + ppOptionsHDRToneMapping.setValue($HDRPostFX::enableToneMapping); + ppOptionsHDRToneMappingAmount.setValue($HDRPostFX::enableToneMapping); + ppOptionsHDRWhiteCutoff.setValue($HDRPostFX::whiteCutoff); + + %this-->ColorCorrectionFileName.Text = $HDRPostFX::colorCorrectionRamp; +} + +function PostFXManager::settingsRefreshLightrays(%this) +{ + //Apply the enabled flag + ppOptionsEnableLightRays.setValue($PostFXManager::PostFX::EnableLightRays); + + ppOptionsLightRaysBrightScalar.setValue($LightRayPostFX::brightScalar); +} + +function PostFXManager::settingsRefreshDOF(%this) +{ + //Apply the enabled flag + ppOptionsEnableDOF.setValue($PostFXManager::PostFX::EnableDOF); + + + //ppOptionsDOFEnableDOF.setValue($PostFXManager::PostFX::EnableDOF); + ppOptionsDOFEnableAutoFocus.setValue($DOFPostFx::EnableAutoFocus); + + ppOptionsDOFFarBlurMinSlider.setValue($DOFPostFx::BlurMin); + ppOptionsDOFFarBlurMaxSlider.setValue($DOFPostFx::BlurMax); + + ppOptionsDOFFocusRangeMinSlider.setValue($DOFPostFx::FocusRangeMin); + ppOptionsDOFFocusRangeMaxSlider.setValue($DOFPostFx::FocusRangeMax); + + ppOptionsDOFBlurCurveNearSlider.setValue($DOFPostFx::BlurCurveNear); + ppOptionsDOFBlurCurveFarSlider.setValue($DOFPostFx::BlurCurveFar); + +} + +function PostFXManager::settingsRefreshAll(%this) +{ + $PostFXManager::PostFX::Enabled = $pref::enablePostEffects; + $PostFXManager::PostFX::EnableSSAO = SSAOPostFx.isEnabled(); + $PostFXManager::PostFX::EnableHDR = HDRPostFX.isEnabled(); + $PostFXManager::PostFX::EnableLightRays = LightRayPostFX.isEnabled(); + $PostFXManager::PostFX::EnableDOF = DOFPostEffect.isEnabled(); + + //For all the postFX here, apply the active settings in the system + //to the gui controls. + + %this.settingsRefreshSSAO(); + %this.settingsRefreshHDR(); + %this.settingsRefreshLightrays(); + %this.settingsRefreshDOF(); + + ppOptionsEnable.setValue($PostFXManager::PostFX::Enabled); + + postVerbose("% - PostFX Manager - GUI values updated."); +} + +function PostFXManager::settingsApplyFromPreset(%this) +{ + postVerbose("% - PostFX Manager - Applying from preset"); + + //SSAO Settings + $SSAOPostFx::blurDepthTol = $PostFXManager::Settings::SSAO::blurDepthTol; + $SSAOPostFx::blurNormalTol = $PostFXManager::Settings::SSAO::blurNormalTol; + $SSAOPostFx::lDepthMax = $PostFXManager::Settings::SSAO::lDepthMax; + $SSAOPostFx::lDepthMin = $PostFXManager::Settings::SSAO::lDepthMin; + $SSAOPostFx::lDepthPow = $PostFXManager::Settings::SSAO::lDepthPow; + $SSAOPostFx::lNormalPow = $PostFXManager::Settings::SSAO::lNormalPow; + $SSAOPostFx::lNormalTol = $PostFXManager::Settings::SSAO::lNormalTol; + $SSAOPostFx::lRadius = $PostFXManager::Settings::SSAO::lRadius; + $SSAOPostFx::lStrength = $PostFXManager::Settings::SSAO::lStrength; + $SSAOPostFx::overallStrength = $PostFXManager::Settings::SSAO::overallStrength; + $SSAOPostFx::quality = $PostFXManager::Settings::SSAO::quality; + $SSAOPostFx::sDepthMax = $PostFXManager::Settings::SSAO::sDepthMax; + $SSAOPostFx::sDepthMin = $PostFXManager::Settings::SSAO::sDepthMin; + $SSAOPostFx::sDepthPow = $PostFXManager::Settings::SSAO::sDepthPow; + $SSAOPostFx::sNormalPow = $PostFXManager::Settings::SSAO::sNormalPow; + $SSAOPostFx::sNormalTol = $PostFXManager::Settings::SSAO::sNormalTol; + $SSAOPostFx::sRadius = $PostFXManager::Settings::SSAO::sRadius; + $SSAOPostFx::sStrength = $PostFXManager::Settings::SSAO::sStrength; + + //HDR settings + $HDRPostFX::adaptRate = $PostFXManager::Settings::HDR::adaptRate; + $HDRPostFX::blueShiftColor = $PostFXManager::Settings::HDR::blueShiftColor; + $HDRPostFX::brightPassThreshold = $PostFXManager::Settings::HDR::brightPassThreshold; + $HDRPostFX::enableBloom = $PostFXManager::Settings::HDR::enableBloom; + $HDRPostFX::enableBlueShift = $PostFXManager::Settings::HDR::enableBlueShift; + $HDRPostFX::enableToneMapping = $PostFXManager::Settings::HDR::enableToneMapping; + $HDRPostFX::gaussMean = $PostFXManager::Settings::HDR::gaussMean; + $HDRPostFX::gaussMultiplier = $PostFXManager::Settings::HDR::gaussMultiplier; + $HDRPostFX::gaussStdDev = $PostFXManager::Settings::HDR::gaussStdDev; + $HDRPostFX::keyValue = $PostFXManager::Settings::HDR::keyValue; + $HDRPostFX::minLuminace = $PostFXManager::Settings::HDR::minLuminace; + $HDRPostFX::whiteCutoff = $PostFXManager::Settings::HDR::whiteCutoff; + $HDRPostFX::colorCorrectionRamp = $PostFXManager::Settings::ColorCorrectionRamp; + + //Light rays settings + $LightRayPostFX::brightScalar = $PostFXManager::Settings::LightRays::brightScalar; + + //DOF settings + $DOFPostFx::EnableAutoFocus = $PostFXManager::Settings::DOF::EnableAutoFocus; + $DOFPostFx::BlurMin = $PostFXManager::Settings::DOF::BlurMin; + $DOFPostFx::BlurMax = $PostFXManager::Settings::DOF::BlurMax; + $DOFPostFx::FocusRangeMin = $PostFXManager::Settings::DOF::FocusRangeMin; + $DOFPostFx::FocusRangeMax = $PostFXManager::Settings::DOF::FocusRangeMax; + $DOFPostFx::BlurCurveNear = $PostFXManager::Settings::DOF::BlurCurveNear; + $DOFPostFx::BlurCurveFar = $PostFXManager::Settings::DOF::BlurCurveFar; + + if ( $PostFXManager::forceEnableFromPresets ) + { + $PostFXManager::PostFX::Enabled = $PostFXManager::Settings::EnablePostFX; + $PostFXManager::PostFX::EnableDOF = $PostFXManager::Settings::EnableDOF; + $PostFXManager::PostFX::EnableLightRays = $PostFXManager::Settings::EnableLightRays; + $PostFXManager::PostFX::EnableHDR = $PostFXManager::Settings::EnableHDR; + $PostFXManager::PostFX::EnableSSAO = $PostFXManager::Settings::EnabledSSAO; + + %this.settingsSetEnabled( true ); + } + + //make sure we apply the correct settings to the DOF + ppOptionsUpdateDOFSettings(); + + // Update the actual GUI controls if its awake ( otherwise it will when opened ). + if ( PostFXManager.isAwake() ) + %this.settingsRefreshAll(); +} + +function PostFXManager::settingsApplySSAO(%this) +{ + $PostFXManager::Settings::SSAO::blurDepthTol = $SSAOPostFx::blurDepthTol; + $PostFXManager::Settings::SSAO::blurNormalTol = $SSAOPostFx::blurNormalTol; + $PostFXManager::Settings::SSAO::lDepthMax = $SSAOPostFx::lDepthMax; + $PostFXManager::Settings::SSAO::lDepthMin = $SSAOPostFx::lDepthMin; + $PostFXManager::Settings::SSAO::lDepthPow = $SSAOPostFx::lDepthPow; + $PostFXManager::Settings::SSAO::lNormalPow = $SSAOPostFx::lNormalPow; + $PostFXManager::Settings::SSAO::lNormalTol = $SSAOPostFx::lNormalTol; + $PostFXManager::Settings::SSAO::lRadius = $SSAOPostFx::lRadius; + $PostFXManager::Settings::SSAO::lStrength = $SSAOPostFx::lStrength; + $PostFXManager::Settings::SSAO::overallStrength = $SSAOPostFx::overallStrength; + $PostFXManager::Settings::SSAO::quality = $SSAOPostFx::quality; + $PostFXManager::Settings::SSAO::sDepthMax = $SSAOPostFx::sDepthMax; + $PostFXManager::Settings::SSAO::sDepthMin = $SSAOPostFx::sDepthMin; + $PostFXManager::Settings::SSAO::sDepthPow = $SSAOPostFx::sDepthPow; + $PostFXManager::Settings::SSAO::sNormalPow = $SSAOPostFx::sNormalPow; + $PostFXManager::Settings::SSAO::sNormalTol = $SSAOPostFx::sNormalTol; + $PostFXManager::Settings::SSAO::sRadius = $SSAOPostFx::sRadius; + $PostFXManager::Settings::SSAO::sStrength = $SSAOPostFx::sStrength; + + postVerbose("% - PostFX Manager - Settings Saved - SSAO"); + +} + +function PostFXManager::settingsApplyHDR(%this) +{ + $PostFXManager::Settings::HDR::adaptRate = $HDRPostFX::adaptRate; + $PostFXManager::Settings::HDR::blueShiftColor = $HDRPostFX::blueShiftColor; + $PostFXManager::Settings::HDR::brightPassThreshold = $HDRPostFX::brightPassThreshold; + $PostFXManager::Settings::HDR::enableBloom = $HDRPostFX::enableBloom; + $PostFXManager::Settings::HDR::enableBlueShift = $HDRPostFX::enableBlueShift; + $PostFXManager::Settings::HDR::enableToneMapping = $HDRPostFX::enableToneMapping; + $PostFXManager::Settings::HDR::gaussMean = $HDRPostFX::gaussMean; + $PostFXManager::Settings::HDR::gaussMultiplier = $HDRPostFX::gaussMultiplier; + $PostFXManager::Settings::HDR::gaussStdDev = $HDRPostFX::gaussStdDev; + $PostFXManager::Settings::HDR::keyValue = $HDRPostFX::keyValue; + $PostFXManager::Settings::HDR::minLuminace = $HDRPostFX::minLuminace; + $PostFXManager::Settings::HDR::whiteCutoff = $HDRPostFX::whiteCutoff; + $PostFXManager::Settings::ColorCorrectionRamp = $HDRPostFX::colorCorrectionRamp; + + postVerbose("% - PostFX Manager - Settings Saved - HDR"); +} + +function PostFXManager::settingsApplyLightRays(%this) +{ + $PostFXManager::Settings::LightRays::brightScalar = $LightRayPostFX::brightScalar; + + postVerbose("% - PostFX Manager - Settings Saved - Light Rays"); + +} + +function PostFXManager::settingsApplyDOF(%this) +{ + $PostFXManager::Settings::DOF::EnableAutoFocus = $DOFPostFx::EnableAutoFocus; + $PostFXManager::Settings::DOF::BlurMin = $DOFPostFx::BlurMin; + $PostFXManager::Settings::DOF::BlurMax = $DOFPostFx::BlurMax; + $PostFXManager::Settings::DOF::FocusRangeMin = $DOFPostFx::FocusRangeMin; + $PostFXManager::Settings::DOF::FocusRangeMax = $DOFPostFx::FocusRangeMax; + $PostFXManager::Settings::DOF::BlurCurveNear = $DOFPostFx::BlurCurveNear; + $PostFXManager::Settings::DOF::BlurCurveFar = $DOFPostFx::BlurCurveFar; + + postVerbose("% - PostFX Manager - Settings Saved - DOF"); + +} + +function PostFXManager::settingsApplyAll(%this, %sFrom) +{ + // Apply settings which control if effects are on/off altogether. + $PostFXManager::Settings::EnablePostFX = $PostFXManager::PostFX::Enabled; + $PostFXManager::Settings::EnableDOF = $PostFXManager::PostFX::EnableDOF; + $PostFXManager::Settings::EnableLightRays = $PostFXManager::PostFX::EnableLightRays; + $PostFXManager::Settings::EnableHDR = $PostFXManager::PostFX::EnableHDR; + $PostFXManager::Settings::EnabledSSAO = $PostFXManager::PostFX::EnableSSAO; + + // Apply settings should save the values in the system to the + // the preset structure ($PostFXManager::Settings::*) + + // SSAO Settings + %this.settingsApplySSAO(); + // HDR settings + %this.settingsApplyHDR(); + // Light rays settings + %this.settingsApplyLightRays(); + // DOF + %this.settingsApplyDOF(); + + postVerbose("% - PostFX Manager - All Settings applied to $PostFXManager::Settings"); +} + +function PostFXManager::settingsApplyDefaultPreset(%this) +{ + PostFXManager::loadPresetHandler($PostFXManager::defaultPreset); +} + diff --git a/Templates/Empty/game/core/scripts/client/postFx/postFxManager.persistance.cs b/Templates/Empty/game/core/scripts/client/postFx/postFxManager.persistance.cs new file mode 100644 index 000000000..31fec95f1 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/postFx/postFxManager.persistance.cs @@ -0,0 +1,79 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +// Used to name the saved files. +$PostFXManager::fileExtension = ".postfxpreset.cs"; + +// The filter string for file open/save dialogs. +$PostFXManager::fileFilter = "Post Effect Presets|*.postfxpreset.cs"; + +// Enable / disable PostFX when loading presets or just apply the settings? +$PostFXManager::forceEnableFromPresets = true; + +//Load a preset file from the disk, and apply the settings to the +//controls. If bApplySettings is true - the actual values in the engine +//will be changed to reflect the settings from the file. +function PostFXManager::loadPresetFile() +{ + //Show the dialog and set the flag + getLoadFilename($PostFXManager::fileFilter, "PostFXManager::loadPresetHandler"); +} + +function PostFXManager::loadPresetHandler( %filename ) +{ + //Check the validity of the file + if ( isScriptFile( %filename ) ) + { + %filename = expandFilename(%filename); + postVerbose("% - PostFX Manager - Executing " @ %filename); + exec(%filename); + + PostFXManager.settingsApplyFromPreset(); + } +} + +//Save a preset file to the specified file. The extension used +//is specified by $PostFXManager::fileExtension for on the fly +//name changes to the extension used. + +function PostFXManager::savePresetFile(%this) +{ + %defaultFile = filePath($Client::MissionFile) @ "/" @ fileBase($Client::MissionFile); + getSaveFilename($PostFXManager::fileFilter, "PostFXManager::savePresetHandler", %defaultFile); +} + +//Called from the PostFXManager::savePresetFile() function +function PostFXManager::savePresetHandler( %filename ) +{ + %filename = makeRelativePath( %filename, getMainDotCsDir() ); + if(strStr(%filename, ".") == -1) + %filename = %filename @ $PostFXManager::fileExtension; + + //Apply the current settings to the preset + PostFXManager.settingsApplyAll(); + + export("$PostFXManager::Settings::*", %filename, false); + + postVerbose("% - PostFX Manager - Save complete. Preset saved at : " @ %filename); +} + diff --git a/Templates/Empty/game/core/scripts/client/postFx/ssao.cs b/Templates/Empty/game/core/scripts/client/postFx/ssao.cs new file mode 100644 index 000000000..69977f352 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/postFx/ssao.cs @@ -0,0 +1,282 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +/// +$SSAOPostFx::overallStrength = 2.0; + +// TODO: Add small/large param docs. + +// The small radius SSAO settings. +$SSAOPostFx::sRadius = 0.1; +$SSAOPostFx::sStrength = 6.0; +$SSAOPostFx::sDepthMin = 0.1; +$SSAOPostFx::sDepthMax = 1.0; +$SSAOPostFx::sDepthPow = 1.0; +$SSAOPostFx::sNormalTol = 0.0; +$SSAOPostFx::sNormalPow = 1.0; + +// The large radius SSAO settings. +$SSAOPostFx::lRadius = 1.0; +$SSAOPostFx::lStrength = 10.0; +$SSAOPostFx::lDepthMin = 0.2; +$SSAOPostFx::lDepthMax = 2.0; +$SSAOPostFx::lDepthPow = 0.2; +$SSAOPostFx::lNormalTol = -0.5; +$SSAOPostFx::lNormalPow = 2.0; + +/// Valid values: 0, 1, 2 +$SSAOPostFx::quality = 0; + +/// +$SSAOPostFx::blurDepthTol = 0.001; + +/// +$SSAOPostFx::blurNormalTol = 0.95; + +/// +$SSAOPostFx::targetScale = "0.5 0.5"; + + +function SSAOPostFx::onAdd( %this ) +{ + %this.wasVis = "Uninitialized"; + %this.quality = "Uninitialized"; +} + +function SSAOPostFx::preProcess( %this ) +{ + if ( $SSAOPostFx::quality !$= %this.quality ) + { + %this.quality = mClamp( mRound( $SSAOPostFx::quality ), 0, 2 ); + + %this.setShaderMacro( "QUALITY", %this.quality ); + } + + %this.targetScale = $SSAOPostFx::targetScale; +} + +function SSAOPostFx::setShaderConsts( %this ) +{ + %this.setShaderConst( "$overallStrength", $SSAOPostFx::overallStrength ); + + // Abbreviate is s-small l-large. + + %this.setShaderConst( "$sRadius", $SSAOPostFx::sRadius ); + %this.setShaderConst( "$sStrength", $SSAOPostFx::sStrength ); + %this.setShaderConst( "$sDepthMin", $SSAOPostFx::sDepthMin ); + %this.setShaderConst( "$sDepthMax", $SSAOPostFx::sDepthMax ); + %this.setShaderConst( "$sDepthPow", $SSAOPostFx::sDepthPow ); + %this.setShaderConst( "$sNormalTol", $SSAOPostFx::sNormalTol ); + %this.setShaderConst( "$sNormalPow", $SSAOPostFx::sNormalPow ); + + %this.setShaderConst( "$lRadius", $SSAOPostFx::lRadius ); + %this.setShaderConst( "$lStrength", $SSAOPostFx::lStrength ); + %this.setShaderConst( "$lDepthMin", $SSAOPostFx::lDepthMin ); + %this.setShaderConst( "$lDepthMax", $SSAOPostFx::lDepthMax ); + %this.setShaderConst( "$lDepthPow", $SSAOPostFx::lDepthPow ); + %this.setShaderConst( "$lNormalTol", $SSAOPostFx::lNormalTol ); + %this.setShaderConst( "$lNormalPow", $SSAOPostFx::lNormalPow ); + + %blur = %this->blurY; + %blur.setShaderConst( "$blurDepthTol", $SSAOPostFx::blurDepthTol ); + %blur.setShaderConst( "$blurNormalTol", $SSAOPostFx::blurNormalTol ); + + %blur = %this->blurX; + %blur.setShaderConst( "$blurDepthTol", $SSAOPostFx::blurDepthTol ); + %blur.setShaderConst( "$blurNormalTol", $SSAOPostFx::blurNormalTol ); + + %blur = %this->blurY2; + %blur.setShaderConst( "$blurDepthTol", $SSAOPostFx::blurDepthTol ); + %blur.setShaderConst( "$blurNormalTol", $SSAOPostFx::blurNormalTol ); + + %blur = %this->blurX2; + %blur.setShaderConst( "$blurDepthTol", $SSAOPostFx::blurDepthTol ); + %blur.setShaderConst( "$blurNormalTol", $SSAOPostFx::blurNormalTol ); +} + +function SSAOPostFx::onEnabled( %this ) +{ + // This tells the AL shaders to reload and sample + // from our #ssaoMask texture target. + $AL::UseSSAOMask = true; + + return true; +} + +function SSAOPostFx::onDisabled( %this ) +{ + $AL::UseSSAOMask = false; +} + + +//----------------------------------------------------------------------------- +// GFXStateBlockData / ShaderData +//----------------------------------------------------------------------------- + +singleton GFXStateBlockData( SSAOStateBlock : PFX_DefaultStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; + samplerStates[1] = SamplerWrapLinear; + samplerStates[2] = SamplerClampPoint; +}; + +singleton GFXStateBlockData( SSAOBlurStateBlock : PFX_DefaultStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; + samplerStates[1] = SamplerClampPoint; +}; + +singleton ShaderData( SSAOShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/ssao/SSAO_P.hlsl"; + pixVersion = 3.0; +}; + +singleton ShaderData( SSAOBlurYShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/ssao/SSAO_Blur_V.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/ssao/SSAO_Blur_P.hlsl"; + pixVersion = 3.0; + + defines = "BLUR_DIR=float2(0.0,1.0)"; +}; + +singleton ShaderData( SSAOBlurXShader : SSAOBlurYShader ) +{ + defines = "BLUR_DIR=float2(1.0,0.0)"; +}; + +//----------------------------------------------------------------------------- +// PostEffects +//----------------------------------------------------------------------------- + +singleton PostEffect( SSAOPostFx ) +{ + allowReflectPass = false; + + renderTime = "PFXBeforeBin"; + renderBin = "AL_LightBinMgr"; + renderPriority = 10; + + shader = SSAOShader; + stateBlock = SSAOStateBlock; + + texture[0] = "#prepass"; + texture[1] = "noise.png"; + texture[2] = "#ssao_pow_table"; + + target = "$outTex"; + targetScale = "0.5 0.5"; + + singleton PostEffect() + { + internalName = "blurY"; + + shader = SSAOBlurYShader; + stateBlock = SSAOBlurStateBlock; + + texture[0] = "$inTex"; + texture[1] = "#prepass"; + + target = "$outTex"; + }; + + singleton PostEffect() + { + internalName = "blurX"; + + shader = SSAOBlurXShader; + stateBlock = SSAOBlurStateBlock; + + texture[0] = "$inTex"; + texture[1] = "#prepass"; + + target = "$outTex"; + }; + + singleton PostEffect() + { + internalName = "blurY2"; + + shader = SSAOBlurYShader; + stateBlock = SSAOBlurStateBlock; + + texture[0] = "$inTex"; + texture[1] = "#prepass"; + + target = "$outTex"; + }; + + singleton PostEffect() + { + internalName = "blurX2"; + + shader = SSAOBlurXShader; + stateBlock = SSAOBlurStateBlock; + + texture[0] = "$inTex"; + texture[1] = "#prepass"; + + // We write to a mask texture which is then + // read by the lighting shaders to mask ambient. + target = "#ssaoMask"; + }; +}; + + +/// Just here for debug visualization of the +/// SSAO mask texture used during lighting. +singleton PostEffect( SSAOVizPostFx ) +{ + allowReflectPass = false; + + shader = PFX_PassthruShader; + stateBlock = PFX_DefaultStateBlock; + + texture[0] = "#ssaoMask"; + + target = "$backbuffer"; +}; + +singleton ShaderData( SSAOPowTableShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/ssao/SSAO_PowerTable_V.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/ssao/SSAO_PowerTable_P.hlsl"; + pixVersion = 2.0; +}; + +singleton PostEffect( SSAOPowTablePostFx ) +{ + shader = SSAOPowTableShader; + stateBlock = PFX_DefaultStateBlock; + + renderTime = "PFXTexGenOnDemand"; + + target = "#ssao_pow_table"; + + targetFormat = "GFXFormatR16F"; + targetSize = "256 1"; +}; \ No newline at end of file diff --git a/Templates/Empty/game/core/scripts/client/recordings.cs b/Templates/Empty/game/core/scripts/client/recordings.cs new file mode 100644 index 000000000..ad03d3dc4 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/recordings.cs @@ -0,0 +1,143 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// RecordingsGui is the main TSControl through which the a demo game recording +// is viewed. +//----------------------------------------------------------------------------- + +function recordingsDlg::onWake() +{ + RecordingsDlgList.clear(); + %i = 0; + %filespec = $currentMod @ "/recordings/*.rec"; + echo(%filespec); + for(%file = findFirstFile(%filespec); %file !$= ""; %file = findNextFile(%filespec)) + RecordingsDlgList.addRow(%i++, fileBase(%file)); + RecordingsDlgList.sort(0); + RecordingsDlgList.setSelectedRow(0); + RecordingsDlgList.scrollVisible(0); +} + +function StartSelectedDemo() +{ + // first unit is filename + %sel = RecordingsDlgList.getSelectedId(); + %rowText = RecordingsDlgList.getRowTextById(%sel); + + %file = $currentMod @ "/recordings/" @ getField(%rowText, 0) @ ".rec"; + + new GameConnection(ServerConnection); + RootGroup.add(ServerConnection); + + // Start up important client-side stuff, such as the group + // for particle emitters. This doesn't get launched during a demo + // as we short circuit the whole mission loading sequence. + clientStartMission(); + + if(ServerConnection.playDemo(%file)) + { + Canvas.setContent(PlayGui); + Canvas.popDialog(RecordingsDlg); + ServerConnection.prepDemoPlayback(); + } + else + { + MessageBoxOK("Playback Failed", "Demo playback failed for file '" @ %file @ "'."); + if (isObject(ServerConnection)) { + ServerConnection.delete(); + } + } +} + +function startDemoRecord() +{ + // make sure that current recording stream is stopped + ServerConnection.stopRecording(); + + // make sure we aren't playing a demo + if(ServerConnection.isDemoPlaying()) + return; + + for(%i = 0; %i < 1000; %i++) + { + %num = %i; + if(%num < 10) + %num = "0" @ %num; + if(%num < 100) + %num = "0" @ %num; + + %file = $currentMod @ "/recordings/demo" @ %num @ ".rec"; + if(!isfile(%file)) + break; + } + if(%i == 1000) + return; + + $DemoFileName = %file; + + ChatHud.AddLine( "\c4Recording to file [\c2" @ $DemoFileName @ "\cr]."); + + ServerConnection.prepDemoRecord(); + ServerConnection.startRecording($DemoFileName); + + // make sure start worked + if(!ServerConnection.isDemoRecording()) + { + deleteFile($DemoFileName); + ChatHud.AddLine( "\c3 *** Failed to record to file [\c2" @ $DemoFileName @ "\cr]."); + $DemoFileName = ""; + } +} + +function stopDemoRecord() +{ + // make sure we are recording + if(ServerConnection.isDemoRecording()) + { + ChatHud.AddLine( "\c4Recording file [\c2" @ $DemoFileName @ "\cr] finished."); + ServerConnection.stopRecording(); + } +} + +function demoPlaybackComplete() +{ + disconnect(); + + // Clean up important client-side stuff, such as the group + // for particle emitters and the decal manager. This doesn't get + // launched during a demo as we short circuit the whole mission + // handling functionality. + clientEndMission(); + + if ( $UseUnifiedShell ) + { + if (isObject( UnifiedMainMenuGui )) + Canvas.setContent( UnifiedMainMenuGui ); + else if (isObject( MainMenuGui )) + Canvas.setContent( MainMenuGui ); + } + else if (isObject( MainMenuGui )) + Canvas.setContent( MainMenuGui ); + + Canvas.pushDialog(RecordingsDlg); +} diff --git a/Templates/Empty/game/core/scripts/client/renderManager.cs b/Templates/Empty/game/core/scripts/client/renderManager.cs new file mode 100644 index 000000000..672451f2d --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/renderManager.cs @@ -0,0 +1,111 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function initRenderManager() +{ + assert( !isObject( DiffuseRenderPassManager ), "initRenderManager() - DiffuseRenderPassManager already initialized!" ); + + new RenderPassManager( DiffuseRenderPassManager ); + + // This token, and the associated render managers, ensure that driver MSAA + // does not get used for Advanced Lighting renders. The 'AL_FormatResolve' + // PostEffect copies the result to the backbuffer. + new RenderFormatToken(AL_FormatToken) + { + enabled = "false"; + + format = "GFXFormatR8G8B8A8"; + depthFormat = "GFXFormatD24S8"; + aaLevel = 0; // -1 = match backbuffer + + // The contents of the back buffer before this format token is executed + // is provided in $inTex + copyEffect = "AL_FormatCopy"; + + // The contents of the render target created by this format token is + // provided in $inTex + resolveEffect = "AL_FormatCopy"; + }; + DiffuseRenderPassManager.addManager( new RenderPassStateBin() { renderOrder = 0.001; stateToken = AL_FormatToken; } ); + + // We really need to fix the sky to render after all the + // meshes... but that causes issues in reflections. + DiffuseRenderPassManager.addManager( new RenderObjectMgr() { bintype = "Sky"; renderOrder = 0.1; processAddOrder = 0.1; } ); + + //DiffuseRenderPassManager.addManager( new RenderVistaMgr() { bintype = "Vista"; renderOrder = 0.15; processAddOrder = 0.15; } ); + + DiffuseRenderPassManager.addManager( new RenderObjectMgr() { bintype = "Begin"; renderOrder = 0.2; processAddOrder = 0.2; } ); + // Normal mesh rendering. + DiffuseRenderPassManager.addManager( new RenderMeshMgr() { bintype = "Interior"; renderOrder = 0.3; processAddOrder = 0.3; } ); + DiffuseRenderPassManager.addManager( new RenderTerrainMgr() { renderOrder = 0.4; processAddOrder = 0.4; } ); + DiffuseRenderPassManager.addManager( new RenderMeshMgr() { bintype = "Mesh"; renderOrder = 0.5; processAddOrder = 0.5; } ); + DiffuseRenderPassManager.addManager( new RenderImposterMgr() { renderOrder = 0.56; processAddOrder = 0.56; } ); + DiffuseRenderPassManager.addManager( new RenderObjectMgr() { bintype = "Object"; renderOrder = 0.6; processAddOrder = 0.6; } ); + + DiffuseRenderPassManager.addManager( new RenderObjectMgr() { bintype = "Shadow"; renderOrder = 0.7; processAddOrder = 0.7; } ); + DiffuseRenderPassManager.addManager( new RenderMeshMgr() { bintype = "Decal"; renderOrder = 0.8; processAddOrder = 0.8; } ); + DiffuseRenderPassManager.addManager( new RenderOcclusionMgr() { bintype = "Occluder"; renderOrder = 0.9; processAddOrder = 0.9; } ); + + // We now render translucent objects that should handle + // their own fogging and lighting. + + // Note that the fog effect is triggered before this bin. + DiffuseRenderPassManager.addManager( new RenderObjectMgr(ObjTranslucentBin) { bintype = "ObjectTranslucent"; renderOrder = 1.0; processAddOrder = 1.0; } ); + + DiffuseRenderPassManager.addManager( new RenderObjectMgr() { bintype = "Water"; renderOrder = 1.2; processAddOrder = 1.2; } ); + DiffuseRenderPassManager.addManager( new RenderObjectMgr() { bintype = "Foliage"; renderOrder = 1.3; processAddOrder = 1.3; } ); + DiffuseRenderPassManager.addManager( new RenderParticleMgr() { renderOrder = 1.35; processAddOrder = 1.35; } ); + DiffuseRenderPassManager.addManager( new RenderTranslucentMgr() { renderOrder = 1.4; processAddOrder = 1.4; } ); + + // Note that the GlowPostFx is triggered after this bin. + DiffuseRenderPassManager.addManager( new RenderGlowMgr(GlowBin) { renderOrder = 1.5; processAddOrder = 1.5; } ); + + // We render any editor stuff from this bin. Note that the HDR is + // completed before this bin to keep editor elements from tone mapping. + DiffuseRenderPassManager.addManager( new RenderObjectMgr(EditorBin) { bintype = "Editor"; renderOrder = 1.6; processAddOrder = 1.6; } ); + + // Resolve format change token last. + DiffuseRenderPassManager.addManager( new RenderPassStateBin() { renderOrder = 1.7; stateToken = AL_FormatToken; } ); +} + +/// This post effect is used to copy data from the non-MSAA back-buffer to the +/// device back buffer (which could be MSAA). It must be declared here so that +/// it is initialized when 'AL_FormatToken' is initialzed. +singleton GFXStateBlockData( AL_FormatTokenState : PFX_DefaultStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; +}; + +singleton PostEffect( AL_FormatCopy ) +{ + // This PostEffect is used by 'AL_FormatToken' directly. It is never added to + // the PostEffectManager. Do not call enable() on it. + isEnabled = false; + allowReflectPass = true; + + shader = PFX_PassthruShader; + stateBlock = AL_FormatTokenState; + + texture[0] = "$inTex"; + target = "$backbuffer"; +}; diff --git a/Templates/Empty/game/core/scripts/client/scatterSky.cs b/Templates/Empty/game/core/scripts/client/scatterSky.cs new file mode 100644 index 000000000..ab1e67cf6 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/scatterSky.cs @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +new GFXStateBlockData( ScatterSkySBData ) +{ + cullDefined = true; + cullMode = "GFXCullNone"; + + zDefined = true; + zEnable = true; + zWriteEnable = false; + zFunc = "GFXCmpLessEqual"; + + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; + samplerStates[1] = SamplerClampLinear; + vertexColorEnable = true; +}; + +singleton ShaderData( ScatterSkyShaderData ) +{ + DXVertexShaderFile = "shaders/common/scatterSkyV.hlsl"; + DXPixelShaderFile = "shaders/common/scatterSkyP.hlsl"; + + OGLVertexShaderFile = "shaders/common/gl/scatterSkyV.glsl"; + OGLPixelShaderFile = "shaders/common/gl/scatterSkyP.glsl"; + + pixVersion = 2.0; +}; diff --git a/Templates/Empty/game/core/scripts/client/screenshot.cs b/Templates/Empty/game/core/scripts/client/screenshot.cs new file mode 100644 index 000000000..897325a1a --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/screenshot.cs @@ -0,0 +1,128 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//--------------------------------------------------------------------------------------------- +// formatImageNumber +// Preceeds a number with zeros to make it 6 digits long. +//--------------------------------------------------------------------------------------------- +function formatImageNumber(%number) +{ + if(%number < 10) + %number = "0" @ %number; + if(%number < 100) + %number = "0" @ %number; + if(%number < 1000) + %number = "0" @ %number; + if(%number < 10000) + %number = "0" @ %number; + return %number; +} + +//--------------------------------------------------------------------------------------------- +// formatSessionNumber +// Preceeds a number with zeros to make it 4 digits long. +//--------------------------------------------------------------------------------------------- +function formatSessionNumber(%number) +{ + if(%number < 10) + %number = "0" @ %number; + if(%number < 100) + %number = "0" @ %number; + return %number; +} + +//--------------------------------------------------------------------------------------------- +// recordMovie +// Records a movie file from the Canvas content using the specified fps. +// Possible encoder values are "PNG" and "THEORA" (default). +//--------------------------------------------------------------------------------------------- +function recordMovie(%movieName, %fps, %encoder) +{ + // If the canvas doesn't exist yet, setup a flag so it'll + // start capturing as soon as it's created + if (!isObject(Canvas)) + return; + + if (%encoder $= "") + %encoder = "THEORA"; + %resolution = Canvas.getVideoMode(); + startVideoCapture(Canvas, %movieName, %encoder, %fps); +} + +function stopMovie() +{ + stopVideoCapture(); +} + +/// This is bound in initializeCommon() to take +/// a screenshot on a keypress. +function doScreenShot( %val ) +{ + // This can be bound, so skip key up events. + if ( %val == 0 ) + return; + + _screenShot( 1 ); +} + +/// A counter for screen shots used by _screenShot(). +$screenshotNumber = 0; + +/// Internal function which generates unique filename +/// and triggers a screenshot capture. +function _screenShot( %tiles, %overlap ) +{ + if ( $pref::Video::screenShotSession $= "" ) + $pref::Video::screenShotSession = 0; + + if ( $screenshotNumber == 0 ) + $pref::Video::screenShotSession++; + + if ( $pref::Video::screenShotSession > 999 ) + $pref::Video::screenShotSession = 1; + + %name = "screenshot_" @ formatSessionNumber($pref::Video::screenShotSession) @ "-" @ + formatImageNumber($screenshotNumber); + %name = expandFileName( %name ); + + $screenshotNumber++; + + if ( ( $pref::Video::screenShotFormat $= "JPEG" ) || + ( $pref::video::screenShotFormat $= "JPG" ) ) + screenShot( %name, "JPEG", %tiles, %overlap ); + else + screenShot( %name, "PNG", %tiles, %overlap ); +} + +/// This will close the console and take a large format +/// screenshot by tiling the current backbuffer and save +/// it to the root game folder. +/// +/// For instance a tile setting of 4 with a window set to +/// 800x600 will output a 3200x2400 screenshot. +function tiledScreenShot( %tiles, %overlap ) +{ + // Pop the console off before we take the shot. + Canvas.popDialog( ConsoleDlg ); + + _screenShot( %tiles, %overlap ); +} diff --git a/Templates/Empty/game/core/scripts/client/scriptDoc.cs b/Templates/Empty/game/core/scripts/client/scriptDoc.cs new file mode 100644 index 000000000..9557cc7e0 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/scriptDoc.cs @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Writes out all script functions to a file. +function writeOutFunctions() +{ + new ConsoleLogger(logger, "scriptFunctions.txt", false); + dumpConsoleFunctions(); + logger.delete(); +} + +// Writes out all script classes to a file. +function writeOutClasses() +{ + new ConsoleLogger(logger, "scriptClasses.txt", false); + dumpConsoleClasses(); + logger.delete(); +} diff --git a/Templates/Empty/game/core/scripts/client/shaders.cs b/Templates/Empty/game/core/scripts/client/shaders.cs new file mode 100644 index 000000000..bf6744fa4 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/shaders.cs @@ -0,0 +1,110 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// This file contains shader data necessary for various engine utility functions +//----------------------------------------------------------------------------- + + +singleton ShaderData( _DebugInterior_ ) +{ + DXVertexShaderFile = "shaders/common/debugInteriorsV.hlsl"; + DXPixelShaderFile = "shaders/common/debugInteriorsP.hlsl"; + + OGLVertexShaderFile = "shaders/common/gl/debugInteriorsV.glsl"; + OGLPixelShaderFile = "shaders/common/gl/debugInteriorsP.glsl"; + + samplerNames[0] = "$diffuseMap"; + + pixVersion = 1.1; +}; + +singleton ShaderData( ParticlesShaderData ) +{ + DXVertexShaderFile = "shaders/common/particlesV.hlsl"; + DXPixelShaderFile = "shaders/common/particlesP.hlsl"; + + OGLVertexShaderFile = "shaders/common/gl/particlesV.glsl"; + OGLPixelShaderFile = "shaders/common/gl/particlesP.glsl"; + + pixVersion = 2.0; +}; + +singleton ShaderData( OffscreenParticleCompositeShaderData ) +{ + DXVertexShaderFile = "shaders/common/particleCompositeV.hlsl"; + DXPixelShaderFile = "shaders/common/particleCompositeP.hlsl"; + + OGLVertexShaderFile = "shaders/common/gl/particleCompositeV.glsl"; + OGLPixelShaderFile = "shaders/common/gl/particleCompositeP.glsl"; + + pixVersion = 2.0; +}; + +//----------------------------------------------------------------------------- +// Planar Reflection +//----------------------------------------------------------------------------- +new ShaderData( ReflectBump ) +{ + DXVertexShaderFile = "shaders/common/planarReflectBumpV.hlsl"; + DXPixelShaderFile = "shaders/common/planarReflectBumpP.hlsl"; + + OGLVertexShaderFile = "shaders/common/gl/planarReflectBumpV.glsl"; + OGLPixelShaderFile = "shaders/common/gl/planarReflectBumpP.glsl"; + + samplerNames[0] = "$diffuseMap"; + samplerNames[1] = "$refractMap"; + samplerNames[2] = "$bumpMap"; + + pixVersion = 2.0; +}; + +new ShaderData( Reflect ) +{ + DXVertexShaderFile = "shaders/common/planarReflectV.hlsl"; + DXPixelShaderFile = "shaders/common/planarReflectP.hlsl"; + + OGLVertexShaderFile = "shaders/common/gl/planarReflectV.glsl"; + OGLPixelShaderFile = "shaders/common/gl/planarReflectP.glsl"; + + samplerNames[0] = "$diffuseMap"; + samplerNames[1] = "$refractMap"; + + pixVersion = 1.4; +}; + +//----------------------------------------------------------------------------- +// fxFoliageReplicator +//----------------------------------------------------------------------------- +new ShaderData( fxFoliageReplicatorShader ) +{ + DXVertexShaderFile = "shaders/common/fxFoliageReplicatorV.hlsl"; + DXPixelShaderFile = "shaders/common/fxFoliageReplicatorP.hlsl"; + + OGLVertexShaderFile = "shaders/common/gl/fxFoliageReplicatorV.glsl"; + OGLPixelShaderFile = "shaders/common/gl/fxFoliageReplicatorP.glsl"; + + samplerNames[0] = "$diffuseMap"; + samplerNames[1] = "$alphaMap"; + + pixVersion = 1.4; +}; \ No newline at end of file diff --git a/Templates/Empty/game/core/scripts/client/terrainBlock.cs b/Templates/Empty/game/core/scripts/client/terrainBlock.cs new file mode 100644 index 000000000..cf18094c9 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/terrainBlock.cs @@ -0,0 +1,33 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +/// Used when generating the blended base texture. +singleton ShaderData( TerrainBlendShader ) +{ + DXVertexShaderFile = "shaders/common/terrain/blendV.hlsl"; + DXPixelShaderFile = "shaders/common/terrain/blendP.hlsl"; + + OGLVertexShaderFile = "shaders/common/terrain/gl/blendV.glsl"; + OGLPixelShaderFile = "shaders/common/terrain/gl/blendP.glsl"; + + pixVersion = 2.0; +}; diff --git a/Templates/Empty/game/core/scripts/client/water.cs b/Templates/Empty/game/core/scripts/client/water.cs new file mode 100644 index 000000000..883554df1 --- /dev/null +++ b/Templates/Empty/game/core/scripts/client/water.cs @@ -0,0 +1,200 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + + +//----------------------------------------------------------------------------- +// Water +//----------------------------------------------------------------------------- + +singleton ShaderData( WaterShader ) +{ + DXVertexShaderFile = "shaders/common/water/waterV.hlsl"; + DXPixelShaderFile = "shaders/common/water/waterP.hlsl"; + + OGLVertexShaderFile = "shaders/common/water/gl/waterV.glsl"; + OGLPixelShaderFile = "shaders/common/water/gl/waterP.glsl"; + + pixVersion = 3.0; +}; + +new GFXSamplerStateData(WaterSampler) +{ + textureColorOp = GFXTOPModulate; + addressModeU = GFXAddressWrap; + addressModeV = GFXAddressWrap; + addressModeW = GFXAddressWrap; + magFilter = GFXTextureFilterLinear; + minFilter = GFXTextureFilterAnisotropic; + mipFilter = GFXTextureFilterLinear; + maxAnisotropy = 4; +}; + +singleton GFXStateBlockData( WaterStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = WaterSampler; // noise + samplerStates[1] = SamplerClampPoint; // #prepass + samplerStates[2] = SamplerClampLinear; // $reflectbuff + samplerStates[3] = SamplerClampPoint; // $backbuff + samplerStates[4] = SamplerWrapLinear; // $cubemap + samplerStates[5] = SamplerWrapLinear; // foam + samplerStates[6] = SamplerClampLinear; // depthMap ( color gradient ) + cullDefined = true; + cullMode = "GFXCullCCW"; +}; + +singleton GFXStateBlockData( UnderWaterStateBlock : WaterStateBlock ) +{ + cullMode = "GFXCullCW"; +}; + +singleton CustomMaterial( WaterMat ) +{ + sampler["prepassTex"] = "#prepass"; + sampler["reflectMap"] = "$reflectbuff"; + sampler["refractBuff"] = "$backbuff"; + + shader = WaterShader; + stateBlock = WaterStateBlock; + version = 3.0; + + useAnisotropic[0] = true; +}; + +//----------------------------------------------------------------------------- +// Underwater +//----------------------------------------------------------------------------- + +singleton ShaderData( UnderWaterShader ) +{ + DXVertexShaderFile = "shaders/common/water/waterV.hlsl"; + DXPixelShaderFile = "shaders/common/water/waterP.hlsl"; + + OGLVertexShaderFile = "shaders/common/water/gl/waterV.glsl"; + OGLPixelShaderFile = "shaders/common/water/gl/waterP.glsl"; + + defines = "UNDERWATER"; + pixVersion = 3.0; +}; + +singleton CustomMaterial( UnderwaterMat ) +{ + // These samplers are set in code not here. + // This is to allow different WaterObject instances + // to use this same material but override these textures + // per instance. + //sampler["bumpMap"] = "core/art/water/noise02"; + //sampler["foamMap"] = "core/art/water/foam"; + + sampler["prepassTex"] = "#prepass"; + sampler["refractBuff"] = "$backbuff"; + + shader = UnderWaterShader; + stateBlock = UnderWaterStateBlock; + specular = "0.75 0.75 0.75 1.0"; + specularPower = 48.0; + version = 3.0; +}; + +//----------------------------------------------------------------------------- +// Basic Water +//----------------------------------------------------------------------------- + +singleton ShaderData( WaterBasicShader ) +{ + DXVertexShaderFile = "shaders/common/water/waterBasicV.hlsl"; + DXPixelShaderFile = "shaders/common/water/waterBasicP.hlsl"; + + OGLVertexShaderFile = "shaders/common/water/gl/waterBasicV.glsl"; + OGLPixelShaderFile = "shaders/common/water/gl/waterBasicP.glsl"; + + pixVersion = 2.0; +}; + +singleton GFXStateBlockData( WaterBasicStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = WaterSampler; // noise + samplerStates[2] = SamplerClampLinear; // $reflectbuff + samplerStates[3] = SamplerClampPoint; // $backbuff + samplerStates[4] = SamplerWrapLinear; // $cubemap + cullDefined = true; + cullMode = "GFXCullCCW"; +}; + +singleton GFXStateBlockData( UnderWaterBasicStateBlock : WaterBasicStateBlock ) +{ + cullMode = "GFXCullCW"; +}; + +singleton CustomMaterial( WaterBasicMat ) +{ + // These samplers are set in code not here. + // This is to allow different WaterObject instances + // to use this same material but override these textures + // per instance. + //sampler["bumpMap"] = "core/art/water/noise02"; + //sampler["skyMap"] = "$cubemap"; + + //sampler["prepassTex"] = "#prepass"; + sampler["reflectMap"] = "$reflectbuff"; + sampler["refractBuff"] = "$backbuff"; + + cubemap = NewLevelSkyCubemap; + shader = WaterBasicShader; + stateBlock = WaterBasicStateBlock; + version = 2.0; +}; + +//----------------------------------------------------------------------------- +// Basic UnderWater +//----------------------------------------------------------------------------- + +singleton ShaderData( UnderWaterBasicShader ) +{ + DXVertexShaderFile = "shaders/common/water/waterBasicV.hlsl"; + DXPixelShaderFile = "shaders/common/water/waterBasicP.hlsl"; + + OGLVertexShaderFile = "shaders/common/water/gl/waterBasicV.glsl"; + OGLPixelShaderFile = "shaders/common/water/gl/waterBasicP.glsl"; + + defines = "UNDERWATER"; + pixVersion = 2.0; +}; + +singleton CustomMaterial( UnderwaterBasicMat ) +{ + // These samplers are set in code not here. + // This is to allow different WaterObject instances + // to use this same material but override these textures + // per instance. + //sampler["bumpMap"] = "core/art/water/noise02"; + //samplers["skyMap"] = "$cubemap"; + + //sampler["prepassTex"] = "#prepass"; + sampler["refractBuff"] = "$backbuff"; + + shader = UnderWaterBasicShader; + stateBlock = UnderWaterBasicStateBlock; + version = 2.0; +}; \ No newline at end of file diff --git a/Templates/Empty/game/core/scripts/gui/chooseLevelDlg.cs b/Templates/Empty/game/core/scripts/gui/chooseLevelDlg.cs new file mode 100644 index 000000000..abb8fcc57 --- /dev/null +++ b/Templates/Empty/game/core/scripts/gui/chooseLevelDlg.cs @@ -0,0 +1,350 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function StartLevel( %mission, %hostingType ) +{ + if( %mission $= "" ) + { + %id = CL_levelList.getSelectedId(); + %mission = getField(CL_levelList.getRowTextById(%id), 1); + } + + if (%hostingType !$= "") + { + %serverType = %hostingType; + } + else + { + if ($pref::HostMultiPlayer) + %serverType = "MultiPlayer"; + else + %serverType = "SinglePlayer"; + } + + // Show the loading screen immediately. + if ( isObject( LoadingGui ) ) + { + Canvas.setContent("LoadingGui"); + LoadingProgress.setValue(1); + LoadingProgressTxt.setValue("LOADING MISSION FILE"); + Canvas.repaint(); + } + + createAndConnectToLocalServer( %serverType, %mission ); +} + + +//---------------------------------------- +function ChooseLevelDlg::onWake( %this ) +{ + CL_levelList.clear(); + ChooseLevelWindow->SmallPreviews.clear(); + + %i = 0; + for(%file = findFirstFile($Server::MissionFileSpec); %file !$= ""; %file = findNextFile($Server::MissionFileSpec)) + { + // Skip our new level/mission if we arent choosing a level + // to launch in the editor. + if ( !%this.launchInEditor ) + { + if (strstr(%file, "newMission.mis") > -1) + continue; + if (strstr(%file, "newLevel.mis") > -1) + continue; + } + + %this.addMissionFile( %file ); + } + + // Also add the new level mission as defined in the world editor settings + // if we are choosing a level to launch in the editor. + if ( %this.launchInEditor ) + { + %file = EditorSettings.value( "WorldEditor/newLevelFile" ); + if ( %file !$= "" ) + %this.addMissionFile( %file ); + } + + // Sort our list + CL_levelList.sort(0); + + // Set the first row as the selected row + CL_levelList.setSelectedRow(0); + + for (%i = 0; %i < CL_levelList.rowCount(); %i++) + { + %preview = new GuiBitmapButtonCtrl() { + internalName = "SmallPreview" @ %i; + Extent = "108 81"; + bitmap = "core/art/gui/images/no-preview"; + command = "ChooseLevelWindow.previewSelected(ChooseLevelWindow->SmallPreviews->SmallPreview" @ %i @ ");"; + }; + + ChooseLevelWindow->SmallPreviews.add(%preview); + + // Set this small preview visible + if (%i >= 5) + %preview.setVisible(false); + + // Set the level index + %preview.levelIndex = %i; + + // Get the name + %name = getField(CL_levelList.getRowText(%i), 0); + + %preview.levelName = %name; + + %file = getField(CL_levelList.getRowText(%i), 1); + + // Find the preview image + %levelPreview = filePath(%file) @ "/" @ fileBase(%file) @ "_preview"; + + // Test against all of the different image formats + // This should probably be moved into an engine function + if (isFile(%levelPreview @ ".png") || + isFile(%levelPreview @ ".jpg") || + isFile(%levelPreview @ ".bmp") || + isFile(%levelPreview @ ".gif") || + isFile(%levelPreview @ ".jng") || + isFile(%levelPreview @ ".mng") || + isFile(%levelPreview @ ".tga")) + { + %preview.setBitmap(%levelPreview); + } + + // Get the description + %desc = getField(CL_levelList.getRowText(%i), 2); + + %preview.levelDesc = %desc; + } + + ChooseLevelWindow->SmallPreviews.firstVisible = -1; + ChooseLevelWindow->SmallPreviews.lastVisible = -1; + + if (ChooseLevelWindow->SmallPreviews.getCount() > 0) + { + ChooseLevelWindow->SmallPreviews.firstVisible = 0; + + if (ChooseLevelWindow->SmallPreviews.getCount() < 6) + ChooseLevelWindow->SmallPreviews.lastVisible = ChooseLevelWindow->SmallPreviews.getCount() - 1; + else + ChooseLevelWindow->SmallPreviews.lastVisible = 4; + } + + if (ChooseLevelWindow->SmallPreviews.getCount() > 0) + ChooseLevelWindow.previewSelected(ChooseLevelWindow->SmallPreviews.getObject(0)); + + // If we have 5 or less previews then hide our next/previous buttons + // and resize to fill their positions + if (ChooseLevelWindow->SmallPreviews.getCount() < 6) + { + ChooseLevelWindow->PreviousSmallPreviews.setVisible(false); + ChooseLevelWindow->NextSmallPreviews.setVisible(false); + + %previewPos = ChooseLevelWindow->SmallPreviews.getPosition(); + %previousPos = ChooseLevelWindow->PreviousSmallPreviews.getPosition(); + + %previewPosX = getWord(%previousPos, 0); + %previewPosY = getWord(%previewPos, 1); + + ChooseLevelWindow->SmallPreviews.setPosition(%previewPosX, %previewPosY); + + ChooseLevelWindow->SmallPreviews.colSpacing = 10;//((getWord(NextSmallPreviews.getPosition(), 0)+11)-getWord(PreviousSmallPreviews.getPosition(), 0))/4; + ChooseLevelWindow->SmallPreviews.refresh(); + } + + if (ChooseLevelWindow->SmallPreviews.getCount() <= 1) + { + // Hide the small previews + ChooseLevelWindow->SmallPreviews.setVisible(false); + + // Shrink the ChooseLevelWindow so that we don't have a large blank space + %extentX = getWord(ChooseLevelWindow.getExtent(), 0); + %extentY = getWord(ChooseLevelWindow->SmallPreviews.getPosition(), 1); + + ChooseLevelWIndow.setExtent(%extentX, %extentY); + } + else + { + // Make sure the small previews are visible + ChooseLevelWindow->SmallPreviews.setVisible(true); + + %extentX = getWord(ChooseLevelWindow.getExtent(), 0); + + %extentY = getWord(ChooseLevelWindow->SmallPreviews.getPosition(), 1); + %extentY = %extentY + getWord(ChooseLevelWindow->SmallPreviews.getExtent(), 1); + %extentY = %extentY + 9; + + ChooseLevelWIndow.setExtent(%extentX, %extentY); + } +} + +function ChooseLevelDlg::addMissionFile( %this, %file ) +{ + %levelName = fileBase(%file); + %levelDesc = "A Torque level"; + + %LevelInfoObject = getLevelInfo(%file); + + if (%LevelInfoObject != 0) + { + if(%LevelInfoObject.levelName !$= "") + %levelName = %LevelInfoObject.levelName; + else if(%LevelInfoObject.name !$= "") + %levelName = %LevelInfoObject.name; + + if (%LevelInfoObject.desc0 !$= "") + %levelDesc = %LevelInfoObject.desc0; + + %LevelInfoObject.delete(); + } + + CL_levelList.addRow( CL_levelList.rowCount(), %levelName TAB %file TAB %levelDesc ); +} + +function ChooseLevelDlg::onSleep( %this ) +{ + // This is set from the outside, only stays true for a single wake/sleep + // cycle. + %this.launchInEditor = false; +} + +function ChooseLevelWindow::previewSelected(%this, %preview) +{ + // Set the selected level + if (isObject(%preview) && %preview.levelIndex !$= "") + CL_levelList.setSelectedRow(%preview.levelIndex); + else + CL_levelList.setSelectedRow(-1); + + // Set the large preview image + if (isObject(%preview) && %preview.bitmap !$= "") + %this->CurrentPreview.setBitmap(%preview.bitmap); + else + %this->CurrentPreview.setBitmap("core/art/gui/images/no-preview"); + + // Set the current level name + if (isObject(%preview) && %preview.levelName !$= "") + %this->LevelName.setText(%preview.levelName); + else + %this->LevelName.setText("Level"); + + // Set the current level description + if (isObject(%preview) && %preview.levelDesc !$= "") + %this->LevelDescription.setText(%preview.levelDesc); + else + %this->LevelDescription.setText("A Torque Level"); +} + +function ChooseLevelWindow::previousPreviews(%this) +{ + %prevHiddenIdx = %this->SmallPreviews.firstVisible - 1; + + if (%prevHiddenIdx < 0) + return; + + %lastVisibleIdx = %this->SmallPreviews.lastVisible; + + if (%lastVisibleIdx >= %this->SmallPreviews.getCount()) + return; + + %prevHiddenObj = %this->SmallPreviews.getObject(%prevHiddenIdx); + %lastVisibleObj = %this->SmallPreviews.getObject(%lastVisibleIdx); + + if (isObject(%prevHiddenObj) && isObject(%lastVisibleObj)) + { + %this->SmallPreviews.firstVisible--; + %this->SmallPreviews.lastVisible--; + + %prevHiddenObj.setVisible(true); + %lastVisibleObj.setVisible(false); + } +} + +function ChooseLevelWindow::nextPreviews(%this) +{ + %firstVisibleIdx = %this->SmallPreviews.firstVisible; + + if (%firstVisibleIdx < 0) + return; + + %firstHiddenIdx = %this->SmallPreviews.lastVisible + 1; + + if (%firstHiddenIdx >= %this->SmallPreviews.getCount()) + return; + + %firstVisibleObj = %this->SmallPreviews.getObject(%firstVisibleIdx); + %firstHiddenObj = %this->SmallPreviews.getObject(%firstHiddenIdx); + + if (isObject(%firstVisibleObj) && isObject(%firstHiddenObj)) + { + %this->SmallPreviews.firstVisible++; + %this->SmallPreviews.lastVisible++; + + %firstVisibleObj.setVisible(false); + %firstHiddenObj.setVisible(true); + } +} + +//---------------------------------------- +function getLevelInfo( %missionFile ) +{ + %file = new FileObject(); + + %LevelInfoObject = ""; + + if ( %file.openForRead( %missionFile ) ) { + %inInfoBlock = false; + + while ( !%file.isEOF() ) { + %line = %file.readLine(); + %line = trim( %line ); + + if( %line $= "new ScriptObject(LevelInfo) {" ) + %inInfoBlock = true; + else if( %line $= "new LevelInfo(theLevelInfo) {" ) + %inInfoBlock = true; + else if( %inInfoBlock && %line $= "};" ) { + %inInfoBlock = false; + %LevelInfoObject = %LevelInfoObject @ %line; + break; + } + + if( %inInfoBlock ) + %LevelInfoObject = %LevelInfoObject @ %line @ " "; + } + + %file.close(); + } + %file.delete(); + + if( %LevelInfoObject !$= "" ) + { + %LevelInfoObject = "%LevelInfoObject = " @ %LevelInfoObject; + eval( %LevelInfoObject ); + + return %LevelInfoObject; + } + + // Didn't find our LevelInfo + return 0; +} diff --git a/Templates/Empty/game/core/scripts/gui/cursors.cs b/Templates/Empty/game/core/scripts/gui/cursors.cs new file mode 100644 index 000000000..0e9b54ef8 --- /dev/null +++ b/Templates/Empty/game/core/scripts/gui/cursors.cs @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +if($platform $= "macos") +{ + new GuiCursor(DefaultCursor) + { + hotSpot = "4 4"; + renderOffset = "0 0"; + bitmapName = "~/art/gui/images/macCursor"; + }; +} +else +{ + new GuiCursor(DefaultCursor) + { + hotSpot = "1 1"; + renderOffset = "0 0"; + bitmapName = "~/art/gui/images/defaultCursor"; + }; +} \ No newline at end of file diff --git a/Templates/Empty/game/core/scripts/gui/guiMusicPlayer.cs b/Templates/Empty/game/core/scripts/gui/guiMusicPlayer.cs new file mode 100644 index 000000000..6af2c48ea --- /dev/null +++ b/Templates/Empty/game/core/scripts/gui/guiMusicPlayer.cs @@ -0,0 +1,244 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// A very simple music player. + +//--------------------------------------------------------------------------------------------- +// Prerequisites. + +if( !isObject( GuiMusicPlayer ) ) + exec( "./guiMusicPlayer.gui" ); + +//--------------------------------------------------------------------------------------------- +// Preferences. + +$pref::GuiMusicPlayer::filePattern = "*.ogg\t*.wav"; +$pref::GuiMusicPlayer::filePatternFMOD = "*.aiff\t*.asf\t*.flac\t*.it\t*.mid\t*.mod\t*.mp2\t*.mp3\t*.ogg\t*.s3m\t*.vag\t*.wav\t*.wma\t*.xm"; +$pref::GuiMusicPlayer::fadeTime = "3.0"; + +//--------------------------------------------------------------------------------------------- +// Datablocks. + +singleton SFXDescription( GuiMusicPlayerStream : AudioMusic2D ) +{ + volume = 1.0; + isLooping = false; + isStreaming = true; + is3D = false; +}; +singleton SFXDescription( GuiMusicPlayerLoopingStream : AudioMusic2D ) +{ + volume = 1.0; + isLooping = true; + isStreaming = true; + is3D = false; +}; + +//--------------------------------------------------------------------------------------------- +// Functions. + +function toggleMusicPlayer() +{ + if( !GuiMusicPlayer.isAwake() ) + { + GuiMusicPlayer.setExtent( Canvas.getExtent() ); + GuiMusicPlayer.setPosition( 0, 0 ); + + Canvas.pushDialog( GuiMusicPlayer ); + } + else + Canvas.popDialog( GuiMusicPlayer ); +} + +//--------------------------------------------------------------------------------------------- +// Methods. + +function GuiMusicPlayer_onSFXSourceStatusChange( %id, %status ) +{ + if( %status $= "Stopped" ) + GuiMusicPlayer.onStop(); +} + +function GuiMusicPlayerClass::play( %this ) +{ + if( %this.status $= "Stopped" + || %this.status $= "Paused" + || %this.status $= "" ) + { + %isPlaying = true; + if( %this.status $= "Paused" && isObject( %this.sfxSource ) ) + %this.sfxSource.play(); + else + { + %sel = GuiMusicPlayerMusicList.getSelectedItem(); + if( %sel == -1 ) + %isPlaying = false; + else + { + %desc = GuiMusicPlayerStream; + if( GuiMusicPlayerLoopCheckBox.getValue() ) + %desc = GuiMusicPlayerLoopingStream; + + if( GuiMusicPlayerFadeCheckBox.getValue() ) + { + %desc.fadeInTime = $pref::GuiMusicPlayer::fadeTime; + %desc.fadeOutTime = $pref::GuiMusicPlayer::fadeTime; + } + else + { + %desc.fadeInTime = 0; + %desc.fadeOutTime = 0; + } + + %file = GuiMusicPlayerMusicList.getItemText( %sel ); + %this.sfxSource = sfxPlayOnce( %desc, %file ); + if( !%this.sfxSource ) + %isPlaying = false; + else + { + %this.sfxSource.statusCallback = "GuiMusicPlayer_onSFXSourceStatusChange"; + GuiMusicPlayer.status = "Playing"; + + GuiMusicPlayerScrubber.setActive( true ); + GuiMusicPlayerScrubber.setup( %this.sfxSource.getDuration() ); + } + } + } + + if( %isPlaying ) + { + GuiMusicPlayerPlayButton.setText( "Pause" ); + GuiMusicPlayerPlayButton.command = "GuiMusicPlayer.pause();"; + GuiMusicPlayerLoopCheckBox.setActive( false ); + GuiMusicPlayerFadeCheckBox.setActive( false ); + %this.status = "Playing"; + } + } +} + +function GuiMusicPlayerClass::stop( %this ) +{ + if( %this.status $= "Playing" + || %this.status $= "Paused" ) + { + if( isObject( %this.sfxSource ) ) + %this.sfxSource.stop( 0 ); // Stop immediately. + } +} + +function GuiMusicPlayerClass::onStop( %this ) +{ + %this.sfxSource = 0; + + GuiMusicPlayerLoopCheckBox.setActive( true ); + GuiMusicPlayerFadeCheckBox.setActive( true ); + GuiMusicPlayerScrubber.setActive( false ); + GuiMusicPlayerPlayButton.setText( "Play" ); + GuiMusicPlayerPlayButton.Command = "GuiMusicPlayer.play();"; + %this.status = "Stopped"; + + GuiMusicPlayerScrubber.setValue( 0 ); +} + +function GuiMusicPlayerClass::pause( %this ) +{ + if( %this.status $= "Playing" ) + { + if( isObject( %this.sfxSource ) ) + %this.sfxSource.pause( 0 ); + + GuiMusicPlayerPlayButton.setText( "Play" ); + GuiMusicPlayerPlayButton.command = "GuiMusicPlayer.play();"; + %this.status = "Paused"; + } +} + +function GuiMusicPlayerClass::seek( %this, %playtime ) +{ + if( ( %this.status $= "Playing" + || %this.status $= "Paused" ) + && isObject( %this.sfxSource ) ) + %this.sfxSource.setPosition( %playtime ); +} + +function GuiMusicPlayer::onWake( %this ) +{ + GuiMusicPlayerMusicList.load(); +} + +function GuiMusicPlayerMusicListClass::load( %this ) +{ + // Remove all the files currently in the list. + + %this.clearItems(); + + // Find the file matching pattern we should use. + + %filePattern = $pref::GuiMusicPlayer::filePattern; + %sfxProvider = getWord( sfxGetDeviceInfo(), 0 ); + %filePatternVarName = "$pref::GuiMusicPlayer::filePattern" @ %sfxProvider; + if( isDefined( %filePatternVarName ) ) + eval( "%filePattern = " @ %filePatternVarName @ ";" ); + + // Find all files matching the pattern. + + for( %file = findFirstFileMultiExpr( %filePattern ); + %file !$= ""; + %file = findNextFileMultiExpr( %filePattern ) ) + %this.addItem( makeRelativePath( %file, getMainDotCsDir() ) ); +} + +function GuiMusicPlayerMusicList::onDoubleClick( %this ) +{ + GuiMusicPlayer.stop(); + GuiMusicPlayer.play(); +} + +function GuiMusicPlayerScrubber::onMouseDragged( %this ) +{ + %this.isBeingDragged = true; +} + +function GuiMusicPlayerScrubberClass::setup( %this, %totalPlaytime ) +{ + %this.range = "0 " @ %totalPlaytime; + %this.ticks = %totalPlaytime / 5; // One tick per five seconds. + + %this.update(); +} + +function GuiMusicPlayerScrubberClass::update( %this ) +{ + if( GuiMusicPlayer.status $= "Playing" + && !%this.isBeingDragged ) + %this.setValue( GuiMusicPlayer.sfxSource.getPosition() ); + + if( GuiMusicPlayer.status $= "Playing" + || GuiMusicPlayer.status $= "Paused" ) + %this.schedule( 5, "update" ); +} + +function GuiMusicPlayerScrubberClass::onDragComplete( %this ) +{ + GuiMusicPlayer.seek( %this.getValue() ); + %this.isBeingDragged = false; +} diff --git a/Templates/Empty/game/core/scripts/gui/guiMusicPlayer.gui b/Templates/Empty/game/core/scripts/gui/guiMusicPlayer.gui new file mode 100644 index 000000000..291f3a356 --- /dev/null +++ b/Templates/Empty/game/core/scripts/gui/guiMusicPlayer.gui @@ -0,0 +1,192 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(GuiMusicPlayer) { + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + superClass = "GuiMusicPlayerClass"; + + new GuiWindowCtrl() { + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "1"; + canMaximize = "1"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Torque Music Player"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "29 35"; + Extent = "518 377"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + closeCommand = "toggleMusicPlayer();"; + + new GuiCheckBoxCtrl(GuiMusicPlayerFadeCheckBox) { + useInactiveState = "0"; + text = "Fade"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "457 347"; + Extent = "53 30"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(GuiMusicPlayerLoopCheckBox) { + useInactiveState = "0"; + text = "Loop"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "457 330"; + Extent = "44 30"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "alwaysOn"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "9 31"; + Extent = "500 298"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiListBoxCtrl(GuiMusicPlayerMusicList) { + AllowMultipleSelections = "1"; + fitParentWidth = "1"; + isContainer = "0"; + Profile = "GuiListBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "485 2"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + superClass = "GuiMusicPlayerMusicListClass"; + }; + }; + new GuiSliderCtrl(GuiMusicPlayerScrubber) { + range = "0 1"; + ticks = "10"; + value = "0"; + snap = "false"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "114 343"; + Extent = "331 23"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$thisControl.onDragComplete();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + class = "GuiMusicPlayerScrubberClass"; + className = "GuiMusicPlayerScrubberClass"; + }; + new GuiButtonCtrl(GuiMusicPlayerStopButton) { + text = "Stop"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "57 338"; + Extent = "40 30"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GuiMusicPlayer.stop();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(GuiMusicPlayerPlayButton) { + text = "Play"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "13 338"; + Extent = "40 30"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GuiMusicPlayer.play();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/core/scripts/gui/guiTreeViewCtrl.cs b/Templates/Empty/game/core/scripts/gui/guiTreeViewCtrl.cs new file mode 100644 index 000000000..bc952dbca --- /dev/null +++ b/Templates/Empty/game/core/scripts/gui/guiTreeViewCtrl.cs @@ -0,0 +1,50 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function GuiTreeViewCtrl::onDefineIcons( %this ) +{ + %icons = "core/art/gui/images/treeview/default:" @ + "core/art/gui/images/treeview/simgroup:" @ + "core/art/gui/images/treeview/simgroup_closed:" @ + "core/art/gui/images/treeview/simgroup_selected:" @ + "core/art/gui/images/treeview/simgroup_selected_closed:" @ + "core/art/gui/images/treeview/hidden:" @ + "core/art/gui/images/treeview/shll_icon_passworded_hi:" @ + "core/art/gui/images/treeview/shll_icon_passworded:" @ + "core/art/gui/images/treeview/default"; + + %this.buildIconTable(%icons); +} + +function GuiTreeViewCtrl::handleRenameObject( %this, %name, %obj ) +{ + %inspector = GuiInspector::findByObject( %obj ); + + if( isObject( %inspector ) ) + { + %field = ( %this.renameInternal ) ? "internalName" : "name"; + %inspector.setObjectField( %field, %name ); + return true; + } + + return false; +} diff --git a/Templates/Empty/game/core/scripts/gui/help.cs b/Templates/Empty/game/core/scripts/gui/help.cs new file mode 100644 index 000000000..a305671af --- /dev/null +++ b/Templates/Empty/game/core/scripts/gui/help.cs @@ -0,0 +1,90 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function HelpDlg::onWake(%this) +{ + HelpFileList.entryCount = 0; + HelpFileList.clear(); + for(%file = findFirstFile("*.hfl"); %file !$= ""; %file = findNextFile("*.hfl")) + { + HelpFileList.fileName[HelpFileList.entryCount] = %file; + HelpFileList.addRow(HelpFileList.entryCount, fileBase(%file)); + HelpFileList.entryCount++; + } + HelpFileList.sortNumerical(0); + for(%i = 0; %i < HelpFileList.entryCount; %i++) + { + %rowId = HelpFileList.getRowId(%i); + %text = HelpFileList.getRowTextById(%rowId); + %text = %i + 1 @ ". " @ restWords(%text); + HelpFileList.setRowById(%rowId, %text); + } + HelpFileList.setSelectedRow(0); +} + +function HelpFileList::onSelect(%this, %row) +{ + %fo = new FileObject(); + %fo.openForRead(%this.fileName[%row]); + %text = ""; + while(!%fo.isEOF()) + %text = %text @ %fo.readLine() @ "\n"; + + %fo.delete(); + HelpText.setText(%text); +} + +function getHelp(%helpName) +{ + Canvas.pushDialog(HelpDlg); + if(%helpName !$= "") + { + %index = HelpFileList.findTextIndex(%helpName); + HelpFileList.setSelectedRow(%index); + } +} + +function contextHelp() +{ + for(%i = 0; %i < Canvas.getCount(); %i++) + { + if(Canvas.getObject(%i).getName() $= HelpDlg) + { + Canvas.popDialog(HelpDlg); + return; + } + } + %content = Canvas.getContent(); + %helpPage = %content.getHelpPage(); + getHelp(%helpPage); +} + +function GuiControl::getHelpPage(%this) +{ + return %this.helpPage; +} + +function GuiMLTextCtrl::onURL(%this, %url) +{ + gotoWebPage( %url ); +} + diff --git a/Templates/Empty/game/core/scripts/gui/loadingGui.cs b/Templates/Empty/game/core/scripts/gui/loadingGui.cs new file mode 100644 index 000000000..08a79d839 --- /dev/null +++ b/Templates/Empty/game/core/scripts/gui/loadingGui.cs @@ -0,0 +1,51 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +function LoadingGui::onAdd(%this) +{ + %this.qLineCount = 0; +} + +//------------------------------------------------------------------------------ +function LoadingGui::onWake(%this) +{ + // Play sound... + //CloseMessagePopup(); +} + +//------------------------------------------------------------------------------ +function LoadingGui::onSleep(%this) +{ + // Clear the load info: + if ( %this.qLineCount !$= "" ) + { + for ( %line = 0; %line < %this.qLineCount; %line++ ) + %this.qLine[%line] = ""; + } + %this.qLineCount = 0; + + LoadingProgress.setValue( 0 ); + LoadingProgressTxt.setValue( "WAITING FOR SERVER" ); + + // Stop sound... +} diff --git a/Templates/Empty/game/core/scripts/gui/messageBoxes/IODropdownDlg.ed.gui b/Templates/Empty/game/core/scripts/gui/messageBoxes/IODropdownDlg.ed.gui new file mode 100644 index 000000000..5fa0093da --- /dev/null +++ b/Templates/Empty/game/core/scripts/gui/messageBoxes/IODropdownDlg.ed.gui @@ -0,0 +1,159 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(IODropdownDlg) { + profile = "GuiDefaultProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + new GuiWindowCtrl(IODropdownFrame) { + canSaveDynamicFields = "0"; + Profile = "GuiWindowProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "272 77"; + extent = "256 117"; + minExtent = "256 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + maxLength = "255"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + text = ""; + closeCommand="IOCallback(IODropdownDlg,IODropdownDlg.cancelCallback);"; + + new GuiMLTextCtrl(IODropdownText) { + text = ""; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiMLTextProfile"; + horizSizing = "center"; + vertSizing = "bottom"; + position = "9 26"; + extent = "237 16"; + minExtent = "8 8"; + canSave = "1"; + visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapBorderCtrl() { + isContainer = "0"; + profile = "GuiGroupBorderProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "7 51"; + extent = "243 28"; + minExtent = "0 0"; + canSave = "1"; + visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl(IOInputText) { + text = "Decal Datablock"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 5"; + extent = "105 18"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(IODropdownMenu) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiPopUpMenuProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "115 5"; + extent = "122 18"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + new GuiButtonCtrl() { + text = "OK"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiButtonProfile"; + horizSizing = "width"; + vertSizing = "top"; + position = "7 85"; + extent = "156 24"; + minExtent = "8 8"; + canSave = "1"; + visible = "1"; + accelerator = "return"; + command = "IOCallback(IODropdownDlg,IODropdownDlg.callback);"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiButtonProfile"; + horizSizing = "left"; + vertSizing = "top"; + position = "170 85"; + extent = "80 24"; + minExtent = "8 8"; + canSave = "1"; + visible = "1"; + accelerator = "escape"; + command = "IOCallback(IODropdownDlg,IODropdownDlg.cancelCallback);"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/core/scripts/gui/messageBoxes/MessageBoxOKCancelDetailsDlg.ed.gui b/Templates/Empty/game/core/scripts/gui/messageBoxes/MessageBoxOKCancelDetailsDlg.ed.gui new file mode 100644 index 000000000..bf746ea09 --- /dev/null +++ b/Templates/Empty/game/core/scripts/gui/messageBoxes/MessageBoxOKCancelDetailsDlg.ed.gui @@ -0,0 +1,137 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(MessageBoxOKCancelDetailsDlg) { + canSaveDynamicFields = "0"; + Profile = "GuiOverlayProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl(MBOKCancelDetailsFrame) { + canSaveDynamicFields = "0"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "362 219"; + Extent = "300 330"; + MinExtent = "48 92"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + maxLength = "255"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + text = ""; + + new GuiMLTextCtrl(MBOKCancelDetailsText) { + canSaveDynamicFields = "0"; + Profile = "GuiMLTextProfile"; + HorizSizing = "center"; + VertSizing = "bottom"; + position = "32 39"; + Extent = "236 70"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "top"; + position = "158 273"; + Extent = "110 23"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "MessageCallback(MessageBoxOKCancelDetailsDlg,MessageBoxOKCancelDetailsDlg.callback);"; + Accelerator = "return"; + hovertime = "1000"; + text = "OK"; + groupNum = "-1"; + buttonType = "PushButton"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "top"; + position = "30 273"; + Extent = "110 23"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "MessageCallback(MessageBoxOKCancelDetailsDlg,MessageBoxOKCancelDetailsDlg.cancelCallback);"; + Accelerator = "escape"; + hovertime = "1000"; + text = "CANCEL"; + groupNum = "-1"; + buttonType = "PushButton"; + }; + new GuiButtonCtrl(MBOKCancelDetailsButton) { + canSaveDynamicFields = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "top"; + position = "9 302"; + Extent = "86 17"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "MBOKCancelDetailsToggleInfoFrame();"; + hovertime = "1000"; + text = "Details"; + groupNum = "-1"; + buttonType = "PushButton"; + }; + new GuiScrollCtrl(MBOKCancelDetailsScroll) { + canSaveDynamicFields = "0"; + Profile = "GuiScrollProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 115"; + Extent = "281 138"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiMLTextCtrl(MBOKCancelDetailsInfoText) { + canSaveDynamicFields = "0"; + Profile = "GuiMLTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "2 2"; + Extent = "259 56"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/core/scripts/gui/messageBoxes/messageBox.ed.cs b/Templates/Empty/game/core/scripts/gui/messageBoxes/messageBox.ed.cs new file mode 100644 index 000000000..d778ae7ee --- /dev/null +++ b/Templates/Empty/game/core/scripts/gui/messageBoxes/messageBox.ed.cs @@ -0,0 +1,326 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +// Cleanup Dialog created by 'core' +if( isObject( MessagePopupDlg ) ) + MessagePopupDlg.delete(); +if( isObject( MessageBoxYesNoDlg ) ) + MessageBoxYesNoDlg.delete(); +if( isObject( MessageBoxYesNoCancelDlg ) ) + MessageBoxYesNoCancelDlg.delete(); +if( isObject( MessageBoxOKCancelDetailsDlg ) ) + MessageBoxOKCancelDetailsDlg.delete(); +if( isObject( MessageBoxOKCancelDlg ) ) + MessageBoxOKCancelDlg.delete(); +if( isObject( MessageBoxOKDlg ) ) + MessageBoxOKDlg.delete(); +if( isObject( IODropdownDlg ) ) + IODropdownDlg.delete(); + + +// Load Editor Dialogs +exec("./messageBoxOk.ed.gui"); +exec("./messageBoxYesNo.ed.gui"); +exec("./messageBoxYesNoCancel.ed.gui"); +exec("./messageBoxOKCancel.ed.gui"); +exec("./messageBoxOKCancelDetailsDlg.ed.gui"); +exec("./messagePopup.ed.gui"); +exec("./IODropdownDlg.ed.gui"); + + + +// -------------------------------------------------------------------- +// Message Sound +// -------------------------------------------------------------------- +/*new SFXDescription(MessageBoxAudioDescription) +{ + volume = 1.0; + isLooping = false; + is3D = false; + channel = $GuiAudioType; +}; + +new SFXProfile(messageBoxBeep) +{ + filename = "./messageBoxSound"; + description = MessageBoxAudioDescription; + preload = true; +};*/ + + + + +//--------------------------------------------------------------------------------------------- +// messageCallback +// Calls a callback passed to a message box. +//--------------------------------------------------------------------------------------------- +function messageCallback(%dlg, %callback) +{ + Canvas.popDialog(%dlg); + eval(%callback); +} + +//The # in the function passed replaced with the output +//of the preset menu. +function IOCallback(%dlg, %callback) +{ + %id = IODropdownMenu.getSelected(); + %text = IODropdownMenu.getTextById(%id); + %callback = strreplace(%callback, "#", %text); + eval(%callback); + + Canvas.popDialog(%dlg); +} + +//--------------------------------------------------------------------------------------------- +// MBSetText +// Sets the text of a message box and resizes it to accomodate the new string. +//--------------------------------------------------------------------------------------------- +function MBSetText(%text, %frame, %msg) +{ + // Get the extent of the text box. + %ext = %text.getExtent(); + // Set the text in the center of the text box. + %text.setText("" @ %msg); + // Force the textbox to resize itself vertically. + %text.forceReflow(); + // Grab the new extent of the text box. + %newExtent = %text.getExtent(); + + // Get the vertical change in extent. + %deltaY = getWord(%newExtent, 1) - getWord(%ext, 1); + + // Resize the window housing the text box. + %windowPos = %frame.getPosition(); + %windowExt = %frame.getExtent(); + %frame.resize(getWord(%windowPos, 0), getWord(%windowPos, 1) - (%deltaY / 2), + getWord(%windowExt, 0), getWord(%windowExt, 1) + %deltaY); + + %frame.canMove = "0"; + //%frame.canClose = "0"; + %frame.resizeWidth = "0"; + %frame.resizeHeight = "0"; + %frame.canMinimize = "0"; + %frame.canMaximize = "0"; + + //sfxPlayOnce( messageBoxBeep ); +} + +//--------------------------------------------------------------------------------------------- +// Various message box display functions. Each one takes a window title, a message, and a +// callback for each button. +//--------------------------------------------------------------------------------------------- + +function MessageBoxOK(%title, %message, %callback) +{ + MBOKFrame.text = %title; + Canvas.pushDialog(MessageBoxOKDlg); + MBSetText(MBOKText, MBOKFrame, %message); + MessageBoxOKDlg.callback = %callback; +} + +function MessageBoxOKDlg::onSleep( %this ) +{ + %this.callback = ""; +} + +function MessageBoxOKCancel(%title, %message, %callback, %cancelCallback) +{ + MBOKCancelFrame.text = %title; + Canvas.pushDialog(MessageBoxOKCancelDlg); + MBSetText(MBOKCancelText, MBOKCancelFrame, %message); + MessageBoxOKCancelDlg.callback = %callback; + MessageBoxOKCancelDlg.cancelCallback = %cancelCallback; +} + +function MessageBoxOKCancelDlg::onSleep( %this ) +{ + %this.callback = ""; +} + +function MessageBoxOKCancelDetails(%title, %message, %details, %callback, %cancelCallback) +{ + if(%details $= "") + { + MBOKCancelDetailsButton.setVisible(false); + } + + MBOKCancelDetailsScroll.setVisible(false); + + MBOKCancelDetailsFrame.setText( %title ); + + Canvas.pushDialog(MessageBoxOKCancelDetailsDlg); + MBSetText(MBOKCancelDetailsText, MBOKCancelDetailsFrame, %message); + MBOKCancelDetailsInfoText.setText(%details); + + %textExtent = MBOKCancelDetailsText.getExtent(); + %textExtentY = getWord(%textExtent, 1); + %textPos = MBOKCancelDetailsText.getPosition(); + %textPosY = getWord(%textPos, 1); + + %extentY = %textPosY + %textExtentY + 65; + + MBOKCancelDetailsInfoText.setExtent(285, 128); + + MBOKCancelDetailsFrame.setExtent(300, %extentY); + + MessageBoxOKCancelDetailsDlg.callback = %callback; + MessageBoxOKCancelDetailsDlg.cancelCallback = %cancelCallback; + + MBOKCancelDetailsFrame.defaultExtent = MBOKCancelDetailsFrame.getExtent(); +} + +function MBOKCancelDetailsToggleInfoFrame() +{ + if(!MBOKCancelDetailsScroll.isVisible()) + { + MBOKCancelDetailsScroll.setVisible(true); + MBOKCancelDetailsText.forceReflow(); + %textExtent = MBOKCancelDetailsText.getExtent(); + %textExtentY = getWord(%textExtent, 1); + %textPos = MBOKCancelDetailsText.getPosition(); + %textPosY = getWord(%textPos, 1); + + %verticalStretch = %textExtentY; + + if((%verticalStretch > 260) || (%verticalStretch < 0)) + %verticalStretch = 260; + + %extent = MBOKCancelDetailsFrame.defaultExtent; + %height = getWord(%extent, 1); + + %posY = %textPosY + %textExtentY + 10; + %posX = getWord(MBOKCancelDetailsScroll.getPosition(), 0); + MBOKCancelDetailsScroll.setPosition(%posX, %posY); + MBOKCancelDetailsScroll.setExtent(getWord(MBOKCancelDetailsScroll.getExtent(), 0), %verticalStretch); + MBOKCancelDetailsFrame.setExtent(300, %height + %verticalStretch + 10); + } else + { + %extent = MBOKCancelDetailsFrame.defaultExtent; + %width = getWord(%extent, 0); + %height = getWord(%extent, 1); + MBOKCancelDetailsFrame.setExtent(%width, %height); + MBOKCancelDetailsScroll.setVisible(false); + } +} + +function MessageBoxOKCancelDetailsDlg::onSleep( %this ) +{ + %this.callback = ""; +} + +function MessageBoxYesNo(%title, %message, %yesCallback, %noCallback) +{ + MBYesNoFrame.text = %title; + MessageBoxYesNoDlg.profile = "GuiOverlayProfile"; + Canvas.pushDialog(MessageBoxYesNoDlg); + MBSetText(MBYesNoText, MBYesNoFrame, %message); + MessageBoxYesNoDlg.yesCallBack = %yesCallback; + MessageBoxYesNoDlg.noCallback = %noCallBack; +} + +function MessageBoxYesNoCancel(%title, %message, %yesCallback, %noCallback, %cancelCallback) +{ + MBYesNoCancelFrame.text = %title; + MessageBoxYesNoDlg.profile = "GuiOverlayProfile"; + Canvas.pushDialog(MessageBoxYesNoCancelDlg); + MBSetText(MBYesNoCancelText, MBYesNoCancelFrame, %message); + MessageBoxYesNoCancelDlg.yesCallBack = %yesCallback; + MessageBoxYesNoCancelDlg.noCallback = %noCallBack; + MessageBoxYesNoCancelDlg.cancelCallback = %cancelCallback; +} + +function MessageBoxYesNoDlg::onSleep( %this ) +{ + %this.yesCallback = ""; + %this.noCallback = ""; +} + +//--------------------------------------------------------------------------------------------- +// MessagePopup +// Displays a message box with no buttons. Disappears after %delay milliseconds. +//--------------------------------------------------------------------------------------------- +function MessagePopup(%title, %message, %delay) +{ + // Currently two lines max. + MessagePopFrame.setText(%title); + Canvas.pushDialog(MessagePopupDlg); + MBSetText(MessagePopText, MessagePopFrame, %message); + if (%delay !$= "") + schedule(%delay, 0, CloseMessagePopup); +} + +//--------------------------------------------------------------------------------------------- +// IODropdown +// By passing in a simgroup or simset, the user will be able to choose a child of that group +// through a guiPopupMenuCtrl +//--------------------------------------------------------------------------------------------- + +function IODropdown(%title, %message, %simgroup, %callback, %cancelCallback) +{ + IODropdownFrame.text = %title; + Canvas.pushDialog(IODropdownDlg); + MBSetText(IODropdownText, IODropdownFrame, %message); + + if(isObject(%simgroup)) + { + for(%i = 0; %i < %simgroup.getCount(); %i++) + IODropdownMenu.add(%simgroup.getObject(%i).getName()); + + } + + IODropdownMenu.sort(); + IODropdownMenu.setFirstSelected(0); + + IODropdownDlg.callback = %callback; + IODropdownDlg.cancelCallback = %cancelCallback; +} + +function IODropdownDlg::onSleep( %this ) +{ + %this.callback = ""; + %this.cancelCallback = ""; + IODropdownMenu.clear(); +} + +function CloseMessagePopup() +{ + Canvas.popDialog(MessagePopupDlg); +} + +//--------------------------------------------------------------------------------------------- +// "Old" message box function aliases for backwards-compatibility. +//--------------------------------------------------------------------------------------------- + +function MessageBoxOKOld( %title, %message, %callback ) +{ + MessageBoxOK( %title, %message, %callback ); +} +function MessageBoxOKCancelOld( %title, %message, %callback, %cancelCallback ) +{ + MessageBoxOKCancel( %title, %message, %callback, %cancelCallback ); +} +function MessageBoxYesNoOld( %title, %message, %yesCallback, %noCallback ) +{ + MessageBoxYesNo( %title, %message, %yesCallback, %noCallback ); +} diff --git a/Templates/Empty/game/core/scripts/gui/messageBoxes/messageBoxOk.ed.gui b/Templates/Empty/game/core/scripts/gui/messageBoxes/messageBoxOk.ed.gui new file mode 100644 index 000000000..52e119ea6 --- /dev/null +++ b/Templates/Empty/game/core/scripts/gui/messageBoxes/messageBoxOk.ed.gui @@ -0,0 +1,60 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(MessageBoxOKDlg) { + profile = "GuiOverlayProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new GuiWindowCtrl(MBOKFrame) { + profile = "GuiWindowProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "170 175"; + extent = "300 107"; + minExtent = "48 95"; + visible = "1"; + helpTag = "0"; + maxLength = "255"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + text = ""; + + new GuiMLTextCtrl(MBOKText) { + profile = "GuiMLTextProfile"; + horizSizing = "center"; + vertSizing = "bottom"; + position = "9 35"; + extent = "281 24"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "111 75"; + extent = "80 24"; + minExtent = "8 8"; + visible = "1"; + command = "MessageCallback(MessageBoxOKDlg,MessageBoxOKDlg.callback);"; + accelerator = "return"; + helpTag = "0"; + text = "Ok"; + simpleStyle = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/core/scripts/gui/messageBoxes/messageBoxOkCancel.ed.gui b/Templates/Empty/game/core/scripts/gui/messageBoxes/messageBoxOkCancel.ed.gui new file mode 100644 index 000000000..5f9c8f5dc --- /dev/null +++ b/Templates/Empty/game/core/scripts/gui/messageBoxes/messageBoxOkCancel.ed.gui @@ -0,0 +1,75 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(MessageBoxOKCancelDlg) { + profile = "GuiOverlayProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new GuiWindowCtrl(MBOKCancelFrame) { + profile = "GuiWindowProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "170 175"; + extent = "300 100"; + minExtent = "48 92"; + visible = "1"; + helpTag = "0"; + maxLength = "255"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + text = ""; + + new GuiMLTextCtrl(MBOKCancelText) { + profile = "GuiMLTextProfile"; + horizSizing = "center"; + vertSizing = "bottom"; + position = "8 34"; + extent = "283 24"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "66 68"; + extent = "80 24"; + minExtent = "8 8"; + visible = "1"; + command = "MessageCallback(MessageBoxOKCancelDlg,MessageBoxOKCancelDlg.callback);"; + accelerator = "return"; + helpTag = "0"; + text = "Ok"; + simpleStyle = "0"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "156 68"; + extent = "80 24"; + minExtent = "8 8"; + visible = "1"; + command = "MessageCallback(MessageBoxOKCancelDlg,MessageBoxOKCancelDlg.cancelCallback);"; + accelerator = "escape"; + helpTag = "0"; + text = "Cancel"; + simpleStyle = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/core/scripts/gui/messageBoxes/messageBoxSound.wav b/Templates/Empty/game/core/scripts/gui/messageBoxes/messageBoxSound.wav new file mode 100644 index 000000000..4b703bc31 Binary files /dev/null and b/Templates/Empty/game/core/scripts/gui/messageBoxes/messageBoxSound.wav differ diff --git a/Templates/Empty/game/core/scripts/gui/messageBoxes/messageBoxYesNo.ed.gui b/Templates/Empty/game/core/scripts/gui/messageBoxes/messageBoxYesNo.ed.gui new file mode 100644 index 000000000..3cd7d18ef --- /dev/null +++ b/Templates/Empty/game/core/scripts/gui/messageBoxes/messageBoxYesNo.ed.gui @@ -0,0 +1,75 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(MessageBoxYesNoDlg) { + profile = "GuiOverlayProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new GuiWindowCtrl(MBYesNoFrame) { + profile = "GuiWindowProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "170 175"; + extent = "300 100"; + minExtent = "48 92"; + visible = "1"; + helpTag = "0"; + maxLength = "255"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + text = ""; + closeCommand = "MessageCallback(MessageBoxYesNoDlg,MessageBoxYesNoDlg.noCallback);"; + + new GuiMLTextCtrl(MBYesNoText) { + profile = "GuiMLTextProfile"; + horizSizing = "center"; + vertSizing = "bottom"; + position = "11 38"; + extent = "280 14"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "70 68"; + extent = "80 22"; + minExtent = "8 8"; + visible = "1"; + command = "MessageCallback(MessageBoxYesNoDlg,MessageBoxYesNoDlg.yesCallback);"; + accelerator = "return"; + helpTag = "0"; + text = "Yes"; + simpleStyle = "0"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "167 68"; + extent = "80 22"; + minExtent = "8 8"; + visible = "1"; + command = "MessageCallback(MessageBoxYesNoDlg,MessageBoxYesNoDlg.noCallback);"; + accelerator = "escape"; + helpTag = "0"; + text = "No"; + simpleStyle = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/core/scripts/gui/messageBoxes/messageBoxYesNoCancel.ed.gui b/Templates/Empty/game/core/scripts/gui/messageBoxes/messageBoxYesNoCancel.ed.gui new file mode 100644 index 000000000..03257494d --- /dev/null +++ b/Templates/Empty/game/core/scripts/gui/messageBoxes/messageBoxYesNoCancel.ed.gui @@ -0,0 +1,103 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(MessageBoxYesNoCancelDlg) { + canSaveDynamicFields = "0"; + Profile = "GuiOverlayProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl(MBYesNoCancelFrame) { + canSaveDynamicFields = "0"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "250 235"; + Extent = "300 102"; + MinExtent = "48 92"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + maxLength = "255"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + text = ""; + closeCommand="MessageCallback(MessageBoxYesNoCancelDlg,MessageBoxYesNoCancelDlg.cancelCallback);"; + + new GuiMLTextCtrl(MBYesNoCancelText) { + canSaveDynamicFields = "0"; + Profile = "GuiMLTextProfile"; + HorizSizing = "center"; + VertSizing = "bottom"; + position = "7 38"; + Extent = "286 14"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "top"; + position = "7 71"; + Extent = "80 22"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "MessageCallback(MessageBoxYesNoCancelDlg,MessageBoxYesNoCancelDlg.yesCallback);"; + Accelerator = "return"; + hovertime = "1000"; + text = "Yes"; + groupNum = "-1"; + buttonType = "PushButton"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "top"; + position = "92 71"; + Extent = "80 22"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "MessageCallback(MessageBoxYesNoCancelDlg,MessageBoxYesNoCancelDlg.noCallback);"; + hovertime = "1000"; + text = "No"; + groupNum = "-1"; + buttonType = "PushButton"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "top"; + position = "213 71"; + Extent = "80 22"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "MessageCallback(MessageBoxYesNoCancelDlg,MessageBoxYesNoCancelDlg.cancelCallback);"; + Accelerator = "escape"; + hovertime = "1000"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/core/scripts/gui/messageBoxes/messagePopup.ed.gui b/Templates/Empty/game/core/scripts/gui/messageBoxes/messagePopup.ed.gui new file mode 100644 index 000000000..806f12204 --- /dev/null +++ b/Templates/Empty/game/core/scripts/gui/messageBoxes/messagePopup.ed.gui @@ -0,0 +1,46 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(MessagePopupDlg) { + profile = "GuiDefaultProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new GuiWindowCtrl(MessagePopFrame) { + profile = "GuiWindowProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "170 175"; + extent = "300 92"; + minExtent = "48 92"; + visible = "1"; + helpTag = "0"; + maxLength = "255"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + text = ""; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + + new GuiMLTextCtrl(MessagePopText) { + profile = "GuiMLTextProfile"; + horizSizing = "center"; + vertSizing = "bottom"; + position = "32 39"; + extent = "236 24"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/core/scripts/gui/optionsDlg.cs b/Templates/Empty/game/core/scripts/gui/optionsDlg.cs new file mode 100644 index 000000000..0784c7939 --- /dev/null +++ b/Templates/Empty/game/core/scripts/gui/optionsDlg.cs @@ -0,0 +1,844 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +/// Returns true if the current quality settings equal +/// this graphics quality level. +function GraphicsQualityLevel::isCurrent( %this ) +{ + // Test each pref to see if the current value + // equals our stored value. + + for ( %i=0; %i < %this.count(); %i++ ) + { + %pref = %this.getKey( %i ); + %value = %this.getValue( %i ); + + if ( getVariable( %pref ) !$= %value ) + return false; + } + + return true; +} + +/// Applies the graphics quality settings and calls +/// 'onApply' on itself or its parent group if its +/// been overloaded. +function GraphicsQualityLevel::apply( %this ) +{ + for ( %i=0; %i < %this.count(); %i++ ) + { + %pref = %this.getKey( %i ); + %value = %this.getValue( %i ); + setVariable( %pref, %value ); + } + + // If we have an overloaded onApply method then + // call it now to finalize the changes. + if ( %this.isMethod( "onApply" ) ) + %this.onApply(); + else + { + %group = %this.getGroup(); + if ( isObject( %group ) && %group.isMethod( "onApply" ) ) + %group.onApply( %this ); + } +} + +function GraphicsQualityPopup::init( %this, %qualityGroup ) +{ + assert( isObject( %this ) ); + assert( isObject( %qualityGroup ) ); + + // Clear the existing content first. + %this.clear(); + + // Fill it. + %select = -1; + for ( %i=0; %i < %qualityGroup.getCount(); %i++ ) + { + %level = %qualityGroup.getObject( %i ); + if ( %level.isCurrent() ) + %select = %i; + + %this.add( %level.getInternalName(), %i ); + } + + // Setup a default selection. + if ( %select == -1 ) + %this.setText( "Custom" ); + else + %this.setSelected( %select ); +} + +function GraphicsQualityPopup::apply( %this, %qualityGroup, %testNeedApply ) +{ + assert( isObject( %this ) ); + assert( isObject( %qualityGroup ) ); + + %quality = %this.getText(); + + %index = %this.findText( %quality ); + if ( %index == -1 ) + return false; + + %level = %qualityGroup.getObject( %index ); + if ( isObject( %level ) && !%level.isCurrent() ) + { + if ( %testNeedApply ) + return true; + + %level.apply(); + } + + return false; +} + +function OptionsDlg::setPane(%this, %pane) +{ + %this-->OptAudioPane.setVisible(false); + %this-->OptGraphicsPane.setVisible(false); + %this-->OptNetworkPane.setVisible(false); + %this-->OptControlsPane.setVisible(false); + + %this.findObjectByInternalName( "Opt" @ %pane @ "Pane", true ).setVisible(true); + + %this.fillRemapList(); + + // Update the state of the apply button. + %this._updateApplyState(); +} + +function OptionsDlg::onWake(%this) +{ + if ( isFunction("getWebDeployment") && getWebDeployment() ) + { + // Cannot enable full screen under web deployment + %this-->OptGraphicsFullscreenToggle.setStateOn( false ); + %this-->OptGraphicsFullscreenToggle.setVisible( false ); + } + else + { + %this-->OptGraphicsFullscreenToggle.setStateOn( Canvas.isFullScreen() ); + } + %this-->OptGraphicsVSyncToggle.setStateOn( !$pref::Video::disableVerticalSync ); + + OptionsDlg.initResMenu(); + %resSelId = OptionsDlg-->OptGraphicsResolutionMenu.findText( _makePrettyResString( $pref::Video::mode ) ); + if( %resSelId != -1 ) + OptionsDlg-->OptGraphicsResolutionMenu.setSelected( %resSelId ); + + OptGraphicsDriverMenu.clear(); + + %buffer = getDisplayDeviceList(); + %count = getFieldCount( %buffer ); + for(%i = 0; %i < %count; %i++) + OptGraphicsDriverMenu.add(getField(%buffer, %i), %i); + + %selId = OptGraphicsDriverMenu.findText( getDisplayDeviceInformation() ); + if ( %selId == -1 ) + OptGraphicsDriverMenu.setFirstSelected(); + else + OptGraphicsDriverMenu.setSelected( %selId ); + + // Setup the graphics quality dropdown menus. + %this-->OptMeshQualityPopup.init( MeshQualityGroup ); + %this-->OptTextureQualityPopup.init( TextureQualityGroup ); + %this-->OptLightingQualityPopup.init( LightingQualityGroup ); + %this-->OptShaderQualityPopup.init( ShaderQualityGroup ); + + // Setup the anisotropic filtering menu. + %ansioCtrl = %this-->OptAnisotropicPopup; + %ansioCtrl.clear(); + %ansioCtrl.add( "Off", 0 ); + %ansioCtrl.add( "4X", 4 ); + %ansioCtrl.add( "8X", 8 ); + %ansioCtrl.add( "16X", 16 ); + %ansioCtrl.setSelected( $pref::Video::defaultAnisotropy, false ); + + // set up the Refresh Rate menu. + %refreshMenu = %this-->OptRefreshSelectMenu; + %refreshMenu.clear(); + // %refreshMenu.add("Auto", 60); + %refreshMenu.add("60", 60); + %refreshMenu.add("75", 75); + %refreshMenu.setSelected( getWord( $pref::Video::mode, $WORD::REFRESH ) ); + + // Audio + //OptAudioHardwareToggle.setStateOn($pref::SFX::useHardware); + //OptAudioHardwareToggle.setActive( true ); + + %this-->OptAudioVolumeMaster.setValue( $pref::SFX::masterVolume ); + %this-->OptAudioVolumeShell.setValue( $pref::SFX::channelVolume[ $GuiAudioType] ); + %this-->OptAudioVolumeSim.setValue( $pref::SFX::channelVolume[ $SimAudioType ] ); + %this-->OptAudioVolumeMusic.setValue( $pref::SFX::channelVolume[ $MusicAudioType ] ); + + OptAudioProviderList.clear(); + %buffer = sfxGetAvailableDevices(); + %count = getRecordCount( %buffer ); + for(%i = 0; %i < %count; %i++) + { + %record = getRecord(%buffer, %i); + %provider = getField(%record, 0); + + if ( OptAudioProviderList.findText( %provider ) == -1 ) + OptAudioProviderList.add( %provider, %i ); + } + + OptAudioProviderList.sort(); + + %selId = OptAudioProviderList.findText($pref::SFX::provider); + if ( %selId == -1 ) + OptAudioProviderList.setFirstSelected(); + else + OptAudioProviderList.setSelected( %selId ); + + // Populate the Anti-aliasing popup. + %aaMenu = %this-->OptAAQualityPopup; + %aaMenu.clear(); + %aaMenu.Add( "Off", 0 ); + %aaMenu.Add( "1x", 1 ); + %aaMenu.Add( "2x", 2 ); + %aaMenu.Add( "4x", 4 ); + %aaMenu.setSelected( getWord( $pref::Video::mode, $WORD::AA ) ); + + OptMouseSensitivity.value = $pref::Input::LinkMouseSensitivity; + + // Set the graphics pane to start. + %this-->OptGraphicsButton.performClick(); +} + +function OptionsDlg::onSleep(%this) +{ + // write out the control config into the rw/config.cs file + moveMap.save( "scripts/client/config.cs" ); +} + +function OptGraphicsDriverMenu::onSelect( %this, %id, %text ) +{ + // Attempt to keep the same resolution settings: + %resMenu = OptionsDlg-->OptGraphicsResolutionMenu; + %currRes = %resMenu.getText(); + + // If its empty the use the current. + if ( %currRes $= "" ) + %currRes = _makePrettyResString( Canvas.getVideoMode() ); + + // Fill the resolution list. + optionsDlg.initResMenu(); + + // Try to select the previous settings: + %selId = %resMenu.findText( %currRes ); + if ( %selId == -1 ) + %selId = 0; + %resMenu.setSelected( %selId ); + + OptionsDlg._updateApplyState(); +} + +function _makePrettyResString( %resString ) +{ + %width = getWord( %resString, $WORD::RES_X ); + %height = getWord( %resString, $WORD::RES_Y ); + + %aspect = %width / %height; + %aspect = mRound( %aspect * 100 ) * 0.01; + + switch$( %aspect ) + { + case "1.33": + %aspect = "4:3"; + case "1.78": + %aspect = "16:9"; + default: + %aspect = ""; + } + + %outRes = %width @ " x " @ %height; + if ( %aspect !$= "" ) + %outRes = %outRes @ " (" @ %aspect @ ")"; + + return %outRes; +} + +function OptionsDlg::initResMenu( %this ) +{ + // Clear out previous values + %resMenu = %this-->OptGraphicsResolutionMenu; + %resMenu.clear(); + + // If we are in a browser then we can't change our resolution through + // the options dialog + if (getWebDeployment()) + { + %count = 0; + %currRes = getWords(Canvas.getVideoMode(), $WORD::RES_X, $WORD::RES_Y); + %resMenu.add(%currRes, %count); + %count++; + + return; + } + + // Loop through all and add all valid resolutions + %count = 0; + %resCount = Canvas.getModeCount(); + for (%i = 0; %i < %resCount; %i++) + { + %testResString = Canvas.getMode( %i ); + %testRes = _makePrettyResString( %testResString ); + + // Only add to list if it isn't there already. + if (%resMenu.findText(%testRes) == -1) + { + %resMenu.add(%testRes, %i); + %count++; + } + } + + %resMenu.sort(); +} + +function OptionsDlg::applyGraphics( %this, %testNeedApply ) +{ + %newAdapter = OptGraphicsDriverMenu.getText(); + %numAdapters = GFXInit::getAdapterCount(); + %newDevice = $pref::Video::displayDevice; + + for( %i = 0; %i < %numAdapters; %i ++ ) + if( GFXInit::getAdapterName( %i ) $= %newAdapter ) + { + %newDevice = GFXInit::getAdapterType( %i ); + break; + } + + // Change the device. + if ( %newDevice !$= $pref::Video::displayDevice ) + { + if ( %testNeedApply ) + return true; + + $pref::Video::displayDevice = %newDevice; + if( %newAdapter !$= getDisplayDeviceInformation() ) + MessageBoxOK( "Change requires restart", "Please restart the game for a display device change to take effect." ); + } + + // Gather the new video mode. + if ( isFunction("getWebDeployment") && getWebDeployment() ) + { + // Under web deployment, we use the custom resolution rather than a Canvas + // defined one. + %newRes = %this-->OptGraphicsResolutionMenu.getText(); + } + else + { + %newRes = getWords( Canvas.getMode( %this-->OptGraphicsResolutionMenu.getSelected() ), $WORD::RES_X, $WORD::RES_Y ); + } + %newBpp = 32; // ... its not 1997 anymore. + %newFullScreen = %this-->OptGraphicsFullscreenToggle.getValue() ? "true" : "false"; + %newRefresh = %this-->OptRefreshSelectMenu.getSelected(); + %newVsync = !%this-->OptGraphicsVSyncToggle.getValue(); + %newFSAA = %this-->OptAAQualityPopup.getSelected(); + + // Under web deployment we can't be full screen. + if ( isFunction("getWebDeployment") && getWebDeployment() ) + { + %newFullScreen = false; + } + else if ( %newFullScreen $= "false" ) + { + // If we're in windowed mode switch the fullscreen check + // if the resolution is bigger than the desktop. + %deskRes = getDesktopResolution(); + %deskResX = getWord(%deskRes, $WORD::RES_X); + %deskResY = getWord(%deskRes, $WORD::RES_Y); + if ( getWord( %newRes, $WORD::RES_X ) > %deskResX || + getWord( %newRes, $WORD::RES_Y ) > %deskResY ) + { + %newFullScreen = "true"; + %this-->OptGraphicsFullscreenToggle.setStateOn( true ); + } + } + + // Build the final mode string. + %newMode = %newRes SPC %newFullScreen SPC %newBpp SPC %newRefresh SPC %newFSAA; + + // Change the video mode. + if ( %newMode !$= $pref::Video::mode || + %newVsync != $pref::Video::disableVerticalSync ) + { + if ( %testNeedApply ) + return true; + + $pref::Video::mode = %newMode; + $pref::Video::disableVerticalSync = %newVsync; + configureCanvas(); + } + + // Test and apply the graphics settings. + if ( %this-->OptMeshQualityPopup.apply( MeshQualityGroup, %testNeedApply ) ) return true; + if ( %this-->OptTextureQualityPopup.apply( TextureQualityGroup, %testNeedApply ) ) return true; + if ( %this-->OptLightingQualityPopup.apply( LightingQualityGroup, %testNeedApply ) ) return true; + if ( %this-->OptShaderQualityPopup.apply( ShaderQualityGroup, %testNeedApply ) ) return true; + + // Check the anisotropic filtering. + %level = %this-->OptAnisotropicPopup.getSelected(); + if ( %level != $pref::Video::defaultAnisotropy ) + { + if ( %testNeedApply ) + return true; + + $pref::Video::defaultAnisotropy = %level; + } + + // If we're applying the state then recheck the + // state to update the apply button. + if ( !%testNeedApply ) + %this._updateApplyState(); + + return false; +} + +function OptionsDlg::_updateApplyState( %this ) +{ + %applyCtrl = %this-->Apply; + %graphicsPane = %this-->OptGraphicsPane; + + assert( isObject( %applyCtrl ) ); + assert( isObject( %graphicsPane ) ); + + %applyCtrl.active = %graphicsPane.isVisible() && %this.applyGraphics( true ); +} + +function OptionsDlg::_autoDetectQuality( %this ) +{ + %msg = GraphicsQualityAutodetect(); + %this.onWake(); + + if ( %msg !$= "" ) + { + MessageBoxOK( "Notice", %msg ); + } +} + +$RemapCount = 0; +$RemapName[$RemapCount] = "Forward"; +$RemapCmd[$RemapCount] = "moveforward"; +$RemapCount++; +$RemapName[$RemapCount] = "Backward"; +$RemapCmd[$RemapCount] = "movebackward"; +$RemapCount++; +$RemapName[$RemapCount] = "Strafe Left"; +$RemapCmd[$RemapCount] = "moveleft"; +$RemapCount++; +$RemapName[$RemapCount] = "Strafe Right"; +$RemapCmd[$RemapCount] = "moveright"; +$RemapCount++; +$RemapName[$RemapCount] = "Turn Left"; +$RemapCmd[$RemapCount] = "turnLeft"; +$RemapCount++; +$RemapName[$RemapCount] = "Turn Right"; +$RemapCmd[$RemapCount] = "turnRight"; +$RemapCount++; +$RemapName[$RemapCount] = "Look Up"; +$RemapCmd[$RemapCount] = "panUp"; +$RemapCount++; +$RemapName[$RemapCount] = "Look Down"; +$RemapCmd[$RemapCount] = "panDown"; +$RemapCount++; +$RemapName[$RemapCount] = "Jump"; +$RemapCmd[$RemapCount] = "jump"; +$RemapCount++; +$RemapName[$RemapCount] = "Fire Weapon"; +$RemapCmd[$RemapCount] = "mouseFire"; +$RemapCount++; +$RemapName[$RemapCount] = "Adjust Zoom"; +$RemapCmd[$RemapCount] = "setZoomFov"; +$RemapCount++; +$RemapName[$RemapCount] = "Toggle Zoom"; +$RemapCmd[$RemapCount] = "toggleZoom"; +$RemapCount++; +$RemapName[$RemapCount] = "Free Look"; +$RemapCmd[$RemapCount] = "toggleFreeLook"; +$RemapCount++; +$RemapName[$RemapCount] = "Switch 1st/3rd"; +$RemapCmd[$RemapCount] = "toggleFirstPerson"; +$RemapCount++; +$RemapName[$RemapCount] = "Chat to Everyone"; +$RemapCmd[$RemapCount] = "toggleMessageHud"; +$RemapCount++; +$RemapName[$RemapCount] = "Message Hud PageUp"; +$RemapCmd[$RemapCount] = "pageMessageHudUp"; +$RemapCount++; +$RemapName[$RemapCount] = "Message Hud PageDown"; +$RemapCmd[$RemapCount] = "pageMessageHudDown"; +$RemapCount++; +$RemapName[$RemapCount] = "Resize Message Hud"; +$RemapCmd[$RemapCount] = "resizeMessageHud"; +$RemapCount++; +$RemapName[$RemapCount] = "Show Scores"; +$RemapCmd[$RemapCount] = "showPlayerList"; +$RemapCount++; +$RemapName[$RemapCount] = "Animation - Wave"; +$RemapCmd[$RemapCount] = "celebrationWave"; +$RemapCount++; +$RemapName[$RemapCount] = "Animation - Salute"; +$RemapCmd[$RemapCount] = "celebrationSalute"; +$RemapCount++; +$RemapName[$RemapCount] = "Suicide"; +$RemapCmd[$RemapCount] = "suicide"; +$RemapCount++; +$RemapName[$RemapCount] = "Toggle Camera"; +$RemapCmd[$RemapCount] = "toggleCamera"; +$RemapCount++; +$RemapName[$RemapCount] = "Drop Camera at Player"; +$RemapCmd[$RemapCount] = "dropCameraAtPlayer"; +$RemapCount++; +$RemapName[$RemapCount] = "Drop Player at Camera"; +$RemapCmd[$RemapCount] = "dropPlayerAtCamera"; +$RemapCount++; +$RemapName[$RemapCount] = "Bring up Options Dialog"; +$RemapCmd[$RemapCount] = "bringUpOptions"; +$RemapCount++; + + +function restoreDefaultMappings() +{ + moveMap.delete(); + exec( "scripts/client/default.bind.cs" ); + optionsDlg.fillRemapList(); +} + +function getMapDisplayName( %device, %action ) +{ + if ( %device $= "keyboard" ) + return( %action ); + else if ( strstr( %device, "mouse" ) != -1 ) + { + // Substitute "mouse" for "button" in the action string: + %pos = strstr( %action, "button" ); + if ( %pos != -1 ) + { + %mods = getSubStr( %action, 0, %pos ); + %object = getSubStr( %action, %pos, 1000 ); + %instance = getSubStr( %object, strlen( "button" ), 1000 ); + return( %mods @ "mouse" @ ( %instance + 1 ) ); + } + else + error( "Mouse input object other than button passed to getDisplayMapName!" ); + } + else if ( strstr( %device, "joystick" ) != -1 ) + { + // Substitute "joystick" for "button" in the action string: + %pos = strstr( %action, "button" ); + if ( %pos != -1 ) + { + %mods = getSubStr( %action, 0, %pos ); + %object = getSubStr( %action, %pos, 1000 ); + %instance = getSubStr( %object, strlen( "button" ), 1000 ); + return( %mods @ "joystick" @ ( %instance + 1 ) ); + } + else + { + %pos = strstr( %action, "pov" ); + if ( %pos != -1 ) + { + %wordCount = getWordCount( %action ); + %mods = %wordCount > 1 ? getWords( %action, 0, %wordCount - 2 ) @ " " : ""; + %object = getWord( %action, %wordCount - 1 ); + switch$ ( %object ) + { + case "upov": %object = "POV1 up"; + case "dpov": %object = "POV1 down"; + case "lpov": %object = "POV1 left"; + case "rpov": %object = "POV1 right"; + case "upov2": %object = "POV2 up"; + case "dpov2": %object = "POV2 down"; + case "lpov2": %object = "POV2 left"; + case "rpov2": %object = "POV2 right"; + default: %object = "??"; + } + return( %mods @ %object ); + } + else + error( "Unsupported Joystick input object passed to getDisplayMapName!" ); + } + } + + return( "??" ); +} + +function buildFullMapString( %index ) +{ + %name = $RemapName[%index]; + %cmd = $RemapCmd[%index]; + + %temp = moveMap.getBinding( %cmd ); + if ( %temp $= "" ) + return %name TAB ""; + + %mapString = ""; + + %count = getFieldCount( %temp ); + for ( %i = 0; %i < %count; %i += 2 ) + { + if ( %mapString !$= "" ) + %mapString = %mapString @ ", "; + + %device = getField( %temp, %i + 0 ); + %object = getField( %temp, %i + 1 ); + %mapString = %mapString @ getMapDisplayName( %device, %object ); + } + + return %name TAB %mapString; +} + +function OptionsDlg::fillRemapList( %this ) +{ + %remapList = %this-->OptRemapList; + + %remapList.clear(); + for ( %i = 0; %i < $RemapCount; %i++ ) + %remapList.addRow( %i, buildFullMapString( %i ) ); +} + +function OptionsDlg::doRemap( %this ) +{ + %remapList = %this-->OptRemapList; + + %selId = %remapList.getSelectedId(); + %name = $RemapName[%selId]; + + RemapDlg-->OptRemapText.setValue( "Re-bind \"" @ %name @ "\" to..." ); + OptRemapInputCtrl.index = %selId; + Canvas.pushDialog( RemapDlg ); +} + +function redoMapping( %device, %action, %cmd, %oldIndex, %newIndex ) +{ + //%actionMap.bind( %device, %action, $RemapCmd[%newIndex] ); + moveMap.bind( %device, %action, %cmd ); + + %remapList = %this-->OptRemapList; + %remapList.setRowById( %oldIndex, buildFullMapString( %oldIndex ) ); + %remapList.setRowById( %newIndex, buildFullMapString( %newIndex ) ); +} + +function findRemapCmdIndex( %command ) +{ + for ( %i = 0; %i < $RemapCount; %i++ ) + { + if ( %command $= $RemapCmd[%i] ) + return( %i ); + } + return( -1 ); +} + +/// This unbinds actions beyond %count associated to the +/// particular moveMap %commmand. +function unbindExtraActions( %command, %count ) +{ + %temp = moveMap.getBinding( %command ); + if ( %temp $= "" ) + return; + + %count = getFieldCount( %temp ) - ( %count * 2 ); + for ( %i = 0; %i < %count; %i += 2 ) + { + %device = getField( %temp, %i + 0 ); + %action = getField( %temp, %i + 1 ); + + moveMap.unbind( %device, %action ); + } +} + +function OptRemapInputCtrl::onInputEvent( %this, %device, %action ) +{ + //error( "** onInputEvent called - device = " @ %device @ ", action = " @ %action @ " **" ); + Canvas.popDialog( RemapDlg ); + + // Test for the reserved keystrokes: + if ( %device $= "keyboard" ) + { + // Cancel... + if ( %action $= "escape" ) + { + // Do nothing... + return; + } + } + + %cmd = $RemapCmd[%this.index]; + %name = $RemapName[%this.index]; + + // Grab the friendly display name for this action + // which we'll use when prompting the user below. + %mapName = getMapDisplayName( %device, %action ); + + // Get the current command this action is mapped to. + %prevMap = moveMap.getCommand( %device, %action ); + + // If nothing was mapped to the previous command + // mapping then it's easy... just bind it. + if ( %prevMap $= "" ) + { + unbindExtraActions( %cmd, 1 ); + moveMap.bind( %device, %action, %cmd ); + optionsDlg-->OptRemapList.setRowById( %this.index, buildFullMapString( %this.index ) ); + return; + } + + // If the previous command is the same as the + // current then they hit the same input as what + // was already assigned. + if ( %prevMap $= %cmd ) + { + unbindExtraActions( %cmd, 0 ); + moveMap.bind( %device, %action, %cmd ); + optionsDlg-->OptRemapList.setRowById( %this.index, buildFullMapString( %this.index ) ); + return; + } + + // Look for the index of the previous mapping. + %prevMapIndex = findRemapCmdIndex( %prevMap ); + + // If we get a negative index then the previous + // mapping was to an item that isn't included in + // the mapping list... so we cannot unmap it. + if ( %prevMapIndex == -1 ) + { + MessageBoxOK( "Remap Failed", "\"" @ %mapName @ "\" is already bound to a non-remappable command!" ); + return; + } + + // Setup the forced remapping callback command. + %callback = "redoMapping(" @ %device @ ", \"" @ %action @ "\", \"" @ + %cmd @ "\", " @ %prevMapIndex @ ", " @ %this.index @ ");"; + + // Warn that we're about to remove the old mapping and + // replace it with another. + %prevCmdName = $RemapName[%prevMapIndex]; + MessageBoxYesNo( "Warning", + "\"" @ %mapName @ "\" is already bound to \"" + @ %prevCmdName @ "\"!\nDo you wish to replace this mapping?", + %callback, "" ); +} + +$AudioTestHandle = 0; +// Description to use for playing the volume test sound. This isn't +// played with the description of the channel that has its volume changed +// because we know nothing about the playback state of the channel. If it +// is paused or stopped, the test sound would not play then. +$AudioTestDescription = new SFXDescription() +{ + sourceGroup = AudioChannelMaster; +}; + +function OptAudioUpdateMasterVolume( %volume ) +{ + if( %volume == $pref::SFX::masterVolume ) + return; + + sfxSetMasterVolume( %volume ); + $pref::SFX::masterVolume = %volume; + + if( !isObject( $AudioTestHandle ) ) + $AudioTestHandle = sfxPlayOnce( AudioChannel, "core/art/sound/volumeTest.wav" ); +} + +function OptAudioUpdateChannelVolume( %description, %volume ) +{ + %channel = sfxGroupToOldChannel( %description.sourceGroup ); + + if( %volume == $pref::SFX::channelVolume[ %channel ] ) + return; + + sfxSetChannelVolume( %channel, %volume ); + $pref::SFX::channelVolume[ %channel ] = %volume; + + if( !isObject( $AudioTestHandle ) ) + { + $AudioTestDescription.volume = %volume; + $AudioTestHandle = sfxPlayOnce( $AudioTestDescription, "core/art/sound/volumeTest.wav" ); + } +} + +function OptAudioProviderList::onSelect( %this, %id, %text ) +{ + // Skip empty provider selections. + if ( %text $= "" ) + return; + + $pref::SFX::provider = %text; + OptAudioDeviceList.clear(); + + %buffer = sfxGetAvailableDevices(); + %count = getRecordCount( %buffer ); + for(%i = 0; %i < %count; %i++) + { + %record = getRecord(%buffer, %i); + %provider = getField(%record, 0); + %device = getField(%record, 1); + + if (%provider !$= %text) + continue; + + if ( OptAudioDeviceList.findText( %device ) == -1 ) + OptAudioDeviceList.add( %device, %i ); + } + + // Find the previous selected device. + %selId = OptAudioDeviceList.findText($pref::SFX::device); + if ( %selId == -1 ) + OptAudioDeviceList.setFirstSelected(); + else + OptAudioDeviceList.setSelected( %selId ); +} + +function OptAudioDeviceList::onSelect( %this, %id, %text ) +{ + // Skip empty selections. + if ( %text $= "" ) + return; + + $pref::SFX::device = %text; + + if ( !sfxCreateDevice( $pref::SFX::provider, + $pref::SFX::device, + $pref::SFX::useHardware, + -1 ) ) + error( "Unable to create SFX device: " @ $pref::SFX::provider + SPC $pref::SFX::device + SPC $pref::SFX::useHardware ); +} + +function OptMouseSetSensitivity(%value) +{ + $pref::Input::LinkMouseSensitivity = %value; +} + +/* +function OptAudioHardwareToggle::onClick(%this) +{ + if (!sfxCreateDevice($pref::SFX::provider, $pref::SFX::device, $pref::SFX::useHardware, -1)) + error("Unable to create SFX device: " @ $pref::SFX::provider SPC $pref::SFX::device SPC $pref::SFX::useHardware); +} +*/ diff --git a/Templates/Empty/game/core/scripts/server/audio.cs b/Templates/Empty/game/core/scripts/server/audio.cs new file mode 100644 index 000000000..67b2fbf5e --- /dev/null +++ b/Templates/Empty/game/core/scripts/server/audio.cs @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- + +function ServerPlay2D(%profile) +{ + // Play the given sound profile on every client. + // The sounds will be transmitted as an event, not attached to any object. + for(%idx = 0; %idx < ClientGroup.getCount(); %idx++) + ClientGroup.getObject(%idx).play2D(%profile); +} + +function ServerPlay3D(%profile,%transform) +{ + // Play the given sound profile at the given position on every client + // The sound will be transmitted as an event, not attached to any object. + for(%idx = 0; %idx < ClientGroup.getCount(); %idx++) + ClientGroup.getObject(%idx).play3D(%profile,%transform); +} + diff --git a/Templates/Empty/game/core/scripts/server/camera.cs b/Templates/Empty/game/core/scripts/server/camera.cs new file mode 100644 index 000000000..e0c597148 --- /dev/null +++ b/Templates/Empty/game/core/scripts/server/camera.cs @@ -0,0 +1,85 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Global movement speed that affects all cameras. This should be moved +// into the camera datablock. +$Camera::movementSpeed = 30; + +function Observer::onTrigger(%this,%obj,%trigger,%state) +{ + // state = 0 means that a trigger key was released + if (%state == 0) + return; + + // Default player triggers: 0=fire 1=altFire 2=jump + %client = %obj.getControllingClient(); + switch$ (%obj.mode) + { + case "Observer": + // Do something interesting. + + case "Corpse": + // Viewing dead corpse, so we probably want to respawn. + %client.spawnPlayer(); + + // Set the camera back into observer mode, since in + // debug mode we like to switch to it. + %this.setMode(%obj,"Observer"); + } +} + +function Observer::setMode(%this,%obj,%mode,%arg1,%arg2,%arg3) +{ + switch$ (%mode) + { + case "Observer": + // Let the player fly around + %obj.setFlyMode(); + + case "Corpse": + // Lock the camera down in orbit around the corpse, + // which should be arg1 + %transform = %arg1.getTransform(); + %obj.setOrbitMode(%arg1, %transform, 0.5, 4.5, 4.5); + + } + %obj.mode = %mode; +} + + +//----------------------------------------------------------------------------- +// Camera methods +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- + +function Camera::onAdd(%this,%obj) +{ + // Default start mode + %this.setMode(%this.mode); +} + +function Camera::setMode(%this,%mode,%arg1,%arg2,%arg3) +{ + // Punt this one over to our datablock + %this.getDatablock().setMode(%this,%mode,%arg1,%arg2,%arg3); +} diff --git a/Templates/Empty/game/core/scripts/server/centerPrint.cs b/Templates/Empty/game/core/scripts/server/centerPrint.cs new file mode 100644 index 000000000..7832a233d --- /dev/null +++ b/Templates/Empty/game/core/scripts/server/centerPrint.cs @@ -0,0 +1,104 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function centerPrintAll( %message, %time, %lines ) +{ + if( %lines $= "" || ((%lines > 3) || (%lines < 1)) ) + %lines = 1; + + %count = ClientGroup.getCount(); + for (%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + if( !%cl.isAIControlled() ) + commandToClient( %cl, 'centerPrint', %message, %time, %lines ); + } +} + +function bottomPrintAll( %message, %time, %lines ) +{ + if( %lines $= "" || ((%lines > 3) || (%lines < 1)) ) + %lines = 1; + + %count = ClientGroup.getCount(); + for (%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + if( !%cl.isAIControlled() ) + commandToClient( %cl, 'bottomPrint', %message, %time, %lines ); + } +} + +//------------------------------------------------------------------------------------------------------- + +function centerPrint( %client, %message, %time, %lines ) +{ + if( %lines $= "" || ((%lines > 3) || (%lines < 1)) ) + %lines = 1; + + + commandToClient( %client, 'CenterPrint', %message, %time, %lines ); +} + +function bottomPrint( %client, %message, %time, %lines ) +{ + if( %lines $= "" || ((%lines > 3) || (%lines < 1)) ) + %lines = 1; + + commandToClient( %client, 'BottomPrint', %message, %time, %lines ); +} + +//------------------------------------------------------------------------------------------------------- + +function clearCenterPrint( %client ) +{ + commandToClient( %client, 'ClearCenterPrint'); +} + +function clearBottomPrint( %client ) +{ + commandToClient( %client, 'ClearBottomPrint'); +} + +//------------------------------------------------------------------------------------------------------- + +function clearCenterPrintAll() +{ + %count = ClientGroup.getCount(); + for (%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + if( !%cl.isAIControlled() ) + commandToClient( %cl, 'ClearCenterPrint'); + } +} + +function clearBottomPrintAll() +{ + %count = ClientGroup.getCount(); + for (%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + if( !%cl.isAIControlled() ) + commandToClient( %cl, 'ClearBottomPrint'); + } +} \ No newline at end of file diff --git a/Templates/Empty/game/core/scripts/server/clientConnection.cs b/Templates/Empty/game/core/scripts/server/clientConnection.cs new file mode 100644 index 000000000..e1c359d71 --- /dev/null +++ b/Templates/Empty/game/core/scripts/server/clientConnection.cs @@ -0,0 +1,235 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +// This script function is called before a client connection +// is accepted. Returning "" will accept the connection, +// anything else will be sent back as an error to the client. +// All the connect args are passed also to onConnectRequest +// +function GameConnection::onConnectRequest( %client, %netAddress, %name ) +{ + echo("Connect request from: " @ %netAddress); + if($Server::PlayerCount >= $pref::Server::MaxPlayers) + return "CR_SERVERFULL"; + return ""; +} + +//----------------------------------------------------------------------------- +// This script function is the first called on a client accept +// +function GameConnection::onConnect( %client, %name ) +{ + // Send down the connection error info, the client is + // responsible for displaying this message if a connection + // error occures. + messageClient(%client,'MsgConnectionError',"",$Pref::Server::ConnectionError); + + // Send mission information to the client + sendLoadInfoToClient( %client ); + + // Simulated client lag for testing... + // %client.setSimulatedNetParams(0.1, 30); + + // Get the client's unique id: + // %authInfo = %client.getAuthInfo(); + // %client.guid = getField( %authInfo, 3 ); + %client.guid = 0; + addToServerGuidList( %client.guid ); + + // Set admin status + if (%client.getAddress() $= "local") { + %client.isAdmin = true; + %client.isSuperAdmin = true; + } + else { + %client.isAdmin = false; + %client.isSuperAdmin = false; + } + + // Save client preferences on the connection object for later use. + %client.gender = "Male"; + %client.armor = "Light"; + %client.race = "Human"; + %client.skin = addTaggedString( "base" ); + %client.setPlayerName(%name); + %client.team = ""; + %client.score = 0; + + // + echo("CADD: " @ %client @ " " @ %client.getAddress()); + + // Inform the client of all the other clients + %count = ClientGroup.getCount(); + for (%cl = 0; %cl < %count; %cl++) { + %other = ClientGroup.getObject(%cl); + if ((%other != %client)) { + // These should be "silent" versions of these messages... + messageClient(%client, 'MsgClientJoin', "", + %other.playerName, + %other, + %other.sendGuid, + %other.team, + %other.score, + %other.isAIControlled(), + %other.isAdmin, + %other.isSuperAdmin); + } + } + + // Inform the client we've joined up + messageClient(%client, + 'MsgClientJoin', 'Welcome to a Torque application %1.', + %client.playerName, + %client, + %client.sendGuid, + %client.team, + %client.score, + %client.isAiControlled(), + %client.isAdmin, + %client.isSuperAdmin); + + // Inform all the other clients of the new guy + messageAllExcept(%client, -1, 'MsgClientJoin', '\c1%1 joined the game.', + %client.playerName, + %client, + %client.sendGuid, + %client.team, + %client.score, + %client.isAiControlled(), + %client.isAdmin, + %client.isSuperAdmin); + + // If the mission is running, go ahead download it to the client + if ($missionRunning) + { + %client.loadMission(); + } + else if ($Server::LoadFailMsg !$= "") + { + messageClient(%client, 'MsgLoadFailed', $Server::LoadFailMsg); + } + $Server::PlayerCount++; +} + +//----------------------------------------------------------------------------- +// A player's name could be obtained from the auth server, but for +// now we use the one passed from the client. +// %realName = getField( %authInfo, 0 ); +// +function GameConnection::setPlayerName(%client,%name) +{ + %client.sendGuid = 0; + + // Minimum length requirements + %name = trim( strToPlayerName( %name ) ); + if ( strlen( %name ) < 3 ) + %name = "Poser"; + + // Make sure the alias is unique, we'll hit something eventually + if (!isNameUnique(%name)) + { + %isUnique = false; + for (%suffix = 1; !%isUnique; %suffix++) { + %nameTry = %name @ "." @ %suffix; + %isUnique = isNameUnique(%nameTry); + } + %name = %nameTry; + } + + // Tag the name with the "smurf" color: + %client.nameBase = %name; + %client.playerName = addTaggedString("\cp\c8" @ %name @ "\co"); +} + +function isNameUnique(%name) +{ + %count = ClientGroup.getCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %test = ClientGroup.getObject( %i ); + %rawName = stripChars( detag( getTaggedString( %test.playerName ) ), "\cp\co\c6\c7\c8\c9" ); + if ( strcmp( %name, %rawName ) == 0 ) + return false; + } + return true; +} + +//----------------------------------------------------------------------------- +// This function is called when a client drops for any reason +// +function GameConnection::onDrop(%client, %reason) +{ + %client.onClientLeaveGame(); + + removeFromServerGuidList( %client.guid ); + messageAllExcept(%client, -1, 'MsgClientDrop', '\c1%1 has left the game.', %client.playerName, %client); + + removeTaggedString(%client.playerName); + echo("CDROP: " @ %client @ " " @ %client.getAddress()); + $Server::PlayerCount--; + + // Reset the server if everyone has left the game + if( $Server::PlayerCount == 0 && $Server::Dedicated) + schedule(0, 0, "resetServerDefaults"); +} + + +//----------------------------------------------------------------------------- + +function GameConnection::startMission(%this) +{ + // Inform the client the mission starting + commandToClient(%this, 'MissionStart', $missionSequence); +} + + +function GameConnection::endMission(%this) +{ + // Inform the client the mission is done. Note that if this is + // called as part of the server destruction routine, the client will + // actually never see this comment since the client connection will + // be destroyed before another round of command processing occurs. + // In this case, the client will only see the disconnect from the server + // and should manually trigger a mission cleanup. + commandToClient(%this, 'MissionEnd', $missionSequence); +} + + +//-------------------------------------------------------------------------- +// Sync the clock on the client. + +function GameConnection::syncClock(%client, %time) +{ + commandToClient(%client, 'syncClock', %time); +} + + +//-------------------------------------------------------------------------- +// Update all the clients with the new score + +function GameConnection::incScore(%this,%delta) +{ + %this.score += %delta; + messageAll('MsgClientScoreChanged', "", %this.score, %this); +} diff --git a/Templates/Empty/game/core/scripts/server/commands.cs b/Templates/Empty/game/core/scripts/server/commands.cs new file mode 100644 index 000000000..fc168be93 --- /dev/null +++ b/Templates/Empty/game/core/scripts/server/commands.cs @@ -0,0 +1,248 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Misc. server commands avialable to clients +//----------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +// Debug commands +//---------------------------------------------------------------------------- + +function serverCmdNetSimulateLag( %client, %msDelay, %packetLossPercent ) +{ + if ( %client.isAdmin ) + %client.setSimulatedNetParams( %packetLossPercent / 100.0, %msDelay ); +} + +//---------------------------------------------------------------------------- +// Camera commands +//---------------------------------------------------------------------------- +function serverCmdTogglePathCamera(%client, %val) +{ + if(%val) + { + %control = %client.PathCamera; + } + else + { + %control = %client.camera; + } + %client.setControlObject(%control); + clientCmdSyncEditorGui(); +} +function serverCmdToggleCamera(%client) +{ + if (%client.getControlObject() == %client.player) + { + %client.camera.setVelocity("0 0 0"); + %control = %client.camera; + } + else + { + %client.player.setVelocity("0 0 0"); + %control = %client.player; + } + %client.setControlObject(%control); + clientCmdSyncEditorGui(); +} + +function serverCmdSetEditorCameraPlayer(%client) +{ + // Switch to Player Mode + %client.player.setVelocity("0 0 0"); + %client.setControlObject(%client.player); + ServerConnection.setFirstPerson(1); + $isFirstPersonVar = 1; + + clientCmdSyncEditorGui(); +} + +function serverCmdSetEditorCameraPlayerThird(%client) +{ + // Swith to Player Mode + %client.player.setVelocity("0 0 0"); + %client.setControlObject(%client.player); + ServerConnection.setFirstPerson(0); + $isFirstPersonVar = 0; + + clientCmdSyncEditorGui(); +} + +function serverCmdDropPlayerAtCamera(%client) +{ + // If the player is mounted to something (like a vehicle) drop that at the + // camera instead. The player will remain mounted. + %obj = %client.player.getObjectMount(); + if (!isObject(%obj)) + %obj = %client.player; + + %obj.setTransform(%client.camera.getTransform()); + %obj.setVelocity("0 0 0"); + + %client.setControlObject(%client.player); + clientCmdSyncEditorGui(); +} + +function serverCmdDropCameraAtPlayer(%client) +{ + %client.camera.setTransform(%client.player.getEyeTransform()); + %client.camera.setVelocity("0 0 0"); + %client.setControlObject(%client.camera); + clientCmdSyncEditorGui(); +} + +function serverCmdCycleCameraFlyType(%client) +{ + if(%client.camera.getMode() $= "Fly") + { + if(%client.camera.newtonMode == false) // Fly Camera + { + // Switch to Newton Fly Mode without rotation damping + %client.camera.newtonMode = "1"; + %client.camera.newtonRotation = "0"; + %client.camera.setVelocity("0 0 0"); + } + else if(%client.camera.newtonRotation == false) // Newton Camera without rotation damping + { + // Switch to Newton Fly Mode with damped rotation + %client.camera.newtonMode = "1"; + %client.camera.newtonRotation = "1"; + %client.camera.setAngularVelocity("0 0 0"); + } + else // Newton Camera with rotation damping + { + // Switch to Fly Mode + %client.camera.newtonMode = "0"; + %client.camera.newtonRotation = "0"; + } + %client.setControlObject(%client.camera); + clientCmdSyncEditorGui(); + } +} + +function serverCmdSetEditorCameraStandard(%client) +{ + // Switch to Fly Mode + %client.camera.setFlyMode(); + %client.camera.newtonMode = "0"; + %client.camera.newtonRotation = "0"; + %client.setControlObject(%client.camera); + clientCmdSyncEditorGui(); +} + +function serverCmdSetEditorCameraNewton(%client) +{ + // Switch to Newton Fly Mode without rotation damping + %client.camera.setFlyMode(); + %client.camera.newtonMode = "1"; + %client.camera.newtonRotation = "0"; + %client.camera.setVelocity("0 0 0"); + %client.setControlObject(%client.camera); + clientCmdSyncEditorGui(); +} + +function serverCmdSetEditorCameraNewtonDamped(%client) +{ + // Switch to Newton Fly Mode with damped rotation + %client.camera.setFlyMode(); + %client.camera.newtonMode = "1"; + %client.camera.newtonRotation = "1"; + %client.camera.setAngularVelocity("0 0 0"); + %client.setControlObject(%client.camera); + clientCmdSyncEditorGui(); +} + +function serverCmdSetEditorOrbitCamera(%client) +{ + %client.camera.setEditOrbitMode(); + %client.setControlObject(%client.camera); + clientCmdSyncEditorGui(); +} + +function serverCmdSetEditorFlyCamera(%client) +{ + %client.camera.setFlyMode(); + %client.setControlObject(%client.camera); + clientCmdSyncEditorGui(); +} + +function serverCmdEditorOrbitCameraSelectChange(%client, %size, %center) +{ + if(%size > 0) + { + %client.camera.setValidEditOrbitPoint(true); + %client.camera.setEditOrbitPoint(%center); + } + else + { + %client.camera.setValidEditOrbitPoint(false); + } +} + +function serverCmdEditorCameraAutoFit(%client, %radius) +{ + %client.camera.autoFitRadius(%radius); + %client.setControlObject(%client.camera); + clientCmdSyncEditorGui(); +} + +//---------------------------------------------------------------------------- +// Server admin +//---------------------------------------------------------------------------- + +function serverCmdSAD( %client, %password ) +{ + if( %password !$= "" && %password $= $Pref::Server::AdminPassword) + { + %client.isAdmin = true; + %client.isSuperAdmin = true; + %name = getTaggedString( %client.playerName ); + MessageAll( 'MsgAdminForce', "\c2" @ %name @ " has become Admin by force.", %client ); + } +} + +function serverCmdSADSetPassword(%client, %password) +{ + if(%client.isSuperAdmin) + $Pref::Server::AdminPassword = %password; +} + + +//---------------------------------------------------------------------------- +// Server chat message handlers +//---------------------------------------------------------------------------- + +function serverCmdTeamMessageSent(%client, %text) +{ + if(strlen(%text) >= $Pref::Server::MaxChatLen) + %text = getSubStr(%text, 0, $Pref::Server::MaxChatLen); + chatMessageTeam(%client, %client.team, '\c3%1: %2', %client.playerName, %text); +} + +function serverCmdMessageSent(%client, %text) +{ + if(strlen(%text) >= $Pref::Server::MaxChatLen) + %text = getSubStr(%text, 0, $Pref::Server::MaxChatLen); + chatMessageAll(%client, '\c4%1: %2', %client.playerName, %text); +} + diff --git a/Templates/Empty/game/core/scripts/server/defaults.cs b/Templates/Empty/game/core/scripts/server/defaults.cs new file mode 100644 index 000000000..78ebdb883 --- /dev/null +++ b/Templates/Empty/game/core/scripts/server/defaults.cs @@ -0,0 +1,60 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// List of master servers to query, each one is tried in order +// until one responds +$Pref::Server::RegionMask = 2; +$pref::Master[0] = "2:master.garagegames.com:28002"; + +// Information about the server +$Pref::Server::Name = "Torque 3D Server"; +$Pref::Server::Info = "This is a Torque 3D server."; + +// The connection error message is transmitted to the client immediatly +// on connection, if any further error occures during the connection +// process, such as network traffic mismatch, or missing files, this error +// message is display. This message should be replaced with information +// usefull to the client, such as the url or ftp address of where the +// latest version of the game can be obtained. +$Pref::Server::ConnectionError = + "You do not have the correct version of the FPS starter kit or "@ + "the related art needed to play on this server, please contact "@ + "the server operator for more information."; + +// The network port is also defined by the client, this value +// overrides pref::net::port for dedicated servers +$Pref::Server::Port = 28000; + +// If the password is set, clients must provide it in order +// to connect to the server +$Pref::Server::Password = ""; + +// Password for admin clients +$Pref::Server::AdminPassword = ""; + +// Misc server settings. +$Pref::Server::MaxPlayers = 64; +$Pref::Server::TimeLimit = 20; // In minutes +$Pref::Server::KickBanTime = 300; // specified in seconds +$Pref::Server::BanTime = 1800; // specified in seconds +$Pref::Server::FloodProtectionEnabled = 1; +$Pref::Server::MaxChatLen = 120; diff --git a/Templates/Empty/game/core/scripts/server/game.cs b/Templates/Empty/game/core/scripts/server/game.cs new file mode 100644 index 000000000..a7198cafb --- /dev/null +++ b/Templates/Empty/game/core/scripts/server/game.cs @@ -0,0 +1,208 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// The default hooks that are most likely be overridden/implemented by a game +//----------------------------------------------------------------------------- + +function onServerCreated() +{ + // Invoked by createServer(), when server is created and ready to go + + // Server::GameType is sent to the master server. + // This variable should uniquely identify your game and/or mod. + $Server::GameType = "Test App"; + + // Load up any objects or datablocks saved to the editor managed scripts + %datablockFiles = new ArrayObject(); + %datablockFiles.add( "art/shapes/particles/managedParticleData.cs" ); + %datablockFiles.add( "art/shapes/particles/managedParticleEmitterData.cs" ); + %datablockFiles.add( "art/decals/managedDecalData.cs" ); + %datablockFiles.add( "art/datablocks/managedDatablocks.cs" ); + %datablockFiles.add( "art/forest/managedItemData.cs" ); + %datablockFiles.add( "art/datablocks/datablockExec.cs" ); + loadDatablockFiles( %datablockFiles, true ); + + // Run the other gameplay scripts in this folder + exec("./scriptExec.cs"); + + // For backwards compatibility... + createGame(); +} + +function loadDatablockFiles( %datablockFiles, %recurse ) +{ + if ( %recurse ) + { + recursiveLoadDatablockFiles( %datablockFiles, 9999 ); + return; + } + + %count = %datablockFiles.count(); + for ( %i=0; %i < %count; %i++ ) + { + %file = %datablockFiles.getKey( %i ); + if ( !isScriptFile( %file ) ) + continue; + + exec( %file ); + } + + // Destroy the incoming list. + %datablockFiles.delete(); +} + +function recursiveLoadDatablockFiles( %datablockFiles, %previousErrors ) +{ + %reloadDatablockFiles = new ArrayObject(); + + // Keep track of the number of datablocks that + // failed during this pass. + %failedDatablocks = 0; + + // Try re-executing the list of datablock files. + %count = %datablockFiles.count(); + for ( %i=0; %i < %count; %i++ ) + { + %file = %datablockFiles.getKey( %i ); + if ( !isScriptFile( %file ) ) + continue; + + // Start counting copy constructor creation errors. + $Con::objectCopyFailures = 0; + + exec( %file ); + + // If errors occured then store this file for re-exec later. + if ( $Con::objectCopyFailures > 0 ) + { + %reloadDatablockFiles.add( %file ); + %failedDatablocks = %failedDatablocks + $Con::objectCopyFailures; + } + } + + // Clear the object copy failure counter so that + // we get console error messages again. + $Con::objectCopyFailures = -1; + + // Delete the old incoming list... we're done with it. + %datablockFiles.delete(); + + // If we still have datablocks to retry. + %newCount = %reloadDatablockFiles.count(); + if ( %newCount > 0 ) + { + // If the datablock failures have not been reduced + // from the last pass then we must have a real syntax + // error and not just a bad dependancy. + if ( %lastFailures > %failedDatablocks ) + recursiveLoadDatablockFiles( %reloadDatablockFiles, %failedDatablocks ); + + else + { + // Since we must have real syntax errors do one + // last normal exec to output error messages. + loadDatablockFiles( %reloadDatablockFiles, false ); + } + + return; + } + + // Cleanup the empty reload list. + %reloadDatablockFiles.delete(); +} + +function onServerDestroyed() +{ + // Invoked by destroyServer(), right before the server is destroyed + destroyGame(); +} + +function onMissionLoaded() +{ + // Called by loadMission() once the mission is finished loading + startGame(); +} + +function onMissionEnded() +{ + // Called by endMission(), right before the mission is destroyed + endGame(); +} + +function onMissionReset() +{ + // Called by resetMission(), after all the temporary mission objects + // have been deleted. +} + + +//----------------------------------------------------------------------------- +// These methods are extensions to the GameConnection class. Extending +// GameConnection make is easier to deal with some of this functionality, +// but these could also be implemented as stand-alone functions. +//----------------------------------------------------------------------------- + +function GameConnection::onClientEnterGame(%this) +{ + // Called for each client after it's finished downloading the + // mission and is ready to start playing. +} + +function GameConnection::onClientLeaveGame(%this) +{ + // Call for each client that drops +} + + +//----------------------------------------------------------------------------- +// Functions that implement game-play +// These are here for backwards compatibilty only, games and/or mods should +// really be overloading the server and mission functions listed ubove. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- + +function createGame() +{ + // This function is called by onServerCreated (above) +} + +function destroyGame() +{ + // This function is called by onServerDestroyed (above) +} + + +//----------------------------------------------------------------------------- + +function startGame() +{ + // This is where the game play should start + // The default onMissionLoaded function starts the game. +} + +function endGame() +{ + // This is where the game play should end + // The default onMissionEnded function shuts down the game. +} diff --git a/Templates/Empty/game/core/scripts/server/kickban.cs b/Templates/Empty/game/core/scripts/server/kickban.cs new file mode 100644 index 000000000..f531d351b --- /dev/null +++ b/Templates/Empty/game/core/scripts/server/kickban.cs @@ -0,0 +1,41 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- + +function kick(%client) +{ + messageAll( 'MsgAdminForce', '\c2The Admin has kicked %1.', %client.playerName); + + if (!%client.isAIControlled()) + BanList::add(%client.guid, %client.getAddress(), $Pref::Server::KickBanTime); + %client.delete("You have been kicked from this server"); +} + +function ban(%client) +{ + messageAll('MsgAdminForce', '\c2The Admin has banned %1.', %client.playerName); + + if (!%client.isAIControlled()) + BanList::add(%client.guid, %client.getAddress(), $Pref::Server::BanTime); + %client.delete("You have been banned from this server"); +} diff --git a/Templates/Empty/game/core/scripts/server/levelInfo.cs b/Templates/Empty/game/core/scripts/server/levelInfo.cs new file mode 100644 index 000000000..49cf1c456 --- /dev/null +++ b/Templates/Empty/game/core/scripts/server/levelInfo.cs @@ -0,0 +1,109 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +// Loading info is text displayed on the client side while the mission +// is being loaded. This information is extracted from the mission file +// and sent to each the client as it joins. +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// clearLoadInfo +// +// Clears the mission info stored +//------------------------------------------------------------------------------ +function clearLoadInfo() { + if (isObject(theLevelInfo)) + theLevelInfo.delete(); +} + +//------------------------------------------------------------------------------ +// buildLoadInfo +// +// Extract the map description from the .mis file +//------------------------------------------------------------------------------ +function buildLoadInfo( %mission ) { + clearLoadInfo(); + + %infoObject = ""; + %file = new FileObject(); + + if ( %file.openForRead( %mission ) ) { + %inInfoBlock = false; + + while ( !%file.isEOF() ) { + %line = %file.readLine(); + %line = trim( %line ); + + if( %line $= "new ScriptObject(MissionInfo) {" ) + %inInfoBlock = true; + else if( %line $= "new LevelInfo(theLevelInfo) {" ) + %inInfoBlock = true; + else if( %inInfoBlock && %line $= "};" ) { + %inInfoBlock = false; + %infoObject = %infoObject @ %line; + break; + } + + if( %inInfoBlock ) + %infoObject = %infoObject @ %line @ " "; + } + + %file.close(); + } + else + error("Level file " @ %mission @ " not found."); + + // Will create the object "MissionInfo" + eval( %infoObject ); + %file.delete(); +} + +//------------------------------------------------------------------------------ +// dumpLoadInfo +// +// Echo the mission information to the console +//------------------------------------------------------------------------------ +function dumpLoadInfo() +{ + echo( "Level Name: " @ theLevelInfo.name ); + echo( "Level Description:" ); + + for( %i = 0; theLevelInfo.desc[%i] !$= ""; %i++ ) + echo (" " @ theLevelInfo.desc[%i]); +} + +//------------------------------------------------------------------------------ +// sendLoadInfoToClient +// +// Sends mission description to the client +//------------------------------------------------------------------------------ +function sendLoadInfoToClient( %client ) +{ + messageClient( %client, 'MsgLoadInfo', "", theLevelInfo.levelName ); + + // Send Mission Description a line at a time + for( %i = 0; theLevelInfo.desc[%i] !$= ""; %i++ ) + messageClient( %client, 'MsgLoadDescripition', "", theLevelInfo.desc[%i] ); + + messageClient( %client, 'MsgLoadInfoDone' ); +} diff --git a/Templates/Empty/game/core/scripts/server/message.cs b/Templates/Empty/game/core/scripts/server/message.cs new file mode 100644 index 000000000..eb060ca13 --- /dev/null +++ b/Templates/Empty/game/core/scripts/server/message.cs @@ -0,0 +1,171 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Server side message commands +//----------------------------------------------------------------------------- + +function messageClient(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13) +{ + commandToClient(%client, 'ServerMessage', %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13); +} + +function messageTeam(%team, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13) +{ + %count = ClientGroup.getCount(); + for(%cl= 0; %cl < %count; %cl++) + { + %recipient = ClientGroup.getObject(%cl); + if(%recipient.team == %team) + messageClient(%recipient, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13); + } +} + +function messageTeamExcept(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13) +{ + %team = %client.team; + %count = ClientGroup.getCount(); + for(%cl= 0; %cl < %count; %cl++) + { + %recipient = ClientGroup.getObject(%cl); + if((%recipient.team == %team) && (%recipient != %client)) + messageClient(%recipient, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13); + } +} + +function messageAll(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13) +{ + %count = ClientGroup.getCount(); + for(%cl = 0; %cl < %count; %cl++) + { + %client = ClientGroup.getObject(%cl); + messageClient(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13); + } +} + +function messageAllExcept(%client, %team, %msgtype, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13) +{ + //can exclude a client, a team or both. A -1 value in either field will ignore that exclusion, so + //messageAllExcept(-1, -1, $Mesblah, 'Blah!'); will message everyone (since there shouldn't be a client -1 or client on team -1). + %count = ClientGroup.getCount(); + for(%cl= 0; %cl < %count; %cl++) + { + %recipient = ClientGroup.getObject(%cl); + if((%recipient != %client) && (%recipient.team != %team)) + messageClient(%recipient, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13); + } +} + + +//--------------------------------------------------------------------------- +// Server side client chat'n +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// silly spam protection... +$SPAM_PROTECTION_PERIOD = 10000; +$SPAM_MESSAGE_THRESHOLD = 4; +$SPAM_PENALTY_PERIOD = 10000; +$SPAM_MESSAGE = '\c3FLOOD PROTECTION:\cr You must wait another %1 seconds.'; + +function GameConnection::spamMessageTimeout(%this) +{ + if(%this.spamMessageCount > 0) + %this.spamMessageCount--; +} + +function GameConnection::spamReset(%this) +{ + %this.isSpamming = false; +} + +function spamAlert(%client) +{ + if($Pref::Server::FloodProtectionEnabled != true) + return(false); + + if(!%client.isSpamming && (%client.spamMessageCount >= $SPAM_MESSAGE_THRESHOLD)) + { + %client.spamProtectStart = getSimTime(); + %client.isSpamming = true; + %client.schedule($SPAM_PENALTY_PERIOD, spamReset); + } + + if(%client.isSpamming) + { + %wait = mFloor(($SPAM_PENALTY_PERIOD - (getSimTime() - %client.spamProtectStart)) / 1000); + messageClient(%client, "", $SPAM_MESSAGE, %wait); + return(true); + } + + %client.spamMessageCount++; + %client.schedule($SPAM_PROTECTION_PERIOD, spamMessageTimeout); + return(false); +} + + +//--------------------------------------------------------------------------- + +function chatMessageClient( %client, %sender, %voiceTag, %voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 ) +{ + //see if the client has muted the sender + if ( !%client.muted[%sender] ) + commandToClient( %client, 'ChatMessage', %sender, %voiceTag, %voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 ); +} + +function chatMessageTeam( %sender, %team, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 ) +{ + if ( ( %msgString $= "" ) || spamAlert( %sender ) ) + return; + + %count = ClientGroup.getCount(); + + for ( %i = 0; %i < %count; %i++ ) + { + %obj = ClientGroup.getObject( %i ); + if ( %obj.team == %sender.team ) + chatMessageClient( %obj, %sender, %sender.voiceTag, %sender.voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 ); + } +} + +function chatMessageAll( %sender, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 ) +{ + if ( ( %msgString $= "" ) || spamAlert( %sender ) ) + return; + + %count = ClientGroup.getCount(); + + for ( %i = 0; %i < %count; %i++ ) + { + %obj = ClientGroup.getObject( %i ); + + if(%sender.team != 0) + chatMessageClient( %obj, %sender, %sender.voiceTag, %sender.voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 ); + else + { + // message sender is an observer -- only send message to other observers + if(%obj.team == %sender.team) + chatMessageClient( %obj, %sender, %sender.voiceTag, %sender.voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 ); + } + } +} + diff --git a/Templates/Empty/game/core/scripts/server/missionDownload.cs b/Templates/Empty/game/core/scripts/server/missionDownload.cs new file mode 100644 index 000000000..2b1168b39 --- /dev/null +++ b/Templates/Empty/game/core/scripts/server/missionDownload.cs @@ -0,0 +1,145 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Mission Loading +// The server portion of the client/server mission loading process +//----------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +// Loading Phases: +// Phase 1: Transmit Datablocks +// Transmit targets +// Phase 2: Transmit Ghost Objects +// Phase 3: Start Game +// +// The server invokes the client MissionStartPhase[1-3] function to request +// permission to start each phase. When a client is ready for a phase, +// it responds with MissionStartPhase[1-3]Ack. + +function GameConnection::loadMission(%this) +{ + // Send over the information that will display the server info + // when we learn it got there, we'll send the data blocks + %this.currentPhase = 0; + if (%this.isAIControlled()) + { + // Cut to the chase... + %this.onClientEnterGame(); + } + else + { + commandToClient(%this, 'MissionStartPhase1', $missionSequence, + $Server::MissionFile, MissionGroup.musicTrack); + echo("*** Sending mission load to client: " @ $Server::MissionFile); + } +} + +function serverCmdMissionStartPhase1Ack(%client, %seq) +{ + // Make sure to ignore calls from a previous mission load + if (%seq != $missionSequence || !$MissionRunning) + return; + if (%client.currentPhase != 0) + return; + %client.currentPhase = 1; + + // Start with the CRC + %client.setMissionCRC( $missionCRC ); + + // Send over the datablocks... + // OnDataBlocksDone will get called when have confirmation + // that they've all been received. + %client.transmitDataBlocks($missionSequence); +} + +function GameConnection::onDataBlocksDone( %this, %missionSequence ) +{ + // Make sure to ignore calls from a previous mission load + if (%missionSequence != $missionSequence) + return; + if (%this.currentPhase != 1) + return; + %this.currentPhase = 1.5; + + // On to the next phase + commandToClient(%this, 'MissionStartPhase2', $missionSequence, $Server::MissionFile); +} + +function serverCmdMissionStartPhase2Ack(%client, %seq, %playerDB) +{ + // Make sure to ignore calls from a previous mission load + if (%seq != $missionSequence || !$MissionRunning) + return; + if (%client.currentPhase != 1.5) + return; + %client.currentPhase = 2; + + // Set the player datablock choice + %client.playerDB = %playerDB; + + // Update mod paths, this needs to get there before the objects. + %client.transmitPaths(); + + // Start ghosting objects to the client + %client.activateGhosting(); + +} + +function GameConnection::clientWantsGhostAlwaysRetry(%client) +{ + if($MissionRunning) + %client.activateGhosting(); +} + +function GameConnection::onGhostAlwaysFailed(%client) +{ + +} + +function GameConnection::onGhostAlwaysObjectsReceived(%client) +{ + // Ready for next phase. + commandToClient(%client, 'MissionStartPhase3', $missionSequence, $Server::MissionFile); +} + +function serverCmdMissionStartPhase3Ack(%client, %seq) +{ + // Make sure to ignore calls from a previous mission load + if(%seq != $missionSequence || !$MissionRunning) + return; + if(%client.currentPhase != 2) + return; + %client.currentPhase = 3; + + // Server is ready to drop into the game + + if ( $Pref::Server::MinPlayers > 1 ) + { + PlayerReady(%client); + } + else + { + %client.startMission(); + %client.onClientEnterGame(); + } +} diff --git a/Templates/Empty/game/core/scripts/server/missionLoad.cs b/Templates/Empty/game/core/scripts/server/missionLoad.cs new file mode 100644 index 000000000..d85b15516 --- /dev/null +++ b/Templates/Empty/game/core/scripts/server/missionLoad.cs @@ -0,0 +1,188 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Server mission loading +//----------------------------------------------------------------------------- + +// On every mission load except the first, there is a pause after +// the initial mission info is downloaded to the client. +$MissionLoadPause = 5000; + +//----------------------------------------------------------------------------- + +function loadMission( %missionName, %isFirstMission ) +{ + endMission(); + echo("*** LOADING MISSION: " @ %missionName); + echo("*** Stage 1 load"); + + // Reset all of these + if (isFunction("clearCenterPrintAll")) + clearCenterPrintAll(); + if (isFunction("clearBottomPrintAll")) + clearBottomPrintAll(); + + // increment the mission sequence (used for ghost sequencing) + $missionSequence++; + $missionRunning = false; + $Server::MissionFile = %missionName; + $Server::LoadFailMsg = ""; + + // Extract mission info from the mission file, + // including the display name and stuff to send + // to the client. + buildLoadInfo( %missionName ); + + // Download mission info to the clients + %count = ClientGroup.getCount(); + for( %cl = 0; %cl < %count; %cl++ ) { + %client = ClientGroup.getObject( %cl ); + if (!%client.isAIControlled()) + sendLoadInfoToClient(%client); + } + + // Now that we've sent the LevelInfo to the clients + // clear it so that it won't conflict with the actual + // LevelInfo loaded in the level + clearLoadInfo(); + + // if this isn't the first mission, allow some time for the server + // to transmit information to the clients: + if( %isFirstMission || $Server::ServerType $= "SinglePlayer" ) + loadMissionStage2(); + else + schedule( $MissionLoadPause, ServerGroup, loadMissionStage2 ); +} + +//----------------------------------------------------------------------------- + +function loadMissionStage2() +{ + echo("*** Stage 2 load"); + + // Create the mission group off the ServerGroup + $instantGroup = ServerGroup; + + // Make sure the mission exists + %file = $Server::MissionFile; + + if( !isFile( %file ) ) + { + $Server::LoadFailMsg = "Could not find mission \"" @ %file @ "\""; + } + else + { + // Calculate the mission CRC. The CRC is used by the clients + // to caching mission lighting. + $missionCRC = getFileCRC( %file ); + + // Exec the mission. The MissionGroup (loaded components) is added to the ServerGroup + exec(%file); + + if( !isObject(MissionGroup) ) + { + $Server::LoadFailMsg = "No 'MissionGroup' found in mission \"" @ %file @ "\"."; + } + } + + if( $Server::LoadFailMsg !$= "" ) + { + // Inform clients that are already connected + for (%clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++) + messageClient(ClientGroup.getObject(%clientIndex), 'MsgLoadFailed', $Server::LoadFailMsg); + return; + } + + // Set mission name. + + if( isObject( theLevelInfo ) ) + $Server::MissionName = theLevelInfo.levelName; + + // Mission cleanup group. This is where run time components will reside. The MissionCleanup + // group will be added to the ServerGroup. + new SimGroup( MissionCleanup ); + + // Make the MissionCleanup group the place where all new objects will automatically be added. + $instantGroup = MissionCleanup; + + // Construct MOD paths + pathOnMissionLoadDone(); + + // Mission loading done... + echo("*** Mission loaded"); + + // Start all the clients in the mission + $missionRunning = true; + for( %clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++ ) + ClientGroup.getObject(%clientIndex).loadMission(); + + // Go ahead and launch the game + onMissionLoaded(); +} + + +//----------------------------------------------------------------------------- + +function endMission() +{ + if (!isObject( MissionGroup )) + return; + + echo("*** ENDING MISSION"); + + // Inform the game code we're done. + onMissionEnded(); + + // Inform the clients + for( %clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++ ) { + // clear ghosts and paths from all clients + %cl = ClientGroup.getObject( %clientIndex ); + %cl.endMission(); + %cl.resetGhosting(); + %cl.clearPaths(); + } + + // Delete everything + MissionGroup.delete(); + MissionCleanup.delete(); + + clearServerPaths(); +} + + +//----------------------------------------------------------------------------- + +function resetMission() +{ + echo("*** MISSION RESET"); + + // Remove any temporary mission objects + MissionCleanup.delete(); + $instantGroup = ServerGroup; + new SimGroup( MissionCleanup ); + $instantGroup = MissionCleanup; + + clearServerPaths(); + // + onMissionReset(); +} diff --git a/Templates/Empty/game/core/scripts/server/server.cs b/Templates/Empty/game/core/scripts/server/server.cs new file mode 100644 index 000000000..7bd955f04 --- /dev/null +++ b/Templates/Empty/game/core/scripts/server/server.cs @@ -0,0 +1,216 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function initBaseServer() +{ + // Base server functionality + exec("./audio.cs"); + exec("./message.cs"); + exec("./commands.cs"); + exec("./levelInfo.cs"); + exec("./missionLoad.cs"); + exec("./missionDownload.cs"); + exec("./clientConnection.cs"); + exec("./kickban.cs"); + exec("./game.cs"); + exec("./spawn.cs"); + exec("./camera.cs"); + exec("./centerPrint.cs"); +} + +/// Attempt to find an open port to initialize the server with +function portInit(%port) +{ + %failCount = 0; + while(%failCount < 10 && !setNetPort(%port)) + { + echo("Port init failed on port " @ %port @ " trying next port."); + %port++; %failCount++; + } +} + +/// Create a server of the given type, load the given level, and then +/// create a local client connection to the server. +// +/// @return true if successful. +function createAndConnectToLocalServer( %serverType, %level ) +{ + if( !createServer( %serverType, %level ) ) + return false; + + %conn = new GameConnection( ServerConnection ); + RootGroup.add( ServerConnection ); + + %conn.setConnectArgs( $pref::Player::Name ); + %conn.setJoinPassword( $Client::Password ); + + %result = %conn.connectLocal(); + if( %result !$= "" ) + { + %conn.delete(); + destroyServer(); + + return false; + } + + return true; +} + +/// Create a server with either a "SinglePlayer" or "MultiPlayer" type +/// Specify the level to load on the server +function createServer(%serverType, %level) +{ + // Increase the server session number. This is used to make sure we're + // working with the server session we think we are. + $Server::Session++; + + if (%level $= "") + { + error("createServer(): level name unspecified"); + return false; + } + + // Make sure our level name is relative so that it can send + // across the network correctly + %level = makeRelativePath(%level, getWorkingDirectory()); + + destroyServer(); + + $missionSequence = 0; + $Server::PlayerCount = 0; + $Server::ServerType = %serverType; + $Server::LoadFailMsg = ""; + $Physics::isSinglePlayer = true; + + // Setup for multi-player, the network must have been + // initialized before now. + if (%serverType $= "MultiPlayer") + { + $Physics::isSinglePlayer = false; + + echo("Starting multiplayer mode"); + + // Make sure the network port is set to the correct pref. + portInit($Pref::Server::Port); + allowConnections(true); + + if ($pref::Net::DisplayOnMaster !$= "Never" ) + schedule(0,0,startHeartbeat); + } + + // Create the ServerGroup that will persist for the lifetime of the server. + new SimGroup(ServerGroup); + + // Load up any core datablocks + exec("core/art/datablocks/datablockExec.cs"); + + // Let the game initialize some things now that the + // the server has been created + onServerCreated(); + + loadMission(%level, true); + + return true; +} + +/// Shut down the server +function destroyServer() +{ + $Server::ServerType = ""; + allowConnections(false); + stopHeartbeat(); + $missionRunning = false; + + // End any running levels + endMission(); + onServerDestroyed(); + + // Delete all the server objects + if (isObject(ServerGroup)) + ServerGroup.delete(); + + // Delete all the connections: + while (ClientGroup.getCount()) + { + %client = ClientGroup.getObject(0); + %client.delete(); + } + + $Server::GuidList = ""; + + // Delete all the data blocks... + deleteDataBlocks(); + + // Save any server settings + echo( "Exporting server prefs..." ); + export( "$Pref::Server::*", "~/prefs.cs", false ); + + // Increase the server session number. This is used to make sure we're + // working with the server session we think we are. + $Server::Session++; +} + +/// Reset the server's default prefs +function resetServerDefaults() +{ + echo( "Resetting server defaults..." ); + + exec( "~/defaults.cs" ); + exec( "~/prefs.cs" ); + + // Reload the current level + loadMission( $Server::MissionFile ); +} + +/// Guid list maintenance functions +function addToServerGuidList( %guid ) +{ + %count = getFieldCount( $Server::GuidList ); + for ( %i = 0; %i < %count; %i++ ) + { + if ( getField( $Server::GuidList, %i ) == %guid ) + return; + } + + $Server::GuidList = $Server::GuidList $= "" ? %guid : $Server::GuidList TAB %guid; +} + +function removeFromServerGuidList( %guid ) +{ + %count = getFieldCount( $Server::GuidList ); + for ( %i = 0; %i < %count; %i++ ) + { + if ( getField( $Server::GuidList, %i ) == %guid ) + { + $Server::GuidList = removeField( $Server::GuidList, %i ); + return; + } + } +} + +/// When the server is queried for information, the value of this function is +/// returned as the status field of the query packet. This information is +/// accessible as the ServerInfo::State variable. +function onServerInfoQuery() +{ + return "Doing Ok"; +} diff --git a/Templates/Empty/game/core/scripts/server/spawn.cs b/Templates/Empty/game/core/scripts/server/spawn.cs new file mode 100644 index 000000000..850033055 --- /dev/null +++ b/Templates/Empty/game/core/scripts/server/spawn.cs @@ -0,0 +1,340 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// What kind of "player" is spawned is either controlled directly by the +// SpawnSphere or it defaults back to the values set here. This also controls +// which SimGroups to attempt to select the spawn sphere's from by walking down +// the list of SpawnGroups till it finds a valid spawn object. +//----------------------------------------------------------------------------- + +// Leave $Game::defaultPlayerClass and $Game::defaultPlayerDataBlock as empty strings ("") +// to spawn a the $Game::defaultCameraClass as the control object. +$Game::DefaultPlayerClass = "Player"; +$Game::DefaultPlayerDataBlock = "DefaultPlayerData"; +$Game::DefaultPlayerSpawnGroups = "PlayerSpawnPoints"; + +//----------------------------------------------------------------------------- +// What kind of "camera" is spawned is either controlled directly by the +// SpawnSphere or it defaults back to the values set here. This also controls +// which SimGroups to attempt to select the spawn sphere's from by walking down +// the list of SpawnGroups till it finds a valid spawn object. +//----------------------------------------------------------------------------- +$Game::DefaultCameraClass = "Camera"; +$Game::DefaultCameraDataBlock = "Observer"; +$Game::DefaultCameraSpawnGroups = "CameraSpawnPoints PlayerSpawnPoints"; + +//----------------------------------------------------------------------------- +// pickCameraSpawnPoint() is responsible for finding a valid spawn point for a +// camera. +//----------------------------------------------------------------------------- +function pickCameraSpawnPoint(%spawnGroups) +{ + // Walk through the groups until we find a valid object + for (%i = 0; %i < getWordCount(%spawnGroups); %i++) + { + %group = getWord(%spawnGroups, %i); + + %count = getWordCount(%group); + + if (isObject(%group)) + %spawnPoint = %group.getRandom(); + + if (isObject(%spawnPoint)) + return %spawnPoint; + } + + // Didn't find a spawn point by looking for the groups + // so let's return the "default" SpawnSphere + // First create it if it doesn't already exist + if (!isObject(DefaultCameraSpawnSphere)) + { + %spawn = new SpawnSphere(DefaultCameraSpawnSphere) + { + dataBlock = "SpawnSphereMarker"; + spawnClass = $Game::DefaultCameraClass; + spawnDatablock = $Game::DefaultCameraDataBlock; + }; + + // Add it to the MissionCleanup group so that it + // doesn't get saved to the Mission (and gets cleaned + // up of course) + MissionCleanup.add(%spawn); + } + + return DefaultCameraSpawnSphere; +} + +//----------------------------------------------------------------------------- +// pickPlayerSpawnPoint() is responsible for finding a valid spawn point for a +// player. +//----------------------------------------------------------------------------- +function pickPlayerSpawnPoint(%spawnGroups) +{ + // Walk through the groups until we find a valid object + for (%i = 0; %i < getWordCount(%spawnGroups); %i++) + { + %group = getWord(%spawnGroups, %i); + + if (isObject(%group)) + %spawnPoint = %group.getRandom(); + + if (isObject(%spawnPoint)) + return %spawnPoint; + } + + // Didn't find a spawn point by looking for the groups + // so let's return the "default" SpawnSphere + // First create it if it doesn't already exist + if (!isObject(DefaultPlayerSpawnSphere)) + { + %spawn = new SpawnSphere(DefaultPlayerSpawnSphere) + { + dataBlock = "SpawnSphereMarker"; + spawnClass = $Game::DefaultPlayerClass; + spawnDatablock = $Game::DefaultPlayerDataBlock; + }; + + // Add it to the MissionCleanup group so that it + // doesn't get saved to the Mission (and gets cleaned + // up of course) + MissionCleanup.add(%spawn); + } + + return DefaultPlayerSpawnSphere; +} + +//----------------------------------------------------------------------------- +// GameConnection::spawnCamera() is responsible for spawning a camera for a +// client +//----------------------------------------------------------------------------- +//function GameConnection::spawnCamera(%this, %spawnPoint) +//{ + //// Set the control object to the default camera + //if (!isObject(%this.camera)) + //{ + //if (isDefined("$Game::DefaultCameraClass")) + //%this.camera = spawnObject($Game::DefaultCameraClass, $Game::DefaultCameraDataBlock); + //} +// + //if(!isObject(%this.PathCamera)) + //{ + //// Create path camera + //%this.PathCamera = spawnObject("PathCamera", "LoopingCam"); + ////%this.PathCamera = new PathCamera() { + ////dataBlock = LoopingCam; + ////position = "0 0 300 1 0 0 0"; + ////}; + //} + //if(isObject(%this.PathCamera)) + //{ + //%this.PathCamera.setPosition("-54.0187 1.81237 5.14039"); + //%this.PathCamera.followPath(MenuPath); + //MissionCleanup.add( %this.PathCamera); + //%this.PathCamera.scopeToClient(%this); + //%this.setControlObject(%this.PathCamera); + //} + //// If we have a camera then set up some properties + //if (isObject(%this.camera)) + //{ + //MissionCleanup.add( %this.camera ); + //%this.camera.scopeToClient(%this); + // + ////%this.setControlObject(%this.camera); + ////%this.setControlObject(%this.PathCamera); +// + //if (isDefined("%spawnPoint")) + //{ + //// Attempt to treat %spawnPoint as an object + //if (getWordCount(%spawnPoint) == 1 && isObject(%spawnPoint)) + //{ + //%this.camera.setTransform(%spawnPoint.getTransform()); + //} + //else + //{ + //// Treat %spawnPoint as an AxisAngle transform + //%this.camera.setTransform(%spawnPoint); + //} + //} + //} +//} + +function GameConnection::spawnCamera(%this, %spawnPoint) +{ + // Set the control object to the default camera + if (!isObject(%this.camera)) + { + if (isDefined("$Game::DefaultCameraClass")) + %this.camera = spawnObject($Game::DefaultCameraClass, $Game::DefaultCameraDataBlock); + } + + // If we have a camera then set up some properties + if (isObject(%this.camera)) + { + MissionCleanup.add( %this.camera ); + %this.camera.scopeToClient(%this); + + %this.setControlObject(%this.camera); + + if (isDefined("%spawnPoint")) + { + // Attempt to treat %spawnPoint as an object + if (getWordCount(%spawnPoint) == 1 && isObject(%spawnPoint)) + { + %this.camera.setTransform(%spawnPoint.getTransform()); + } + else + { + // Treat %spawnPoint as an AxisAngle transform + %this.camera.setTransform(%spawnPoint); + } + } + } +} + +//----------------------------------------------------------------------------- +// GameConnection::spawnPlayer() is responsible for spawning a player for a +// client +//----------------------------------------------------------------------------- +function GameConnection::spawnPlayer(%this, %spawnPoint, %noControl) +{ + if (isObject(%this.player)) + { + // The client should not already have a player. Assigning + // a new one could result in an uncontrolled player object. + error("Attempting to create a player for a client that already has one!"); + } + + // Attempt to treat %spawnPoint as an object + if (getWordCount(%spawnPoint) == 1 && isObject(%spawnPoint)) + { + // Defaults + %spawnClass = $Game::DefaultPlayerClass; + %spawnDataBlock = $Game::DefaultPlayerDataBlock; + + // Overrides by the %spawnPoint + if (isDefined("%spawnPoint.spawnClass")) + { + %spawnClass = %spawnPoint.spawnClass; + %spawnDataBlock = %spawnPoint.spawnDatablock; + } + + // This may seem redundant given the above but it allows + // the SpawnSphere to override the datablock without + // overriding the default player class + if (isDefined("%spawnPoint.spawnDatablock")) + %spawnDataBlock = %spawnPoint.spawnDatablock; + + %spawnProperties = %spawnPoint.spawnProperties; + %spawnScript = %spawnPoint.spawnScript; + + // Spawn with the engine's Sim::spawnObject() function + %player = spawnObject(%spawnClass, %spawnDatablock, "", + %spawnProperties, %spawnScript); + + // If we have an object do some initial setup + if (isObject(%player)) + { + // Set the transform to %spawnPoint's transform + %player.setTransform(%spawnPoint.getTransform()); + } + else + { + // If we weren't able to create the player object then warn the user + if (isDefined("%spawnDatablock")) + { + MessageBoxOK("Spawn Player Failed", + "Unable to create a player with class " @ %spawnClass @ + " and datablock " @ %spawnDatablock @ ".\n\nStarting as an Observer instead.", + %this @ ".spawnCamera();"); + } + else + { + MessageBoxOK("Spawn Player Failed", + "Unable to create a player with class " @ %spawnClass @ + ".\n\nStarting as an Observer instead.", + %this @ ".spawnCamera();"); + } + } + } + else + { + // Create a default player + %player = spawnObject($Game::DefaultPlayerClass, $Game::DefaultPlayerDataBlock); + + if (!%player.isMemberOfClass("Player")) + warn("Trying to spawn a class that does not derive from Player."); + + // Treat %spawnPoint as a transform + %player.setTransform(%spawnPoint); + } + + // If we didn't actually create a player object then bail + if (!isObject(%player)) + { + // Make sure we at least have a camera + %this.spawnCamera(%spawnPoint); + + return; + } + + // Update the default camera to start with the player + if (isObject(%this.camera)) + { + if (%player.getClassname() $= "Player") + %this.camera.setTransform(%player.getEyeTransform()); + else + %this.camera.setTransform(%player.getTransform()); + } + + // Add the player object to MissionCleanup so that it + // won't get saved into the level files and will get + // cleaned up properly + MissionCleanup.add(%player); + + // Store the client object on the player object for + // future reference + %player.client = %this; + + // Player setup... + if (%player.isMethod("setShapeName")) + %player.setShapeName(%this.playerName); + + if (%player.isMethod("setEnergyLevel")) + %player.setEnergyLevel(%player.getDataBlock().maxEnergy); + + // Give the client control of the player + %this.player = %player; + + // Give the client control of the camera if in the editor + if( $startWorldEditor ) + { + %control = %this.camera; + %control.mode = toggleCameraFly; + EditorGui.syncCameraGui(); + } + else + %control = %player; + + if(!isDefined("%noControl")) + %this.setControlObject(%control); +} \ No newline at end of file diff --git a/Templates/Empty/game/core/unifiedShell/GamepadButtonsGui.cs b/Templates/Empty/game/core/unifiedShell/GamepadButtonsGui.cs new file mode 100644 index 000000000..d14a2419e --- /dev/null +++ b/Templates/Empty/game/core/unifiedShell/GamepadButtonsGui.cs @@ -0,0 +1,95 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +// global vars +//------------------------------------------------------------------------------ + +$BUTTON_A = 0; +$BUTTON_B = 1; +$BUTTON_X = 2; +$BUTTON_Y = 3; + +//------------------------------------------------------------------------------ +// GamepadButtonsGui methods +//------------------------------------------------------------------------------ + +/// Callback when this control wakes up. All buttons are set to invisible and +/// disabled. +function GamepadButtonsGui::onWake(%this) +{ + %this.setButton($BUTTON_A); + %this.setButton($BUTTON_B); + %this.setButton($BUTTON_X); + %this.setButton($BUTTON_Y); +} + +/// Sets the command and text for the specified button. If %text and %command +/// are left empty, the button will be disabled and hidden. +/// Note: This command is not executed when the A button is pressed. That +/// command is executed directly from the GuiGameList___Ctrl. This command is +/// for the graphical hint and to allow a mouse equivalent. +/// +/// \param %button (constant) The button to set. See: $BUTTON_A, _B, _X, _Y +/// \param %text (string) The text to display next to the A button graphic. +/// \param %command (string) The command executed when the A button is pressed. +function GamepadButtonsGui::setButton(%this, %button, %text, %command) +{ + switch (%button) + { + case $BUTTON_A : + %labelCtrl = ButtonALabel; + %buttonCtrl = ButtonAButton; + %imgCtrl = ButtonAImg; + + case $BUTTON_B : + %labelCtrl = ButtonBLabel; + %buttonCtrl = ButtonBButton; + %imgCtrl = ButtonBImg; + + case $BUTTON_X : + %labelCtrl = ButtonXLabel; + %buttonCtrl = ButtonXButton; + %imgCtrl = ButtonXImg; + + case $BUTTON_Y : + %labelCtrl = ButtonYLabel; + %buttonCtrl = ButtonYButton; + %imgCtrl = ButtonYImg; + + default: + error("GamepadButtonsGui::setButton(" @ %button @ ", " @ %text @ ", " @ %command @ "). No valid button was specified. Please pass one of the $BUTTON_ globals for this parameter."); + return ""; + } + + %set = (! ((%text $= "") && (%command $= ""))); + %labelCtrl.setText(%text); + %labelCtrl.setActive(%set); + %labelCtrl.setVisible(%set); + + %buttonCtrl.Command = %command; + %buttonCtrl.setActive(%set); + %buttonCtrl.setVisible(%set); + + %imgCtrl.setActive(%set); + %imgCtrl.setVisible(%set); +} diff --git a/Templates/Empty/game/core/unifiedShell/GamepadButtonsGui.gui b/Templates/Empty/game/core/unifiedShell/GamepadButtonsGui.gui new file mode 100644 index 000000000..cd66ed22c --- /dev/null +++ b/Templates/Empty/game/core/unifiedShell/GamepadButtonsGui.gui @@ -0,0 +1,222 @@ +//------------------------------------------------------------------------------ +// Torque Engine +// Copyright (C) GarageGames.com, Inc. +//------------------------------------------------------------------------------ + +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(GamepadButtonsGui) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GamepadDefaultProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "0 0"; + Extent = "464 112"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiBitmapCtrl(ButtonBImg) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GamepadDefaultProfile"; + HorizSizing = "left"; + VertSizing = "relative"; + position = "416 16"; + Extent = "32 32"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "core/unifiedShell/images/gamepad_button_b"; + wrap = "0"; + }; + new GuiTextCtrl(ButtonBLabel) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GamepadButtonTextRight"; + HorizSizing = "relative"; + VertSizing = "relative"; + position = "248 16"; + Extent = "160 32"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Button B Label"; + maxLength = "1024"; + }; + new GuiButtonBaseCtrl(ButtonBButton) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GamepadDefaultProfile"; + HorizSizing = "relative"; + VertSizing = "relative"; + position = "248 16"; + Extent = "200 32"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Button"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapCtrl(ButtonAImg) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GamepadDefaultProfile"; + HorizSizing = "left"; + VertSizing = "relative"; + position = "400 64"; + Extent = "32 32"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "core/unifiedShell/images/gamepad_button_a"; + wrap = "0"; + }; + new GuiTextCtrl(ButtonALabel) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GamepadButtonTextRight"; + HorizSizing = "relative"; + VertSizing = "relative"; + position = "232 64"; + Extent = "160 32"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Button B Label"; + maxLength = "1024"; + }; + new GuiButtonBaseCtrl(ButtonAButton) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GamepadDefaultProfile"; + HorizSizing = "relative"; + VertSizing = "relative"; + position = "232 64"; + Extent = "200 32"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Button"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapCtrl(ButtonXImg) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GamepadDefaultProfile"; + HorizSizing = "right"; + VertSizing = "relative"; + position = "32 64"; + Extent = "32 32"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "core/unifiedShell/images/gamepad_button_x"; + wrap = "0"; + }; + new GuiTextCtrl(ButtonXLabel) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GamepadButtonTextLeft"; + HorizSizing = "relative"; + VertSizing = "relative"; + position = "72 64"; + Extent = "160 32"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Button X Label"; + maxLength = "1024"; + }; + new GuiButtonBaseCtrl(ButtonXButton) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GamepadDefaultProfile"; + HorizSizing = "relative"; + VertSizing = "relative"; + position = "32 64"; + Extent = "200 32"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Button"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapCtrl(ButtonYImg) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GamepadDefaultProfile"; + HorizSizing = "right"; + VertSizing = "relative"; + position = "16 16"; + Extent = "32 32"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "core/unifiedShell/images/gamepad_button_y"; + wrap = "0"; + }; + new GuiTextCtrl(ButtonYLabel) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GamepadButtonTextLeft"; + HorizSizing = "relative"; + VertSizing = "relative"; + position = "55 16"; + Extent = "164 32"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Button Y Label"; + maxLength = "1024"; + }; + new GuiButtonBaseCtrl(ButtonYButton) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GamepadDefaultProfile"; + HorizSizing = "relative"; + VertSizing = "relative"; + position = "16 16"; + Extent = "208 32"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Button"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/core/unifiedShell/MainMenuGui.cs b/Templates/Empty/game/core/unifiedShell/MainMenuGui.cs new file mode 100644 index 000000000..5e3725b32 --- /dev/null +++ b/Templates/Empty/game/core/unifiedShell/MainMenuGui.cs @@ -0,0 +1,105 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +// ListMenu methods +//------------------------------------------------------------------------------ + +/// Callback when this gui is added to the sim. +function ListMenu::onAdd(%this) +{ + %this.addRow("Play Game", "onSinglePlayer", 0); + + // Defunct for now + //%this.addRow("Select Model", "onSelectModel", 4, -15); + + // No need for video options on Xbox 360 + if ( $platform $= "xenon" ) + %this.addRow("Exit Game", "onQuit", 4, -15); + else + { + %this.addRow("Setup", "onOptions", 4, -15); + %this.addRow("Exit Game", "onQuit", 6, -15); + } +} + +//------------------------------------------------------------------------------ +// MainMenuButtonHolder methods +//------------------------------------------------------------------------------ + +function MainMenuButtonHolder::onWake(%this) +{ + %this.add(GamepadButtonsGui); + + GamepadButtonsGui.setButton($BUTTON_A, "Go", ListMenu.CallbackOnA); +} + +//------------------------------------------------------------------------------ +// global methods +//------------------------------------------------------------------------------ + +/// Callback from the shell button for triggering single player. +function onSinglePlayer() +{ + echo("Default implementation. Override onSinglePlayer() to add game specific functionality"); + + if ( isObject( LoadingGui ) ) + { + Canvas.setContent("LoadingGui"); + LoadingProgress.setValue(1); + LoadingProgressTxt.setValue("LOADING MISSION FILE"); + Canvas.repaint(); + } + + // Grab the specified default level + %mission = $DefaultLevelFile; + + // If the default level isn't loaded attempt a fallback + if ( %mission $= "" ) + %mission = "levels/default.mis"; + + %serverType = $AutoLoadLevelMode; + + if ( %serverType $= "" ) + %serverType = "SinglePlayer"; + + createAndConnectToLocalServer( %serverType, %mission ); +} + +/// Callback from the shell button to bring up the object picker. +function onSelectModel() +{ + Canvas.setContent(ObjectPickerGui); +} + +/// Callback from the shell button to bring up the options gui. +function onOptions() +{ + Canvas.setContent(OptionsGui); +} + +/// Callback from the shell "quit" button. +function onQuit() +{ + echo("Default implementation. Override onQuit() to add game specific functionality"); + quit(); +} diff --git a/Templates/Empty/game/core/unifiedShell/MainMenuGui.gui b/Templates/Empty/game/core/unifiedShell/MainMenuGui.gui new file mode 100644 index 000000000..a5404196b --- /dev/null +++ b/Templates/Empty/game/core/unifiedShell/MainMenuGui.gui @@ -0,0 +1,72 @@ +//------------------------------------------------------------------------------ +// Torque Engine +// Copyright (C) GarageGames.com, Inc. +//------------------------------------------------------------------------------ + +//--- OBJECT WRITE BEGIN --- +%guiContent = singleton GuiChunkedBitmapCtrl(UnifiedMainMenuGui) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiContentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = "art/gui/background"; + useVariable = "0"; + tile = "0"; + + new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "0 0"; + Extent = "640 480"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiControl(MainMenuButtonHolder) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GamepadDefaultProfile"; + HorizSizing = "center"; + VertSizing = "bottom"; + position = "88 340"; + Extent = "464 112"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + }; + + singleton GuiGameListMenuCtrl(ListMenu) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "DefaultListMenuProfile"; + HorizSizing = "center"; + VertSizing = "bottom"; + position = "160 64"; + Extent = "320 240"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + CallbackOnA = "ListMenu.activateRow();"; + DebugRender = false; + }; + + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/core/unifiedShell/ObjectPickerGui.cs b/Templates/Empty/game/core/unifiedShell/ObjectPickerGui.cs new file mode 100644 index 000000000..275f988d4 --- /dev/null +++ b/Templates/Empty/game/core/unifiedShell/ObjectPickerGui.cs @@ -0,0 +1,172 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +// global vars +//------------------------------------------------------------------------------ + +$PICKER::ROW_OBJECT = 0; ///< The row used to pick ojbects +$PICKER::ROW_MOUNT = 1; ///< The row used to pick the mounted object + +$PICKER::MODEL["Default"] = getWorkingDirectory() @ "/art/shapes/players/SpaceOrc/SpaceOrc.dts"; + +$PICKER::WEAPON["Default"] = getWorkingDirectory() @ "/art/shapes/weapons/SwarmGun/swarmgun.dts"; +$PICKER::WEAPON["Rocket Launcher"] = getWorkingDirectory() @ "/art/shapes/weapons/SwarmGun/swarmgun.dts"; + +//------------------------------------------------------------------------------ +// PickerMenu methods +//------------------------------------------------------------------------------ + +/// Callback when this gui is added to the sim. +function PickerMenu::onAdd(%this) +{ + %this.addRow("Model", "Default", true, "onModelChange"); + %this.addRow("Weapon", "Default", true, "onMountChange"); +} + +/// Callback when the control wakes up. +function PickerMenu::onWake(%this) +{ + // For now PlayerDatasGroup is currently being populated + // by loadPlayerPickerData() which is implemented in + // <$defaultGame>/client/init.cs + + %this.modelList = ""; + + if (isObject(PlayerDatasGroup)) + { + for (%i = 0; %i < PlayerDatasGroup.getCount(); %i++) + { + %obj = PlayerDatasGroup.getObject(%i); + %name = %obj.getName(); + + %name = strreplace(%name, "Data", ""); + echo(%name); + $PICKER::MODEL[%name] = %obj.shapeFile; + + %this.modelList = %this.modelList @ %name @ "\t"; + } + } + + %this.setOptions($PICKER::ROW_OBJECT, %this.modelList); + + %this.setOptions($PICKER::ROW_MOUNT, "Default\tRocket Launcher"); + + // Initialize the currently selected object here + if ($pref::Player:PlayerDB $= "") + $pref::Player:PlayerDB = getField(%this.modelList, 0) @ "Data"; + + %db = strreplace($pref::Player:PlayerDB, "Data", ""); + + //PickerObjectView.setModel($PICKER::MODEL[%db]); + + if ($pref::Player:Weapon $= "") + $pref::Player:Weapon = "Default"; + + + PickerObjectView.setMount($PICKER::WEAPON[$pref::Player:Weapon],0); + PickerObjectView.setOrbitDistance(3); + + %this.selectOption($PICKER::ROW_OBJECT, %db); + %this.selectOption($PICKER::ROW_MOUNT, $pref::Player:Weapon); +} + +function PickerMenu::setPlayer(%this) +{ + %selected = PickerMenu.getCurrentOption($PICKER::ROW_OBJECT); + + if (%selected $= "Default") + %selected = "DefaultPlayer"; + + $pref::Player:PlayerDB = %selected @ "Data"; + + %selected = PickerMenu.getCurrentOption($PICKER::ROW_MOUNT); + + $pref::Player:Weapon = %selected; + + Canvas.setContent(UnifiedMainMenuGui); +} + +//------------------------------------------------------------------------------ +// callbacks from PickerMenu +//------------------------------------------------------------------------------ + +/// Callback when the primary object model is changed. +/// +/// \param %direction (string) "LEFT" or "RIGHT" indicating the direction the +/// option changed. +function onModelChange(%direction) +{ + %selected = PickerMenu.getCurrentOption($PICKER::ROW_OBJECT); + PickerObjectView.setModel($PICKER::MODEL[%selected]); + PickerObjectView.setOrbitDistance(3); + PickerInfoDisplay.update(); +} + +/// Callback when the mounted object model is changed. +/// +/// \param %direction (string) "LEFT" or "RIGHT" indicating the direction the +/// option changed. +function onMountChange(%direction) +{ + %selected = PickerMenu.getCurrentOption($PICKER::ROW_MOUNT); + PickerObjectView.setMount($PICKER::WEAPON[%selected],0); + $pref::Player:Weapon = %selected; + + PickerInfoDisplay.update(); +} + +//------------------------------------------------------------------------------ +// PickerInfoDisplay methods +//------------------------------------------------------------------------------ + +/// Updates the information display to show information about the currently +/// selected objects. +function PickerInfoDisplay::update(%this) +{ + %objectName = PickerMenu.getCurrentOption($PICKER::ROW_OBJECT); + %mountName = PickerMenu.getCurrentOption($PICKER::ROW_MOUNT); + %this.setText(""); + %this.addText("", false); + %this.addText("Selected Objects
", false); + %this.addText("Object:" TAB %objectName @ "
", false); + %this.addText("Mounted Object:" TAB %mountName @ "
", false); + %this.forceReflow(); +} + +/// Callback when this control wakes up +function PickerInfoDisplay::onWake(%this) +{ + %this.update(); +} + +//------------------------------------------------------------------------------ +// PickerButtonHolder methods +//------------------------------------------------------------------------------ + +function PickerButtonHolder::onWake(%this) +{ + %this.add(GamepadButtonsGui); + + GamepadButtonsGui.setButton($BUTTON_A, "Accept", PickerMenu.CallbackOnA); + GamepadButtonsGui.setButton($BUTTON_B, "Go Back", PickerMenu.CallbackOnB); +} diff --git a/Templates/Empty/game/core/unifiedShell/ObjectPickerGui.gui b/Templates/Empty/game/core/unifiedShell/ObjectPickerGui.gui new file mode 100644 index 000000000..e431b5781 --- /dev/null +++ b/Templates/Empty/game/core/unifiedShell/ObjectPickerGui.gui @@ -0,0 +1,82 @@ +//------------------------------------------------------------------------------ +// Torque Engine +// Copyright (C) GarageGames.com, Inc. +//------------------------------------------------------------------------------ + +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ObjectPickerGui) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "640 480"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiBitmapCtrl(PickerBackground) { + canSaveDynamicFields = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "relative"; + VertSizing = "relative"; + position = "0 0"; + Extent = "640 480"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = getWorkingDirectory() @ "/art/skies/skybox_1.jpg"; + wrap = "0"; + }; + new GuiGameListOptionsCtrl(PickerMenu) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "DefaultOptionsMenuProfile"; + HorizSizing = "relative"; + VertSizing = "relative"; + position = "20 185"; + Extent = "320 186"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + CallbackOnA = "PickerMenu.setPlayer();"; + CallbackOnB = "Canvas.setContent(UnifiedMainMenuGui);"; + hovertime = "1000"; + DebugRender = false; + }; + new GuiMLTextCtrl(PickerInfoDisplay) { + Profile = "GuiDefaultProfile"; + HorizSizing = "relative"; + VertSizing = "relative"; + position = "350 185"; + Extent = "240 56"; + }; + new GuiObjectView(PickerObjectView) { + Profile = "GuiDefaultProfile"; + HorizSizing = "relative"; + VertSizing = "relative"; + position = "230 0"; + Extent = "180 180"; + }; + new GuiControl(PickerButtonHolder) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GamepadDefaultProfile"; + HorizSizing = "center"; + VertSizing = "top"; + position = "88 368"; + Extent = "464 112"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/core/unifiedShell/OptionsGui.cs b/Templates/Empty/game/core/unifiedShell/OptionsGui.cs new file mode 100644 index 000000000..2a946bc8f --- /dev/null +++ b/Templates/Empty/game/core/unifiedShell/OptionsGui.cs @@ -0,0 +1,380 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +// global vars +//------------------------------------------------------------------------------ + +$OPTIONS_MENU::NO_DEVICE = -1; ///< Indicates there is no specified device +$OPTIONS_MENU::ROW_GFXDEVICE = 0; ///< Row to choose gfx device +$OPTIONS_MENU::ROW_GFXRES = 1; ///< Row to choose gfx resolution +$OPTIONS_MENU::ROW_FULLSCREEN = 2; ///< Row to choose fullscreen or not +$OPTIONS_MENU::ROW_VOLUME = 3; ///< Row to set audio volume +$OPTIONS_MENU::ROW_AA = 4; ///< Row to set AA + +//------------------------------------------------------------------------------ +// OptionsMenu methods +//------------------------------------------------------------------------------ + +/// Callback when this gui is added to the sim. +function OptionsMenu::onAdd(%this) +{ + %deviceList = %this.getGfxDeviceList(); + %this.addRow("Adapter", %deviceList, true, "onGfxDeviceChange", 0, 0, false); + + %resList = %this.getGfxResList(isFullScreen()); + %this.addRow("Resolution", %resList, false, "", 0, -15); + + %yesNoList = "Yes\tNo"; + %this.addRow("Fullscreen", %yesNoList, true, "onFullscreenChange", 0, -15); + + %volumeList = %this.getSfxVolumeList(); + %this.addRow("Volume", %volumeList, false, "onVolumeChange", 0, -15, false); + + %aaList = %this.getAAList(); + %this.addRow("Antialias", %aaList, false, "", 0, -15); +} + +/// Callback when the control wakes up. +function OptionsMenu::onWake(%this) +{ + %this.loadPrefs(); +} + +/// Initializes each row on this control to reflect the state of saved prefs. +function OptionsMenu::loadPrefs(%this) +{ + // init the display adapter chooser + %this.selectOption($OPTIONS_MENU::ROW_GFXDEVICE, $pref::Video::displayDevice); + OptionsInfoDisplay.displayGfxDevice(); + + // init the display resolution chooser + %currRes = getWords($pref::Video::mode, $WORD::RES_X, $WORD::RES_Y); + %this.selectOption($OPTIONS_MENU::ROW_GFXRES, %currRes); + + // init the fullscreen chooser + %fullscreen = (isFullScreen()) ? "Yes" : "No"; + %this.selectOption($OPTIONS_MENU::ROW_FULLSCREEN, %fullscreen); + + // init the master volume + %volume = mRoundByFive($pref::Audio::masterVolume * 100); + %this.selectOption($OPTIONS_MENU::ROW_VOLUME, %volume); + + %currAA = getWord($pref::Video::mode, $WORD::AA); + %this.selectOption($OPTIONS_MENU::ROW_AA, %currAA); +} + +/// Gets a tab separated list of all the graphics devices available. The list +/// will not include the null device by default but you may request to have the +/// null device included. Devices are listed by type. +/// +/// \param %includeNull (bool) [optional] Specify true to include the null +/// device in the list. Default is false. +/// \return (string) A tab separated list of the avilable graphics devices. +function OptionsMenu::getGfxDeviceList(%this, %includeNull) +{ + %count = GFXInit::getAdapterCount(); + %list = ""; + for (%i = 0; %i < %count; %i++) + { + %type = GFXInit::getAdapterType(%i); + if ((%includeNull) || (%type !$= "NullDevice")) + { + %list = %list TAB %type; + } + } + return trim(%list); +} + +/// Gets a tab separated list of available graphics resolutions. The resolutions +/// will be those available for the settings currently shown on the options +/// screen. +/// +/// \param %fullscreen (bool) Specify true to get a list of all resolutions or +/// false to prune out resolutions that won't fit nicely on the desktop. +/// \return (string) A tab separated list of available graphics resolutions. +function OptionsMenu::getGfxResList(%this, %fullscreen) +{ + %type = %this.getCurrentOption($OPTIONS_MENU::ROW_GFXDEVICE); + %adapter = getGfxDeviceIndex(%type); + + %deskRes = getDesktopResolution(); + %deskResX = firstWord(%deskRes); + %deskResY = getWord(%deskRes, 1); + + %list = ""; + %count = GFXInit::getAdapterModeCount(%adapter); + for (%i = 0; %i < %count; %i++) + { + %rawRes = GFXInit::getAdapterMode(%adapter, %i); + %resX = firstWord(%rawRes); + %resY = getWord(%rawRes, 1); + if (%fullscreen || ((%resX < %deskResX) && (%resY < %deskResY))) + { + %res = %resX SPC %resY; + if (! listHasElement(%list, %res)) + { + %list = %list TAB %res; + } + } + } + + return trim(%list); +} + +/// Refreshes the list of resolutions on the control taking into account the +/// displayed settings for device and fullscreen. +function OptionsMenu::refreshResolutions(%this) +{ + %oldRes = %this.getCurrentOption($OPTIONS_MENU::ROW_GFXRES); + %fullscreen = (%this.getCurrentOption($OPTIONS_MENU::ROW_FULLSCREEN) $= "Yes"); + %newResList = %this.getGfxResList(%fullscreen); + %this.setOptions($OPTIONS_MENU::ROW_GFXRES, %newResList); + %this.selectOption($OPTIONS_MENU::ROW_GFXRES, %oldRes); +} + +/// Builds a list of volume increments suitable for listing on the volume +/// control. List will be from 0 to 100, incrementing by 5. +function OptionsMenu::getSfxVolumeList(%this) +{ + %start = 0; + %end = 100; + %inc = 5; + + %list = ""; + for (%i = %start; %i <= %end; %i += %inc) + { + %list = %list TAB %i; + } + + return trim(%list); +} + +function OptionsMenu::getAAList(%this) +{ + %type = %this.getCurrentOption($OPTIONS_MENU::ROW_GFXDEVICE); + %adapter = getGfxDeviceIndex(%type); + + %list = ""; + %count = GFXInit::getAdapterModeCount(%adapter); + %maxAA = 0; + for (%i = 0; %i < %count; %i++) + { + %rawRes = GFXInit::getAdapterMode(%adapter, %i); + %aa = getWord(%rawRes, $WORD::AA); + if (%aa > %maxAA) + %maxAA = %aa; + } + + %list = ""; + for (%i = 0; %i <= %maxAA; %i++) + { + %list = %list TAB %i; + } + return trim(%list); +} + +//------------------------------------------------------------------------------ +// OptionsButtonHolder methods +//------------------------------------------------------------------------------ + +function OptionsButtonHolder::onWake(%this) +{ + %this.add(GamepadButtonsGui); + + GamepadButtonsGui.setButton($BUTTON_A, "Apply Changes", OptionsMenu.CallbackOnA); + GamepadButtonsGui.setButton($BUTTON_B, "Go Back", OptionsMenu.CallbackOnB); + GamepadButtonsGui.setButton($BUTTON_Y, "Revert Options", OptionsMenu.CallbackOnY); +} + +//------------------------------------------------------------------------------ +// OptionsInfoDisplay methods +//------------------------------------------------------------------------------ + +/// Updates the control to display information on the display device selected on +/// the control for choosing a display device. +function OptionsInfoDisplay::displayGfxDevice(%this) +{ + %type = OptionsMenu.getCurrentOption($OPTIONS_MENU::ROW_GFXDEVICE); + %index = getGfxDeviceIndex(%type); + if (%index != $OPTIONS_MENU::NO_DEVICE) + { + %name = GFXInit::getAdapterName(%index); + %shader = GFXInit::getAdapterShaderModel(%index); + } + else + { + %name = "No valid device of that type"; + %shader = "NA"; + } + %this.setText(""); + %this.addText("", false); + %this.addText("Graphics Device
", false); + %this.addText("Type:" TAB %type @ "
", false); + %this.addText("Device:" TAB %name @ "
", false); + %this.addText("Shader:" TAB %shader @ "
", false); + %this.forceReflow(); +} + +//------------------------------------------------------------------------------ +// callbacks from OptionsMenu +//------------------------------------------------------------------------------ + +/// Callback when the graphics device is changed. This will refresh the lists of +/// resolutions and other related settings. +/// +/// \param %direction (string) "LEFT" or "RIGHT" indicating the direction the +/// option changed. +function onGfxDeviceChange(%direction) +{ + OptionsInfoDisplay.displayGfxDevice(); + $ThisControl.refreshResolutions(); +} + +/// Callback when the fullscreen setting is changed. Refreshes the list of +/// resolutions to reflect what is available. +/// +/// \param %direction (string) "LEFT" or "RIGHT" indicating the direction the +/// option changed. +function onFullscreenChange(%direction) +{ + $ThisControl.refreshResolutions(); +} + +/// Callback when the volume setting is changed. +/// +/// \param %direction (string) "LEFT" or "RIGHT" indicating the direction the +/// option changed. +function onVolumeChange(%direction) +{ + %volume = (OptionsMenu.getCurrentOption($OPTIONS_MENU::ROW_VOLUME) / 100); + sfxSetMasterVolume(%volume); + // TODO: play sample audio blip for user feedback +} + +//------------------------------------------------------------------------------ +// global methods +//------------------------------------------------------------------------------ + +/// Applies the options that have been set. +function applyOptions() +{ + // set the audio options + %rawVolume = OptionsMenu.getCurrentOption($OPTIONS_MENU::ROW_VOLUME); + $pref::Audio::masterVolume = %rawVolume / 100; + + // set the new video mode. + %newRes = OptionsMenu.getCurrentOption($OPTIONS_MENU::ROW_GFXRES); + %newFs = (OptionsMenu.getCurrentOption($OPTIONS_MENU::ROW_FULLSCREEN) $= "Yes"); + %newBpp = "32"; + %rate = getWord($pref::Video::mode, $WORD::REFRESH); + %aa = OptionsMenu.getCurrentOption($OPTIONS_MENU::ROW_AA); + + // even though pref is set by "setVideoMode" we must set it here to handle + // the case of a restart to apply new driver settings + $pref::Video::mode = %newRes SPC %newFs SPC %newBpp SPC %rate SPC %aa; + + // check if Torque will require a restart for the new driver + %oldDriver = $pref::Video::displayDevice; + $pref::Video::displayDevice = OptionsMenu.getCurrentOption($OPTIONS_MENU::ROW_GFXDEVICE); + if (%oldDriver !$= $pref::Video::displayDevice) + { + MessageBoxOKCancel("Change Video Device Now?", + "Changing your video device requires Torque to be restarted. Selecting \"Ok\" will restart Torque with the new settings. Selecting \"Cancel\" will keep the new video settings and apply them next time you restart Torque.", + "restartInstance();", ""); + } + + $pref::Video::mode = %newRes SPC %newFs SPC %newBpp SPC %rate SPC %aa; + configureCanvas(); +} + +/// Reverts all options to the saved preferences. +function revertOptions() +{ + OptionsMenu.loadPrefs(); +} + +/// Looks up the system index of the gfx device from the type. +/// +/// \param %type (string) A string representing the system type of the adapter. +/// \return (int) The index of the adapter if it is found or if there is no +/// device with that type it returns $OPTIONS_MENU::NO_DEVICE +function getGfxDeviceIndex(%type) +{ + %count = GFXInit::getAdapterCount(); + for (%i = 0; %i < %count; %i++) + { + %otherType = GFXInit::getAdapterType(%i); + if (%type $= %otherType) + { + return %i; + } + } + + return $OPTIONS_MENU::NO_DEVICE; +} + +/// Determines if the list contains the given element. +/// +/// \return (bool) True if the element is found in the list, false if it is not. +function listHasElement(%list, %element) +{ + %count = getFieldCount(%list); + for (%i = 0; %i < %count; %i++) + { + %word = getField(%list, %i); + if (%word $= %element) + { + return true; + } + } + + return false; +} + +/// Rounds %n to the nearest whole integer ending in a multiple of five. +/// +/// \param %n (int or float) The number to round. +/// \return (int) %n rounded to the nearest multiple of five. +function mRoundByFive(%n) +{ + return (mFloor((%n + 2.5) / 5) * 5); +} + +/// Determines if the saved preferences indicate running in fullscreen mode. +/// +/// \return (bool) True if the preferences are saved to run in fullscreen or +/// false if saved to run windowed. +function isFullScreen() +{ + %fullscreen = getWord($pref::Video::mode, $WORD::FULLSCREEN); + return (%fullscreen $= "true"); +} + +/// Sets the preference for fullscreen to the indicated value. +/// +/// \param %bool (bool) Specify true to set the preference to fullscreen, false +/// to set it to windowed. +function setFullScreen(%bool) +{ + $pref::Video::resolution = setWord($pref::Video::mode, $WORD::FULLSCREEN, (%bool ? "true" : "false")); +} diff --git a/Templates/Empty/game/core/unifiedShell/OptionsGui.gui b/Templates/Empty/game/core/unifiedShell/OptionsGui.gui new file mode 100644 index 000000000..eadee1d16 --- /dev/null +++ b/Templates/Empty/game/core/unifiedShell/OptionsGui.gui @@ -0,0 +1,104 @@ +//------------------------------------------------------------------------------ +// Torque Engine +// Copyright (C) GarageGames.com, Inc. +//------------------------------------------------------------------------------ + +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(OptionsGui) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "640 480"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiMLTextCtrl(OptionsInfoDisplay) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "center"; + VertSizing = "bottom"; + position = "160 25"; + Extent = "320 70"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + }; + new GuiBitmapCtrl(OptionsMenuBackground) { + canSaveDynamicFields = "1"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "640 480"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = getWorkingDirectory() @ "/art/skies/skybox_1.jpg"; + wrap = "0"; + }; + + new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "0 0"; + Extent = "640 480"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiControl(OptionsButtonHolder) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GamepadDefaultProfile"; + HorizSizing = "center"; + VertSizing = "top"; + position = "88 380"; + Extent = "464 112"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + }; + + new GuiGameListOptionsCtrl(OptionsMenu) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "DefaultOptionsMenuProfile"; + HorizSizing = "center"; + VertSizing = "bottom"; + position = "160 0"; + Extent = "320 240"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + CallbackOnA = "applyOptions();"; + CallbackOnB = "Canvas.setContent(UnifiedMainMenuGui);"; + CallbackOnY = "revertOptions();"; + hovertime = "1000"; + DebugRender = false; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/core/unifiedShell/images/gamepad_button_a.png b/Templates/Empty/game/core/unifiedShell/images/gamepad_button_a.png new file mode 100644 index 000000000..9bd0d6f61 Binary files /dev/null and b/Templates/Empty/game/core/unifiedShell/images/gamepad_button_a.png differ diff --git a/Templates/Empty/game/core/unifiedShell/images/gamepad_button_b.png b/Templates/Empty/game/core/unifiedShell/images/gamepad_button_b.png new file mode 100644 index 000000000..022f06650 Binary files /dev/null and b/Templates/Empty/game/core/unifiedShell/images/gamepad_button_b.png differ diff --git a/Templates/Empty/game/core/unifiedShell/images/gamepad_button_x.png b/Templates/Empty/game/core/unifiedShell/images/gamepad_button_x.png new file mode 100644 index 000000000..dc898296d Binary files /dev/null and b/Templates/Empty/game/core/unifiedShell/images/gamepad_button_x.png differ diff --git a/Templates/Empty/game/core/unifiedShell/images/gamepad_button_y.png b/Templates/Empty/game/core/unifiedShell/images/gamepad_button_y.png new file mode 100644 index 000000000..069142d9f Binary files /dev/null and b/Templates/Empty/game/core/unifiedShell/images/gamepad_button_y.png differ diff --git a/Templates/Empty/game/core/unifiedShell/images/listMenuArray.png b/Templates/Empty/game/core/unifiedShell/images/listMenuArray.png new file mode 100644 index 000000000..f31eeb753 Binary files /dev/null and b/Templates/Empty/game/core/unifiedShell/images/listMenuArray.png differ diff --git a/Templates/Empty/game/core/unifiedShell/main.cs b/Templates/Empty/game/core/unifiedShell/main.cs new file mode 100644 index 000000000..20979c7d8 --- /dev/null +++ b/Templates/Empty/game/core/unifiedShell/main.cs @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function loadShell() +{ + exec("./profiles.cs"); + + exec("./MainMenuGui.cs"); + exec("./MainMenuGui.gui"); + + exec("./OptionsGui.cs"); + exec("./OptionsGui.gui"); + + exec("./GamepadButtonsGui.cs"); + exec("./GamepadButtonsGui.gui"); + + exec("./ObjectPickerGui.cs"); + exec("./ObjectPickerGui.gui"); +} + +loadShell(); diff --git a/Templates/Empty/game/core/unifiedShell/profiles.cs b/Templates/Empty/game/core/unifiedShell/profiles.cs new file mode 100644 index 000000000..7864365eb --- /dev/null +++ b/Templates/Empty/game/core/unifiedShell/profiles.cs @@ -0,0 +1,79 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +// Gui Profiles for the unified shell +//------------------------------------------------------------------------------ + +singleton GuiGameListMenuProfile(DefaultListMenuProfile) +{ + fontType = "Arial Bold"; + fontSize = 20; + fontColor = "120 120 120"; + fontColorSEL = "16 16 16"; + fontColorNA = "200 200 200"; + fontColorHL = "100 100 120"; + HitAreaUpperLeft = "16 20"; + HitAreaLowerRight = "503 74"; + IconOffset = "40 0"; + TextOffset = "100 0"; + RowSize = "525 93"; + bitmap = "./images/listMenuArray"; + canKeyFocus = true; +}; + +singleton GuiGameListOptionsProfile(DefaultOptionsMenuProfile) +{ + fontType = "Arial Bold"; + fontSize = 20; + fontColor = "120 120 120"; + fontColorSEL = "16 16 16"; + fontColorNA = "200 200 200"; + fontColorHL = "100 100 120"; + HitAreaUpperLeft = "16 20"; + HitAreaLowerRight = "503 74"; + IconOffset = "40 0"; + TextOffset = "90 0"; + RowSize = "525 93"; + ColumnSplit = "220"; + RightPad = "20"; + bitmap = "./images/listMenuArray"; + canKeyFocus = true; +}; + +singleton GuiControlProfile(GamepadDefaultProfile) +{ + border = 0; +}; + +singleton GuiControlProfile(GamepadButtonTextLeft) +{ + fontType = "Arial Bold"; + fontSize = 20; + fontColor = "40 40 40"; + justify = "left"; +}; + +singleton GuiControlProfile(GamepadButtonTextRight : GamepadButtonTextLeft) +{ + justify = "right"; +}; diff --git a/Templates/Empty/game/levels/Empty Room.mis b/Templates/Empty/game/levels/Empty Room.mis new file mode 100644 index 000000000..c3ba059a4 --- /dev/null +++ b/Templates/Empty/game/levels/Empty Room.mis @@ -0,0 +1,83 @@ +//--- OBJECT WRITE BEGIN --- +new SimGroup(MissionGroup) { + canSaveDynamicFields = "1"; + Enabled = "1"; + + new LevelInfo(theLevelInfo) { + visibleDistance = "1000"; + fogColor = "0.6 0.6 0.7 1"; + fogDensity = "0"; + fogDensityOffset = "700"; + fogAtmosphereHeight = "0"; + canvasClearColor = "0 0 0 255"; + canSaveDynamicFields = "1"; + levelName = "Empty Room"; + desc0 = "An empty room ready to be populated with Torque objects."; + Enabled = "1"; + }; + new SkyBox(theSky) { + canSaveDynamicFields = "1"; + Position = "0 0 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + Material = "BlackSkyMat"; + drawBottom = "0"; + fogBandHeight = "0"; + }; + new Sun(theSun) { + canSaveDynamicFields = "1"; + Position = "0 0 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + azimuth = "230.396"; + elevation = "45"; + color = "0.968628 0.901961 0.901961 1"; + ambient = "0.078431 0.113725 0.156863 1"; + castShadows = "1"; + attenuationRatio = "0 1 1"; + shadowType = "PSSM"; + texSize = "1024"; + overDarkFactor = "3000 2000 1000 250"; + shadowDistance = "400"; + shadowSoftness = "0.25"; + numSplits = "4"; + logWeight = "0.96"; + fadeStartDistance = "325"; + lastSplitTerrainOnly = "0"; + }; + new SimGroup(PlayerDropPoints) { + canSaveDynamicFields = "1"; + Enabled = "1"; + + new SpawnSphere() { + canSaveDynamicFields = "1"; + Position = "0 0 2"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + radius = "5"; + spawnClass = ""; + spawnDatablock = ""; + autoSpawn = "0"; + sphereWeight = "1"; + indoorWeight = "1"; + outdoorWeight = "1"; + Enabled = "1"; + homingCount = "0"; + lockCount = "0"; + }; + }; + new GroundPlane() { + canSaveDynamicFields = "1"; + Position = "0 0 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + squareSize = "128"; + scaleU = "12"; + scaleV = "12"; + Material = "BlankWhite"; + Enabled = "1"; + }; +}; +//--- OBJECT WRITE END --- + diff --git a/Templates/Empty/game/levels/Empty Room_preview.png b/Templates/Empty/game/levels/Empty Room_preview.png new file mode 100644 index 000000000..0cee49b84 Binary files /dev/null and b/Templates/Empty/game/levels/Empty Room_preview.png differ diff --git a/Templates/Empty/game/levels/main.cs b/Templates/Empty/game/levels/main.cs new file mode 100644 index 000000000..509b0f0c0 --- /dev/null +++ b/Templates/Empty/game/levels/main.cs @@ -0,0 +1,21 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- diff --git a/Templates/Empty/game/main.cs b/Templates/Empty/game/main.cs new file mode 100644 index 000000000..bd1333e6a --- /dev/null +++ b/Templates/Empty/game/main.cs @@ -0,0 +1,280 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Set the name of our application +$appName = "Empty"; + +// The directory it is run from +$defaultGame = "scripts"; + +// Set profile directory +$Pref::Video::ProfilePath = "core/profile"; + +function createCanvas(%windowTitle) +{ + if ($isDedicated) + { + GFXInit::createNullDevice(); + return true; + } + + // Create the Canvas + %foo = new GuiCanvas(Canvas); + + // Set the window title + if (isObject(Canvas)) + Canvas.setWindowTitle(getEngineName() @ " - " @ $appName); + + return true; +} + +// Display the optional commandline arguements +$displayHelp = false; + +// Use these to record and play back crashes +//saveJournal("editorOnFileQuitCrash.jrn"); +//playJournal("editorOnFileQuitCrash.jrn", false); + +//------------------------------------------------------------------------------ +// Check if a script file exists, compiled or not. +function isScriptFile(%path) +{ + if( isFile(%path @ ".dso") || isFile(%path) ) + return true; + + return false; +} + +//------------------------------------------------------------------------------ +// Process command line arguments +exec("core/parseArgs.cs"); + +$isDedicated = false; +$dirCount = 2; +$userDirs = $defaultGame @ ";art;levels"; + +// load tools scripts if we're a tool build +if (isToolBuild()) + $userDirs = "tools;" @ $userDirs; + + +// Parse the executable arguments with the standard +// function from core/main.cs +defaultParseArgs(); + + +if($dirCount == 0) { + $userDirs = $defaultGame; + $dirCount = 1; +} + +//----------------------------------------------------------------------------- +// Display a splash window immediately to improve app responsiveness before +// engine is initialized and main window created +if (!$isDedicated) + displaySplashWindow(); + + +//----------------------------------------------------------------------------- +// The displayHelp, onStart, onExit and parseArgs function are overriden +// by mod packages to get hooked into initialization and cleanup. + +function onStart() +{ + // Default startup function +} + +function onExit() +{ + // OnExit is called directly from C++ code, whereas onStart is + // invoked at the end of this file. +} + +function parseArgs() +{ + // Here for mod override, the arguments have already + // been parsed. +} + +function compileFiles(%pattern) +{ + %path = filePath(%pattern); + + %saveDSO = $Scripts::OverrideDSOPath; + %saveIgnore = $Scripts::ignoreDSOs; + + $Scripts::OverrideDSOPath = %path; + $Scripts::ignoreDSOs = false; + %mainCsFile = makeFullPath("main.cs"); + + for (%file = findFirstFileMultiExpr(%pattern); %file !$= ""; %file = findNextFileMultiExpr(%pattern)) + { + // we don't want to try and compile the primary main.cs + if(%mainCsFile !$= %file) + compile(%file, true); + } + + $Scripts::OverrideDSOPath = %saveDSO; + $Scripts::ignoreDSOs = %saveIgnore; + +} + +if($compileAll) +{ + echo(" --- Compiling all files ---"); + compileFiles("*.cs"); + compileFiles("*.gui"); + compileFiles("*.ts"); + echo(" --- Exiting after compile ---"); + quit(); +} + +if($compileTools) +{ + echo(" --- Compiling tools scritps ---"); + compileFiles("tools/*.cs"); + compileFiles("tools/*.gui"); + compileFiles("tools/*.ts"); + echo(" --- Exiting after compile ---"); + quit(); +} + +package Help { + function onExit() { + // Override onExit when displaying help + } +}; + +function displayHelp() { + activatePackage(Help); + + // Notes on logmode: console logging is written to console.log. + // -log 0 disables console logging. + // -log 1 appends to existing logfile; it also closes the file + // (flushing the write buffer) after every write. + // -log 2 overwrites any existing logfile; it also only closes + // the logfile when the application shuts down. (default) + + error( + "Torque Demo command line options:\n"@ + " -log Logging behavior; see main.cs comments for details\n"@ + " -game Reset list of mods to only contain \n"@ + " Works like the -game argument\n"@ + " -dir Add to list of directories\n"@ + " -console Open a separate console\n"@ + " -show Deprecated\n"@ + " -jSave Record a journal\n"@ + " -jPlay Play back a journal\n"@ + " -jDebug Play back a journal and issue an int3 at the end\n"@ + " -help Display this help message\n" + ); +} + + +//-------------------------------------------------------------------------- + +// Default to a new logfile each session. +if( !$logModeSpecified ) +{ + if( $platform !$= "xbox" && $platform !$= "xenon" ) + setLogMode(6); +} + +// Get the first dir on the list, which will be the last to be applied... this +// does not modify the list. +nextToken($userDirs, currentMod, ";"); + +// Execute startup scripts for each mod, starting at base and working up +function loadDir(%dir) +{ + pushback($userDirs, %dir, ";"); + + if (isScriptFile(%dir @ "/main.cs")) + exec(%dir @ "/main.cs"); +} + +echo("--------- Loading DIRS ---------"); +function loadDirs(%dirPath) +{ + %dirPath = nextToken(%dirPath, token, ";"); + if (%dirPath !$= "") + loadDirs(%dirPath); + + if(exec(%token @ "/main.cs") != true) + { + error("Error: Unable to find specified directory: " @ %token ); + $dirCount--; + } +} +loadDirs($userDirs); +echo(""); + +if($dirCount == 0) { + enableWinConsole(true); + error("Error: Unable to load any specified directories"); + quit(); +} +// Parse the command line arguments +echo("--------- Parsing Arguments ---------"); +parseArgs(); + +// Either display the help message or startup the app. +if ($displayHelp) { + enableWinConsole(true); + displayHelp(); + quit(); +} +else { + onStart(); + echo("Engine initialized..."); + + // Auto-load on the 360 + if( $platform $= "xenon" ) + { + %mission = "levels/Empty Terrain.mis"; + + echo("Xbox360 Autoloading level: '" @ %mission @ "'"); + + + if ($pref::HostMultiPlayer) + %serverType = "MultiPlayer"; + else + %serverType = "SinglePlayer"; + + createAndConnectToLocalServer( %serverType, %mission ); + } +} + +// Display an error message for unused arguments +for ($i = 1; $i < $Game::argc; $i++) { + if (!$argUsed[$i]) + error("Error: Unknown command line argument: " @ $Game::argv[$i]); +} + +// Automatically start up the appropriate eidtor, if any +if ($startWorldEditor) { + Canvas.setCursor("DefaultCursor"); + Canvas.setContent(EditorChooseLevelGui); +} else if ($startGUIEditor) { + Canvas.setCursor("DefaultCursor"); + Canvas.setContent(EditorChooseGUI); +} diff --git a/Templates/Empty/game/scripts/client/commands.cs b/Templates/Empty/game/scripts/client/commands.cs new file mode 100644 index 000000000..7444b3983 --- /dev/null +++ b/Templates/Empty/game/scripts/client/commands.cs @@ -0,0 +1,31 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +// Game start / end events sent from the server +//---------------------------------------------------------------------------- + +function clientCmdGameEnd(%seq) +{ + // Stop local activity... the game will be destroyed on the server + sfxStopAll(); +} diff --git a/Templates/Empty/game/scripts/client/default.bind.cs b/Templates/Empty/game/scripts/client/default.bind.cs new file mode 100644 index 000000000..5ea30d8f0 --- /dev/null +++ b/Templates/Empty/game/scripts/client/default.bind.cs @@ -0,0 +1,542 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +if ( isObject( moveMap ) ) + moveMap.delete(); +new ActionMap(moveMap); + + +//------------------------------------------------------------------------------ +// Non-remapable binds +//------------------------------------------------------------------------------ + +function escapeFromGame() +{ + if ( $Server::ServerType $= "SinglePlayer" ) + MessageBoxYesNo( "Exit", "Exit from this Mission?", "disconnect();", ""); + else + MessageBoxYesNo( "Disconnect", "Disconnect from the server?", "disconnect();", ""); +} + +moveMap.bindCmd(keyboard, "escape", "", "handleEscape();"); + +//------------------------------------------------------------------------------ +// Movement Keys +//------------------------------------------------------------------------------ + +$movementSpeed = 1; // m/s + +function setSpeed(%speed) +{ + if(%speed) + $movementSpeed = %speed; +} + +function moveleft(%val) +{ + $mvLeftAction = %val * $movementSpeed; +} + +function moveright(%val) +{ + $mvRightAction = %val * $movementSpeed; +} + +function moveforward(%val) +{ + $mvForwardAction = %val * $movementSpeed; +} + +function movebackward(%val) +{ + $mvBackwardAction = %val * $movementSpeed; +} + +function moveup(%val) +{ + %object = ServerConnection.getControlObject(); + + if(%object.isInNamespaceHierarchy("Camera")) + $mvUpAction = %val * $movementSpeed; +} + +function movedown(%val) +{ + %object = ServerConnection.getControlObject(); + + if(%object.isInNamespaceHierarchy("Camera")) + $mvDownAction = %val * $movementSpeed; +} + +function turnLeft( %val ) +{ + $mvYawRightSpeed = %val ? $Pref::Input::KeyboardTurnSpeed : 0; +} + +function turnRight( %val ) +{ + $mvYawLeftSpeed = %val ? $Pref::Input::KeyboardTurnSpeed : 0; +} + +function panUp( %val ) +{ + $mvPitchDownSpeed = %val ? $Pref::Input::KeyboardTurnSpeed : 0; +} + +function panDown( %val ) +{ + $mvPitchUpSpeed = %val ? $Pref::Input::KeyboardTurnSpeed : 0; +} + +function getMouseAdjustAmount(%val) +{ + // based on a default camera FOV of 90' + return(%val * ($cameraFov / 90) * 0.01) * $pref::Input::LinkMouseSensitivity; +} + +function getGamepadAdjustAmount(%val) +{ + // based on a default camera FOV of 90' + return(%val * ($cameraFov / 90) * 0.01) * 10.0; +} + +function yaw(%val) +{ + %yawAdj = getMouseAdjustAmount(%val); + if(ServerConnection.isControlObjectRotDampedCamera()) + { + // Clamp and scale + %yawAdj = mClamp(%yawAdj, -m2Pi()+0.01, m2Pi()-0.01); + %yawAdj *= 0.5; + } + + $mvYaw += %yawAdj; +} + +function pitch(%val) +{ + %pitchAdj = getMouseAdjustAmount(%val); + if(ServerConnection.isControlObjectRotDampedCamera()) + { + // Clamp and scale + %pitchAdj = mClamp(%pitchAdj, -m2Pi()+0.01, m2Pi()-0.01); + %pitchAdj *= 0.5; + } + + $mvPitch += %pitchAdj; +} + +function jump(%val) +{ + $mvTriggerCount2++; +} + +function gamePadMoveX( %val ) +{ + $mvXAxis_L = %val; +} + +function gamePadMoveY( %val ) +{ + $mvYAxis_L = %val; +} + +function gamepadYaw(%val) +{ + %yawAdj = getGamepadAdjustAmount(%val); + if(ServerConnection.isControlObjectRotDampedCamera()) + { + // Clamp and scale + %yawAdj = mClamp(%yawAdj, -m2Pi()+0.01, m2Pi()-0.01); + %yawAdj *= 0.5; + } + + if(%yawAdj > 0) + { + $mvYawLeftSpeed = %yawAdj; + $mvYawRightSpeed = 0; + } + else + { + $mvYawLeftSpeed = 0; + $mvYawRightSpeed = -%yawAdj; + } +} + +function gamepadPitch(%val) +{ + %pitchAdj = getGamepadAdjustAmount(%val); + if(ServerConnection.isControlObjectRotDampedCamera()) + { + // Clamp and scale + %pitchAdj = mClamp(%pitchAdj, -m2Pi()+0.01, m2Pi()-0.01); + %pitchAdj *= 0.5; + } + + if(%pitchAdj > 0) + { + $mvPitchDownSpeed = %pitchAdj; + $mvPitchUpSpeed = 0; + } + else + { + $mvPitchDownSpeed = 0; + $mvPitchUpSpeed = -%pitchAdj; + } +} + +moveMap.bind( keyboard, a, moveleft ); +moveMap.bind( keyboard, d, moveright ); +moveMap.bind( keyboard, left, moveleft ); +moveMap.bind( keyboard, right, moveright ); + +moveMap.bind( keyboard, w, moveforward ); +moveMap.bind( keyboard, s, movebackward ); +moveMap.bind( keyboard, up, moveforward ); +moveMap.bind( keyboard, down, movebackward ); + +moveMap.bind( keyboard, e, moveup ); +moveMap.bind( keyboard, c, movedown ); + +moveMap.bind( keyboard, space, jump ); +moveMap.bind( mouse, xaxis, yaw ); +moveMap.bind( mouse, yaxis, pitch ); + +moveMap.bind( gamepad, thumbrx, "D", "-0.23 0.23", gamepadYaw ); +moveMap.bind( gamepad, thumbry, "D", "-0.23 0.23", gamepadPitch ); +moveMap.bind( gamepad, thumblx, "D", "-0.23 0.23", gamePadMoveX ); +moveMap.bind( gamepad, thumbly, "D", "-0.23 0.23", gamePadMoveY ); + +moveMap.bind( gamepad, btn_a, jump ); +moveMap.bindCmd( gamepad, btn_back, "disconnect();", "" ); + +moveMap.bindCmd(gamepad, dpadl, "toggleLightColorViz();", ""); +moveMap.bindCmd(gamepad, dpadu, "toggleDepthViz();", ""); +moveMap.bindCmd(gamepad, dpadd, "toggleNormalsViz();", ""); +moveMap.bindCmd(gamepad, dpadr, "toggleLightSpecularViz();", ""); + + +//------------------------------------------------------------------------------ +// Mouse Trigger +//------------------------------------------------------------------------------ + +function mouseFire(%val) +{ + $mvTriggerCount0++; +} + +function altTrigger(%val) +{ + $mvTriggerCount1++; +} + +moveMap.bind( mouse, button0, mouseFire ); +moveMap.bind( mouse, button1, altTrigger ); + +//------------------------------------------------------------------------------ +// Gamepad Trigger +//------------------------------------------------------------------------------ + +function gamepadFire(%val) +{ + if(%val > 0.1 && !$gamepadFireTriggered) + { + $gamepadFireTriggered = true; + $mvTriggerCount0++; + } + else if(%val <= 0.1 && $gamepadFireTriggered) + { + $gamepadFireTriggered = false; + $mvTriggerCount0++; + } +} + +function gamepadAltTrigger(%val) +{ + if(%val > 0.1 && !$gamepadAltTriggerTriggered) + { + $gamepadAltTriggerTriggered = true; + $mvTriggerCount1++; + } + else if(%val <= 0.1 && $gamepadAltTriggerTriggered) + { + $gamepadAltTriggerTriggered = false; + $mvTriggerCount1++; + } +} + +moveMap.bind(gamepad, triggerr, gamepadFire); +moveMap.bind(gamepad, triggerl, gamepadAltTrigger); + +//------------------------------------------------------------------------------ +// Zoom and FOV functions +//------------------------------------------------------------------------------ + +if($Player::CurrentFOV $= "") + $Player::CurrentFOV = $pref::Player::DefaultFOV / 2; + +// toggleZoomFOV() works by dividing the CurrentFOV by 2. Each time that this +// toggle is hit it simply divides the CurrentFOV by 2 once again. If the +// FOV is reduced below a certain threshold then it resets to equal half of the +// DefaultFOV value. This gives us 4 zoom levels to cycle through. + +function toggleZoomFOV() +{ + $Player::CurrentFOV = $Player::CurrentFOV / 2; + + if($Player::CurrentFOV < 5) + resetCurrentFOV(); + + if(ServerConnection.zoomed) + setFOV($Player::CurrentFOV); + else + { + setFov(ServerConnection.getControlCameraDefaultFov()); + } +} + +function resetCurrentFOV() +{ + $Player::CurrentFOV = ServerConnection.getControlCameraDefaultFov() / 2; +} + +function turnOffZoom() +{ + ServerConnection.zoomed = false; + setFov(ServerConnection.getControlCameraDefaultFov()); + + // Rather than just disable the DOF effect, we want to set it to the level's + // preset values. + //DOFPostEffect.disable(); + ppOptionsUpdateDOFSettings(); +} + +function setZoomFOV(%val) +{ + if(%val) + toggleZoomFOV(); +} + +function toggleZoom(%val) +{ + if (%val) + { + ServerConnection.zoomed = true; + setFov($Player::CurrentFOV); + + DOFPostEffect.setAutoFocus( true ); + DOFPostEffect.setFocusParams( 0.5, 0.5, 50, 500, -5, 5 ); + DOFPostEffect.enable(); + } + else + { + turnOffZoom(); + } +} + +moveMap.bind(keyboard, f, setZoomFOV); +moveMap.bind(keyboard, r, toggleZoom); +moveMap.bind( gamepad, btn_b, toggleZoom ); + +//------------------------------------------------------------------------------ +// Camera & View functions +//------------------------------------------------------------------------------ + +function toggleFreeLook( %val ) +{ + if ( %val ) + $mvFreeLook = true; + else + $mvFreeLook = false; +} + +function toggleFirstPerson(%val) +{ + if (%val) + { + ServerConnection.setFirstPerson(!ServerConnection.isFirstPerson()); + } +} + +function toggleCamera(%val) +{ + if (%val) + commandToServer('ToggleCamera'); +} + +moveMap.bind( keyboard, z, toggleFreeLook ); +moveMap.bind(keyboard, tab, toggleFirstPerson ); +moveMap.bind(keyboard, "alt c", toggleCamera); + +moveMap.bind( gamepad, btn_back, toggleCamera ); + + +//------------------------------------------------------------------------------ +// Demo recording functions +//------------------------------------------------------------------------------ + +function startRecordingDemo( %val ) +{ + if ( %val ) + startDemoRecord(); +} + +function stopRecordingDemo( %val ) +{ + if ( %val ) + stopDemoRecord(); +} + +moveMap.bind( keyboard, F3, startRecordingDemo ); +moveMap.bind( keyboard, F4, stopRecordingDemo ); + + +//------------------------------------------------------------------------------ +// Helper Functions +//------------------------------------------------------------------------------ + +function dropCameraAtPlayer(%val) +{ + if (%val) + commandToServer('dropCameraAtPlayer'); +} + +function dropPlayerAtCamera(%val) +{ + if (%val) + commandToServer('DropPlayerAtCamera'); +} + +moveMap.bind(keyboard, "F8", dropCameraAtPlayer); +moveMap.bind(keyboard, "F7", dropPlayerAtCamera); + +function bringUpOptions(%val) +{ + if (%val) + Canvas.pushDialog(OptionsDlg); +} + +GlobalActionMap.bind(keyboard, "ctrl o", bringUpOptions); + + +//------------------------------------------------------------------------------ +// Debugging Functions +//------------------------------------------------------------------------------ + +$MFDebugRenderMode = 0; +function cycleDebugRenderMode(%val) +{ + if (!%val) + return; + + $MFDebugRenderMode++; + + if ($MFDebugRenderMode > 16) + $MFDebugRenderMode = 0; + if ($MFDebugRenderMode == 15) + $MFDebugRenderMode = 16; + + setInteriorRenderMode($MFDebugRenderMode); + + if (isObject(ChatHud)) + { + %message = "Setting Interior debug render mode to "; + %debugMode = "Unknown"; + + switch($MFDebugRenderMode) + { + case 0: + %debugMode = "NormalRender"; + case 1: + %debugMode = "NormalRenderLines"; + case 2: + %debugMode = "ShowDetail"; + case 3: + %debugMode = "ShowAmbiguous"; + case 4: + %debugMode = "ShowOrphan"; + case 5: + %debugMode = "ShowLightmaps"; + case 6: + %debugMode = "ShowTexturesOnly"; + case 7: + %debugMode = "ShowPortalZones"; + case 8: + %debugMode = "ShowOutsideVisible"; + case 9: + %debugMode = "ShowCollisionFans"; + case 10: + %debugMode = "ShowStrips"; + case 11: + %debugMode = "ShowNullSurfaces"; + case 12: + %debugMode = "ShowLargeTextures"; + case 13: + %debugMode = "ShowHullSurfaces"; + case 14: + %debugMode = "ShowVehicleHullSurfaces"; + // Depreciated + //case 15: + // %debugMode = "ShowVertexColors"; + case 16: + %debugMode = "ShowDetailLevel"; + } + + ChatHud.addLine(%message @ %debugMode); + } +} + +GlobalActionMap.bind(keyboard, "F9", cycleDebugRenderMode); + +//------------------------------------------------------------------------------ +// +// Start profiler by pressing ctrl f3 +// ctrl f3 - starts profile that will dump to console and file +// +function doProfile(%val) +{ + if (%val) + { + // key down -- start profile + echo("Starting profile session..."); + profilerReset(); + profilerEnable(true); + } + else + { + // key up -- finish off profile + echo("Ending profile session..."); + + profilerDumpToFile("profilerDumpToFile" @ getSimTime() @ ".txt"); + profilerEnable(false); + } +} + +GlobalActionMap.bind(keyboard, "ctrl F3", doProfile); + +//------------------------------------------------------------------------------ +// Misc. +//------------------------------------------------------------------------------ + +GlobalActionMap.bind(keyboard, "tilde", toggleConsole); +GlobalActionMap.bindCmd(keyboard, "alt k", "cls();",""); +GlobalActionMap.bindCmd(keyboard, "alt enter", "", "Canvas.attemptFullscreenToggle();"); diff --git a/Templates/Empty/game/scripts/client/defaults.cs b/Templates/Empty/game/scripts/client/defaults.cs new file mode 100644 index 000000000..f9b6c7e66 --- /dev/null +++ b/Templates/Empty/game/scripts/client/defaults.cs @@ -0,0 +1,43 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// First we execute the core default preferences. +exec( "core/scripts/client/defaults.cs" ); + + +// Now add your own game specific client preferences as +// well as any overloaded core defaults here. + + + + +// Finally load the preferences saved from the last +// game execution if they exist. +if ( $platform !$= "xenon" ) +{ + if ( isFile( "./prefs.cs" ) ) + exec( "./prefs.cs" ); +} +else +{ + echo( "Not loading client prefs.cs on Xbox360" ); +} \ No newline at end of file diff --git a/Templates/Empty/game/scripts/client/init.cs b/Templates/Empty/game/scripts/client/init.cs new file mode 100644 index 000000000..f70ea0fb7 --- /dev/null +++ b/Templates/Empty/game/scripts/client/init.cs @@ -0,0 +1,170 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Variables used by client scripts & code. The ones marked with (c) +// are accessed from code. Variables preceeded by Pref:: are client +// preferences and stored automatically in the ~/client/prefs.cs file +// in between sessions. +// +// (c) Client::MissionFile Mission file name +// ( ) Client::Password Password for server join + +// (?) Pref::Player::CurrentFOV +// (?) Pref::Player::DefaultFov +// ( ) Pref::Input::KeyboardTurnSpeed + +// (c) pref::Master[n] List of master servers +// (c) pref::Net::RegionMask +// (c) pref::Client::ServerFavoriteCount +// (c) pref::Client::ServerFavorite[FavoriteCount] +// .. Many more prefs... need to finish this off + +// Moves, not finished with this either... +// (c) firstPerson +// $mv*Action... + +//----------------------------------------------------------------------------- +// These are variables used to control the shell scripts and +// can be overriden by mods: +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +function initClient() +{ + echo("\n--------- Initializing " @ $appName @ ": Client Scripts ---------"); + + // Make sure this variable reflects the correct state. + $Server::Dedicated = false; + + // Game information used to query the master server + $Client::GameTypeQuery = $appName; + $Client::MissionTypeQuery = "Any"; + + // The common module provides basic client functionality + initBaseClient(); + + // Use our prefs to configure our Canvas/Window + configureCanvas(); + + // Load up the Game GUI + exec("art/gui/playGui.gui"); + + // Load up the shell GUIs + if($platform !$= "xenon") // Use the unified shell instead + exec("art/gui/mainMenuGui.gui"); + exec("art/gui/StartupGui.gui"); + + // Gui scripts + exec("scripts/gui/playGui.cs"); + exec("scripts/gui/startupGui.cs"); + + // Client scripts + exec("./missionDownload.cs"); + exec("./serverConnection.cs"); + + // Default player key bindings + exec("./default.bind.cs"); + + if (isFile("./config.cs")) + exec("./config.cs"); + + loadMaterials(); + + // Really shouldn't be starting the networking unless we are + // going to connect to a remote server, or host a multi-player + // game. + setNetPort(0); + + // Copy saved script prefs into C++ code. + setDefaultFov( $pref::Player::defaultFov ); + setZoomSpeed( $pref::Player::zoomSpeed ); + + if( isFile( "./audioData.cs" ) ) + exec( "./audioData.cs" ); + + // Start up the main menu... this is separated out into a + // method for easier mod override. + + if ($startWorldEditor || $startGUIEditor) { + // Editor GUI's will start up in the primary main.cs once + // engine is initialized. + return; + } + + // Connect to server if requested. + if ($JoinGameAddress !$= "") { + // If we are instantly connecting to an address, load the + // loading GUI then attempt the connect. + loadLoadingGui(); + connect($JoinGameAddress, "", $Pref::Player::Name); + } + else { + // Otherwise go to the splash screen. + Canvas.setCursor("DefaultCursor"); + loadStartup(); + } +} + + +//----------------------------------------------------------------------------- + +function loadMainMenu() +{ + // Startup the client with the Main menu... + if (isObject( MainMenuGui )) + Canvas.setContent( MainMenuGui ); + else if (isObject( UnifiedMainMenuGui )) + Canvas.setContent( UnifiedMainMenuGui ); + Canvas.setCursor("DefaultCursor"); + + // first check if we have a level file to load + if ($levelToLoad !$= "") + { + %levelFile = "levels/"; + %ext = getSubStr($levelToLoad, strlen($levelToLoad) - 3, 3); + if(%ext !$= "mis") + %levelFile = %levelFile @ $levelToLoad @ ".mis"; + else + %levelFile = %levelFile @ $levelToLoad; + + // Clear out the $levelToLoad so we don't attempt to load the level again + // later on. + $levelToLoad = ""; + + // let's make sure the file exists + %file = findFirstFile(%levelFile); + + if(%file !$= "") + createAndConnectToLocalServer( "SinglePlayer", %file ); + } +} + +function loadLoadingGui() +{ + Canvas.setContent("LoadingGui"); + LoadingProgress.setValue(1); + + LoadingProgressTxt.setValue("WAITING FOR SERVER"); + + Canvas.repaint(); +} diff --git a/Templates/Empty/game/scripts/client/missionDownload.cs b/Templates/Empty/game/scripts/client/missionDownload.cs new file mode 100644 index 000000000..1d740bc5c --- /dev/null +++ b/Templates/Empty/game/scripts/client/missionDownload.cs @@ -0,0 +1,215 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +// Mission Loading & Mission Info +// The mission loading server handshaking is handled by the +// core/scripts/client/missingLoading.cs. This portion handles the interface +// with the game GUI. +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +// Loading Phases: +// Phase 1: Download Datablocks +// Phase 2: Download Ghost Objects +// Phase 3: Scene Lighting + +//---------------------------------------------------------------------------- +// Phase 1 +//---------------------------------------------------------------------------- + +function onMissionDownloadPhase1(%missionName, %musicTrack) +{ + // Load the post effect presets for this mission. + %path = "levels/" @ fileBase( %missionName ) @ $PostFXManager::fileExtension; + if ( isScriptFile( %path ) ) + postFXManager::loadPresetHandler( %path ); + else + PostFXManager::settingsApplyDefaultPreset(); + + // Close and clear the message hud (in case it's open) + if ( isObject( MessageHud ) ) + MessageHud.close(); + + // Reset the loading progress controls: + if ( !isObject( LoadingProgress ) ) + return; + + LoadingProgress.setValue(0); + LoadingProgressTxt.setValue("LOADING DATABLOCKS"); + Canvas.repaint(); +} + +function onPhase1Progress(%progress) +{ + if ( !isObject( LoadingProgress ) ) + return; + + LoadingProgress.setValue(%progress); + Canvas.repaint(33); +} + +function onPhase1Complete() +{ + if ( !isObject( LoadingProgress ) ) + return; + + LoadingProgress.setValue( 1 ); + Canvas.repaint(); +} + +//---------------------------------------------------------------------------- +// Phase 2 +//---------------------------------------------------------------------------- + +function onMissionDownloadPhase2() +{ + if ( !isObject( LoadingProgress ) ) + return; + + LoadingProgress.setValue(0); + LoadingProgressTxt.setValue("LOADING OBJECTS"); + Canvas.repaint(); +} + +function onPhase2Progress(%progress) +{ + if ( !isObject( LoadingProgress ) ) + return; + + LoadingProgress.setValue(%progress); + Canvas.repaint(33); +} + +function onPhase2Complete() +{ + if ( !isObject( LoadingProgress ) ) + return; + + LoadingProgress.setValue( 1 ); + Canvas.repaint(); +} + +function onFileChunkReceived(%fileName, %ofs, %size) +{ + if ( !isObject( LoadingProgress ) ) + return; + + LoadingProgress.setValue(%ofs / %size); + LoadingProgressTxt.setValue("Downloading " @ %fileName @ "..."); +} + +//---------------------------------------------------------------------------- +// Phase 3 +//---------------------------------------------------------------------------- + +function onMissionDownloadPhase3() +{ + if ( !isObject( LoadingProgress ) ) + return; + + LoadingProgress.setValue(0); + LoadingProgressTxt.setValue("LIGHTING MISSION"); + Canvas.repaint(); +} + +function onPhase3Progress(%progress) +{ + if ( !isObject( LoadingProgress ) ) + return; + + LoadingProgress.setValue(%progress); + Canvas.repaint(33); +} + +function onPhase3Complete() +{ + $lightingMission = false; + + if ( !isObject( LoadingProgress ) ) + return; + + LoadingProgressTxt.setValue("STARTING MISSION"); + LoadingProgress.setValue( 1 ); + Canvas.repaint(); +} + +//---------------------------------------------------------------------------- +// Mission loading done! +//---------------------------------------------------------------------------- + +function onMissionDownloadComplete() +{ + // Client will shortly be dropped into the game, so this is + // good place for any last minute gui cleanup. +} + + +//------------------------------------------------------------------------------ +// Before downloading a mission, the server transmits the mission +// information through these messages. +//------------------------------------------------------------------------------ + +addMessageCallback( 'MsgLoadInfo', handleLoadInfoMessage ); +addMessageCallback( 'MsgLoadDescripition', handleLoadDescriptionMessage ); +addMessageCallback( 'MsgLoadInfoDone', handleLoadInfoDoneMessage ); +addMessageCallback( 'MsgLoadFailed', handleLoadFailedMessage ); + +//------------------------------------------------------------------------------ + +function handleLoadInfoMessage( %msgType, %msgString, %mapName ) +{ + // Clear all of the loading info lines: + for( %line = 0; %line < LoadingGui.qLineCount; %line++ ) + LoadingGui.qLine[%line] = ""; + LoadingGui.qLineCount = 0; +} + +//------------------------------------------------------------------------------ + +function handleLoadDescriptionMessage( %msgType, %msgString, %line ) +{ + LoadingGui.qLine[LoadingGui.qLineCount] = %line; + LoadingGui.qLineCount++; + + // Gather up all the previous lines, append the current one + // and stuff it into the control + %text = ""; + + for( %line = 0; %line < LoadingGui.qLineCount - 1; %line++ ) + %text = %text @ LoadingGui.qLine[%line] @ " "; + %text = %text @ LoadingGui.qLine[%line] @ ""; +} + +//------------------------------------------------------------------------------ + +function handleLoadInfoDoneMessage( %msgType, %msgString ) +{ + // This will get called after the last description line is sent. +} + +//------------------------------------------------------------------------------ + +function handleLoadFailedMessage( %msgType, %msgString ) +{ + MessageBoxOK( "Mission Load Failed", %msgString NL "Press OK to return to the Main Menu", "disconnect();" ); +} diff --git a/Templates/Empty/game/scripts/client/serverConnection.cs b/Templates/Empty/game/scripts/client/serverConnection.cs new file mode 100644 index 000000000..fa07fa830 --- /dev/null +++ b/Templates/Empty/game/scripts/client/serverConnection.cs @@ -0,0 +1,127 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Functions dealing with connecting to a server + + +//----------------------------------------------------------------------------- +// Server connection error +//----------------------------------------------------------------------------- + +addMessageCallback( 'MsgConnectionError', handleConnectionErrorMessage ); + +function handleConnectionErrorMessage(%msgType, %msgString, %msgError) +{ + // On connect the server transmits a message to display if there + // are any problems with the connection. Most connection errors + // are game version differences, so hopefully the server message + // will tell us where to get the latest version of the game. + $ServerConnectionErrorMessage = %msgError; +} + + +//---------------------------------------------------------------------------- +// GameConnection client callbacks +//---------------------------------------------------------------------------- + +function GameConnection::initialControlSet(%this) +{ + echo ("*** Initial Control Object"); + + // The first control object has been set by the server + // and we are now ready to go. + + // first check if the editor is active + if (!isToolBuild() || !Editor::checkActiveLoadDone()) + { + if (Canvas.getContent() != PlayGui.getId()) + Canvas.setContent(PlayGui); + } +} + +function GameConnection::onControlObjectChange(%this) +{ + echo ("*** Control Object Changed"); + + // Reset the current FOV to match the new object + // and turn off any current zoom. + resetCurrentFOV(); + turnOffZoom(); +} + +// Called on the new connection object after connect() succeeds. +function GameConnection::onConnectionAccepted(%this) +{ + // Startup the physX world on the client before any + // datablocks and objects are ghosted over. + physicsInitWorld( "client" ); +} + +function GameConnection::onConnectionError(%this, %msg) +{ + // General connection error, usually raised by ghosted objects + // initialization problems, such as missing files. We'll display + // the server's connection error message. + disconnectedCleanup(); + MessageBoxOK( "DISCONNECT", $ServerConnectionErrorMessage @ " (" @ %msg @ ")" ); +} + +//----------------------------------------------------------------------------- +// Disconnect +//----------------------------------------------------------------------------- + +function disconnect() +{ + // We need to stop the client side simulation + // else physics resources will not cleanup properly. + physicsStopSimulation( "client" ); + + // Delete the connection if it's still there. + if (isObject(ServerConnection)) + ServerConnection.delete(); + + disconnectedCleanup(); + + // Call destroyServer in case we're hosting + destroyServer(); +} + +function disconnectedCleanup() +{ + // End mission, if it's running. + + if( $Client::missionRunning ) + clientEndMission(); + + // Disable mission lighting if it's going, this is here + // in case we're disconnected while the mission is loading. + + $lightingMission = false; + $sceneLighting::terminateLighting = true; + + // Back to the launch screen + if (isObject( MainMenuGui )) + Canvas.setContent( MainMenuGui ); + + // We can now delete the client physics simulation. + physicsDestroyWorld( "client" ); +} diff --git a/Templates/Empty/game/scripts/gui/playGui.cs b/Templates/Empty/game/scripts/gui/playGui.cs new file mode 100644 index 000000000..48b77d195 --- /dev/null +++ b/Templates/Empty/game/scripts/gui/playGui.cs @@ -0,0 +1,80 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// PlayGui is the main TSControl through which the game is viewed. +// The PlayGui also contains the hud controls. +//----------------------------------------------------------------------------- + +function PlayGui::onWake(%this) +{ + // Turn off any shell sounds... + // sfxStop( ... ); + + $enableDirectInput = "1"; + activateDirectInput(); + + // Message hud dialog + if ( isObject( MainChatHud ) ) + { + Canvas.pushDialog( MainChatHud ); + chatHud.attach(HudMessageVector); + } + + // just update the action map here + moveMap.push(); + + // hack city - these controls are floating around and need to be clamped + if ( isFunction( "refreshCenterTextCtrl" ) ) + schedule(0, 0, "refreshCenterTextCtrl"); + if ( isFunction( "refreshBottomTextCtrl" ) ) + schedule(0, 0, "refreshBottomTextCtrl"); +} + +function PlayGui::onSleep(%this) +{ + if ( isObject( MainChatHud ) ) + Canvas.popDialog( MainChatHud ); + + // pop the keymaps + moveMap.pop(); +} + +function PlayGui::clearHud( %this ) +{ + Canvas.popDialog( MainChatHud ); + + while ( %this.getCount() > 0 ) + %this.getObject( 0 ).delete(); +} + +//----------------------------------------------------------------------------- + +function refreshBottomTextCtrl() +{ + BottomPrintText.position = "0 0"; +} + +function refreshCenterTextCtrl() +{ + CenterPrintText.position = "0 0"; +} diff --git a/Templates/Empty/game/scripts/gui/startupGui.cs b/Templates/Empty/game/scripts/gui/startupGui.cs new file mode 100644 index 000000000..675daeafa --- /dev/null +++ b/Templates/Empty/game/scripts/gui/startupGui.cs @@ -0,0 +1,149 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// StartupGui is the splash screen that initially shows when the game is loaded +//----------------------------------------------------------------------------- + +function loadStartup() +{ + // The index of the current splash screen + $StartupIdx = 0; + + // A list of the splash screens and logos + // to cycle through. Note that they have to + // be in consecutive numerical order + StartupGui.bitmap0 = "art/gui/background"; + StartupGui.logo0 = "art/gui/Torque-3D-logo"; + StartupGui.logoPos0 = "178 251"; + StartupGui.logoExtent0 = "443 139"; + + // Call the next() function to set our firt + // splash screen + StartupGui.next(); + + // Play our startup sound + //SFXPlayOnce(AudioGui, "art/sound/gui/startup");//SFXPlay(startsnd); +} + +function StartupGui::click(%this) +{ + %this.done = true; + %this.onDone(); +} + +function StartupGui::next(%this) +{ + // Set us to a blank screen while we load the next one + Canvas.setContent(BlankGui); + + // Set our bitmap and reset the done variable + %this.setBitmap(getVariable(%this @ ".bitmap" @ $StartupIdx)); + %this.done = false; + + // If we have a logo then set it + if (isObject(%this->StartupLogo)) + { + if (getVariable(%this @ ".logo" @ $StartupIdx) !$= "") + { + %this->StartupLogo.setBitmap(getVariable(%this @ ".logo" @ $StartupIdx)); + + if (getVariable(%this @ ".logoPos" @ $StartupIdx) !$= "") + { + %logoPosX = getWord(getVariable(%this @ ".logoPos" @ $StartupIdx), 0); + %logoPosY = getWord(getVariable(%this @ ".logoPos" @ $StartupIdx), 1); + + %this->StartupLogo.setPosition(%logoPosX, %logoPosY); + } + + if (getVariable(%this @ ".logoExtent" @ $StartupIdx) !$= "") + %this->StartupLogo.setExtent(getVariable(%this @ ".logoExtent" @ $StartupIdx)); + + %this->StartupLogo.setVisible(true); + } + else + %this->StartupLogo.setVisible(false); + } + + // If we have a secondary logo then set it + if (isObject(%this->StartupLogoSecondary)) + { + if (getVariable(%this @ ".seclogo" @ $StartupIdx) !$= "") + { + %this->StartupLogoSecondary.setBitmap(getVariable(%this @ ".seclogo" @ $StartupIdx)); + + if (getVariable(%this @ ".seclogoPos" @ $StartupIdx) !$= "") + { + %logoPosX = getWord(getVariable(%this @ ".seclogoPos" @ $StartupIdx), 0); + %logoPosY = getWord(getVariable(%this @ ".seclogoPos" @ $StartupIdx), 1); + + %this->StartupLogoSecondary.setPosition(%logoPosX, %logoPosY); + } + + if (getVariable(%this @ ".seclogoExtent" @ $StartupIdx) !$= "") + %this->StartupLogoSecondary.setExtent(getVariable(%this @ ".seclogoExtent" @ $StartupIdx)); + + %this->StartupLogoSecondary.setVisible(true); + } + else + %this->StartupLogoSecondary.setVisible(false); + } + + // Increment our screen index for the next screen + $StartupIdx++; + + // Set the Canvas to our newly updated GuiFadeinBitmapCtrl + Canvas.setContent(%this); +} + +function StartupGui::onDone(%this) +{ + // If we have been tagged as done decide if we need + // to end or cycle to the next one + if (%this.done) + { + // See if we have a valid bitmap for the next screen + if (getVariable(%this @ ".bitmap" @ $StartupIdx) $= "") + { + // Clear our data and load the main menu + %this.done = true; + + // NOTE: Don't ever ever delete yourself during a callback from C++. + // + // Deleting the whole gui itself seems a bit excessive, what if we want + // to return to the startup gui at a later time? Any bitmaps set on + // the controls should be unloaded automatically if the control is not + // awake, if this is not the case then that's what needs to be fixed. + + //%this.delete(); + //BlankGui.delete(); + //flushTextureCache(); + + loadMainMenu(); + } + else + { + // We do have a bitmap so cycle to it + %this.next(); + } + } +} diff --git a/Templates/Empty/game/scripts/main.cs b/Templates/Empty/game/scripts/main.cs new file mode 100644 index 000000000..eea2e916b --- /dev/null +++ b/Templates/Empty/game/scripts/main.cs @@ -0,0 +1,142 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Load up core script base +loadDir("core"); // Should be loaded at a higher level, but for now leave -- SRZ 11/29/07 + +//----------------------------------------------------------------------------- +// Package overrides to initialize the mod. +package fps { + +function displayHelp() { + Parent::displayHelp(); + error( + "Fps Mod options:\n"@ + " -dedicated Start as dedicated server\n"@ + " -connect
For non-dedicated: Connect to a game at
\n" @ + " -mission For dedicated: Load the mission\n" + ); +} + +function parseArgs() +{ + // Call the parent + Parent::parseArgs(); + + // Arguments, which override everything else. + for (%i = 1; %i < $Game::argc ; %i++) + { + %arg = $Game::argv[%i]; + %nextArg = $Game::argv[%i+1]; + %hasNextArg = $Game::argc - %i > 1; + + switch$ (%arg) + { + //-------------------- + case "-dedicated": + $Server::Dedicated = true; + enableWinConsole(true); + $argUsed[%i]++; + + //-------------------- + case "-mission": + $argUsed[%i]++; + if (%hasNextArg) { + $missionArg = %nextArg; + $argUsed[%i+1]++; + %i++; + } + else + error("Error: Missing Command Line argument. Usage: -mission "); + + //-------------------- + case "-connect": + $argUsed[%i]++; + if (%hasNextArg) { + $JoinGameAddress = %nextArg; + $argUsed[%i+1]++; + %i++; + } + else + error("Error: Missing Command Line argument. Usage: -connect "); + } + } +} + +function onStart() +{ + // The core does initialization which requires some of + // the preferences to loaded... so do that first. + exec( "./client/defaults.cs" ); + exec( "./server/defaults.cs" ); + + Parent::onStart(); + echo("\n--------- Initializing Directory: scripts ---------"); + + // Load the scripts that start it all... + exec("./client/init.cs"); + exec("./server/init.cs"); + + // Init the physics plugin. + physicsInit(); + + // Start up the audio system. + sfxStartup(); + + // Server gets loaded for all sessions, since clients + // can host in-game servers. + initServer(); + + // Start up in either client, or dedicated server mode + if ($Server::Dedicated) + initDedicated(); + else + initClient(); +} + +function onExit() +{ + // Ensure that we are disconnected and/or the server is destroyed. + // This prevents crashes due to the SceneGraph being deleted before + // the objects it contains. + if ($Server::Dedicated) + destroyServer(); + else + disconnect(); + + // Destroy the physics plugin. + physicsDestroy(); + + echo("Exporting client prefs"); + export("$pref::*", "./client/prefs.cs", False); + + echo("Exporting server prefs"); + export("$Pref::Server::*", "./server/prefs.cs", False); + BanList::Export("./server/banlist.cs"); + + Parent::onExit(); +} + +}; // package fps + +// Activate the game package. +activatePackage(fps); diff --git a/Templates/Empty/game/scripts/server/commands.cs b/Templates/Empty/game/scripts/server/commands.cs new file mode 100644 index 000000000..2f33de30d --- /dev/null +++ b/Templates/Empty/game/scripts/server/commands.cs @@ -0,0 +1,25 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Misc. server commands avialable to clients +//----------------------------------------------------------------------------- \ No newline at end of file diff --git a/Templates/Empty/game/scripts/server/defaults.cs b/Templates/Empty/game/scripts/server/defaults.cs new file mode 100644 index 000000000..bc3ce3b34 --- /dev/null +++ b/Templates/Empty/game/scripts/server/defaults.cs @@ -0,0 +1,43 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// First we execute the core default preferences. +exec( "core/scripts/server/defaults.cs" ); + + +// Now add your own game specific server preferences as +// well as any overloaded core defaults here. + + + + +// Finally load the preferences saved from the last +// game execution if they exist. +if ( $platform !$= "xenon" ) +{ + if ( isFile( "./prefs.cs" ) ) + exec( "./prefs.cs" ); +} +else +{ + echo( "Not loading server prefs.cs on Xbox360" ); +} diff --git a/Templates/Empty/game/scripts/server/game.cs b/Templates/Empty/game/scripts/server/game.cs new file mode 100644 index 000000000..0cda449a1 --- /dev/null +++ b/Templates/Empty/game/scripts/server/game.cs @@ -0,0 +1,233 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// What kind of "player" is spawned is either controlled directly by the +// SpawnSphere or it defaults back to the values set here. This also controls +// which SimGroups to attempt to select the spawn sphere's from by walking down +// the list of SpawnGroups till it finds a valid spawn object. +// These override the values set in core/scripts/server/spawn.cs +//----------------------------------------------------------------------------- + +// Leave $Game::defaultPlayerClass and $Game::defaultPlayerDataBlock as empty strings ("") +// to spawn a the $Game::defaultCameraClass as the control object. +$Game::DefaultPlayerClass = ""; +$Game::DefaultPlayerDataBlock = ""; +$Game::DefaultPlayerSpawnGroups = "CameraSpawnPoints PlayerSpawnPoints PlayerDropPoints"; + +//----------------------------------------------------------------------------- +// What kind of "camera" is spawned is either controlled directly by the +// SpawnSphere or it defaults back to the values set here. This also controls +// which SimGroups to attempt to select the spawn sphere's from by walking down +// the list of SpawnGroups till it finds a valid spawn object. +// These override the values set in core/scripts/server/spawn.cs +//----------------------------------------------------------------------------- +$Game::DefaultCameraClass = "Camera"; +$Game::DefaultCameraDataBlock = "Observer"; +$Game::DefaultCameraSpawnGroups = "CameraSpawnPoints PlayerSpawnPoints PlayerDropPoints"; + +// Global movement speed that affects all Cameras +$Camera::MovementSpeed = 30; + +//----------------------------------------------------------------------------- +// GameConnection manages the communication between the server's world and the +// client's simulation. These functions are responsible for maintaining the +// client's camera and player objects. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// This is the main entry point for spawning a control object for the client. +// The control object is the actual game object that the client is responsible +// for controlling in the client and server simulations. We also spawn a +// convenient camera object for use as an alternate control object. We do not +// have to spawn this camera object in order to function in the simulation. +// +// Called for each client after it's finished downloading the mission and is +// ready to start playing. +//----------------------------------------------------------------------------- +function GameConnection::onClientEnterGame(%this) +{ + // This function currently relies on some helper functions defined in + // core/scripts/spawn.cs. For custom spawn behaviors one can either + // override the properties on the SpawnSphere's or directly override the + // functions themselves. + + // Find a spawn point for the camera + %cameraSpawnPoint = pickCameraSpawnPoint($Game::DefaultCameraSpawnGroups); + // Spawn a camera for this client using the found %spawnPoint + %this.spawnCamera(%cameraSpawnPoint); + + // Find a spawn point for the player + %playerSpawnPoint = pickPlayerSpawnPoint($Game::DefaultPlayerSpawnGroups); + // Spawn a camera for this client using the found %spawnPoint + %this.spawnPlayer(%playerSpawnPoint); +} + +//----------------------------------------------------------------------------- +// Clean up the client's control objects +//----------------------------------------------------------------------------- +function GameConnection::onClientLeaveGame(%this) +{ + // Cleanup the camera + if (isObject(%this.camera)) + %this.camera.delete(); + // Cleanup the player + if (isObject(%this.player)) + %this.player.delete(); +} + +//----------------------------------------------------------------------------- +// Handle a player's death +//----------------------------------------------------------------------------- +function GameConnection::onDeath(%this, %sourceObject, %sourceClient, %damageType, %damLoc) +{ + // Clear out the name on the corpse + if (isObject(%this.player)) + { + if (%this.player.isMethod("setShapeName")) + %this.player.setShapeName(""); + } + + // Switch the client over to the death cam + if (isObject(%this.camera) && isObject(%this.player)) + { + %this.camera.setMode("Corpse", %this.player); + %this.setControlObject(%this.camera); + } + + // Unhook the player object + %this.player = 0; +} + +//----------------------------------------------------------------------------- +// Server, mission, and game management +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// The server has started up so do some game start up +//----------------------------------------------------------------------------- +function onServerCreated() +{ + // Server::GameType is sent to the master server. + // This variable should uniquely identify your game and/or mod. + $Server::GameType = "Torque 3D"; + + // Server::MissionType sent to the master server. Clients can + // filter servers based on mission type. + $Server::MissionType = "pureLIGHT"; + + // GameStartTime is the sim time the game started. Used to calculated + // game elapsed time. + $Game::StartTime = 0; + + // Create the server physics world. + physicsInitWorld( "server" ); + + // Load up any objects or datablocks saved to the editor managed scripts + %datablockFiles = new ArrayObject(); + %datablockFiles.add( "art/shapes/particles/managedParticleData.cs" ); + %datablockFiles.add( "art/shapes/particles/managedParticleEmitterData.cs" ); + %datablockFiles.add( "art/decals/managedDecalData.cs" ); + %datablockFiles.add( "art/datablocks/managedDatablocks.cs" ); + %datablockFiles.add( "art/forest/managedItemData.cs" ); + %datablockFiles.add( "art/datablocks/datablockExec.cs" ); + loadDatablockFiles( %datablockFiles, true ); + + // Run the other gameplay scripts in this folder + exec("./scriptExec.cs"); + + // Keep track of when the game started + $Game::StartTime = $Sim::Time; +} + +//----------------------------------------------------------------------------- +// This function is called as part of a server shutdown +//----------------------------------------------------------------------------- +function onServerDestroyed() +{ + // Destroy the server physcis world + physicsDestroyWorld( "server" ); +} + +//----------------------------------------------------------------------------- +// Called by loadMission() once the mission is finished loading +//----------------------------------------------------------------------------- +function onMissionLoaded() +{ + // Start the server side physics simulation + physicsStartSimulation( "server" ); + + // Nothing special for now, just start up the game play + startGame(); +} + +//----------------------------------------------------------------------------- +// Called by endMission(), right before the mission is destroyed +//----------------------------------------------------------------------------- +function onMissionEnded() +{ + // Stop the server physics simulation + physicsStopSimulation( "server" ); + + // Normally the game should be ended first before the next + // mission is loaded, this is here in case loadMission has been + // called directly. The mission will be ended if the server + // is destroyed, so we only need to cleanup here. + $Game::Running = false; +} + +//----------------------------------------------------------------------------- +// Called once the game has started +//----------------------------------------------------------------------------- +function startGame() +{ + if ($Game::Running) + { + error("startGame(): End the game first!"); + return; + } + + $Game::Running = true; +} + +//----------------------------------------------------------------------------- +// Called once the game has ended +//----------------------------------------------------------------------------- +function endGame() +{ + if (!$Game::Running) + { + error("endGame(): No game running!"); + return; + } + + // Inform the client the game is over + for( %clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++ ) + { + %cl = ClientGroup.getObject( %clientIndex ); + commandToClient(%cl, 'GameEnd'); + } + + // Delete all the temporary mission objects + resetMission(); + $Game::Running = false; +} diff --git a/Templates/Empty/game/scripts/server/init.cs b/Templates/Empty/game/scripts/server/init.cs new file mode 100644 index 000000000..827bb5b93 --- /dev/null +++ b/Templates/Empty/game/scripts/server/init.cs @@ -0,0 +1,96 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- + +// Variables used by server scripts & code. The ones marked with (c) +// are accessed from code. Variables preceeded by Pref:: are server +// preferences and stored automatically in the ServerPrefs.cs file +// in between server sessions. +// +// (c) Server::ServerType {SinglePlayer, MultiPlayer} +// (c) Server::GameType Unique game name +// (c) Server::Dedicated Bool +// ( ) Server::MissionFile Mission .mis file name +// (c) Server::MissionName DisplayName from .mis file +// (c) Server::MissionType Not used +// (c) Server::PlayerCount Current player count +// (c) Server::GuidList Player GUID (record list?) +// (c) Server::Status Current server status +// +// (c) Pref::Server::Name Server Name +// (c) Pref::Server::Password Password for client connections +// ( ) Pref::Server::AdminPassword Password for client admins +// (c) Pref::Server::Info Server description +// (c) Pref::Server::MaxPlayers Max allowed players +// (c) Pref::Server::RegionMask Registers this mask with master server +// ( ) Pref::Server::BanTime Duration of a player ban +// ( ) Pref::Server::KickBanTime Duration of a player kick & ban +// ( ) Pref::Server::MaxChatLen Max chat message len +// ( ) Pref::Server::FloodProtectionEnabled Bool + +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- + +function initServer() +{ + echo("\n--------- Initializing " @ $appName @ ": Server Scripts ---------"); + + // Server::Status is returned in the Game Info Query and represents the + // current status of the server. This string sould be very short. + $Server::Status = "Unknown"; + + // Turn on testing/debug script functions + $Server::TestCheats = false; + + // Specify where the mission files are. + $Server::MissionFileSpec = "levels/*.mis"; + + // The common module provides the basic server functionality + initBaseServer(); + + // Load up game server support scripts + exec("./commands.cs"); + exec("./game.cs"); +} + + +//----------------------------------------------------------------------------- + +function initDedicated() +{ + enableWinConsole(true); + echo("\n--------- Starting Dedicated Server ---------"); + + // Make sure this variable reflects the correct state. + $Server::Dedicated = true; + + // The server isn't started unless a mission has been specified. + if ($missionArg !$= "") { + createServer("MultiPlayer", $missionArg); + } + else + echo("No mission specified (use -mission filename)"); +} + diff --git a/Templates/Empty/game/scripts/server/scriptExec.cs b/Templates/Empty/game/scripts/server/scriptExec.cs new file mode 100644 index 000000000..f2f2d1f58 --- /dev/null +++ b/Templates/Empty/game/scripts/server/scriptExec.cs @@ -0,0 +1,24 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Load up all scripts. This function is called when +// a server is constructed. diff --git a/Templates/Empty/game/shaders/common/basicCloudsP.hlsl b/Templates/Empty/game/shaders/common/basicCloudsP.hlsl new file mode 100644 index 000000000..53b88d8b7 --- /dev/null +++ b/Templates/Empty/game/shaders/common/basicCloudsP.hlsl @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "torque.hlsl" + +struct ConnectData +{ + float4 hpos : POSITION; + float2 texCoord : TEXCOORD0; +}; + +uniform sampler2D diffuseMap : register(S0); + +float4 main( ConnectData IN ) : COLOR +{ + float4 col = tex2D( diffuseMap, IN.texCoord ); + return hdrEncode( col ); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/basicCloudsV.hlsl b/Templates/Empty/game/shaders/common/basicCloudsV.hlsl new file mode 100644 index 000000000..49842fd37 --- /dev/null +++ b/Templates/Empty/game/shaders/common/basicCloudsV.hlsl @@ -0,0 +1,58 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +struct CloudVert +{ + float4 pos : POSITION; + float3 normal : NORMAL; + float3 binormal : BINORMAL; + float3 tangent : TANGENT; + float2 uv0 : TEXCOORD0; +}; + +struct ConnectData +{ + float4 hpos : POSITION; + float2 texCoord : TEXCOORD0; +}; + +uniform float4x4 modelview; +uniform float accumTime; +uniform float texScale; +uniform float2 texDirection; +uniform float2 texOffset; + +ConnectData main( CloudVert IN ) +{ + ConnectData OUT; + + OUT.hpos = mul(modelview, IN.pos); + + float2 uv = IN.uv0; + uv += texOffset; + uv *= texScale; + uv += accumTime * texDirection; + + OUT.texCoord = uv; + + return OUT; +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/cloudLayerP.hlsl b/Templates/Empty/game/shaders/common/cloudLayerP.hlsl new file mode 100644 index 000000000..a3c2d06e8 --- /dev/null +++ b/Templates/Empty/game/shaders/common/cloudLayerP.hlsl @@ -0,0 +1,145 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "torque.hlsl" + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +struct ConnectData +{ + float4 hpos : POSITION; + float4 texCoord12 : TEXCOORD0; + float4 texCoord34 : TEXCOORD1; + float3 vLightTS : TEXCOORD2; // light vector in tangent space, denormalized + float3 vViewTS : TEXCOORD3; // view vector in tangent space, denormalized + float worldDist : TEXCOORD4; +}; + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- +uniform sampler2D normalHeightMap : register(S0); +uniform float3 ambientColor; +uniform float3 sunColor; +uniform float cloudCoverage; +uniform float3 cloudBaseColor; +uniform float cloudExposure; + +//----------------------------------------------------------------------------- +// Globals +//----------------------------------------------------------------------------- +// The per-color weighting to be used for luminance calculations in RGB order. +static const float3 LUMINANCE_VECTOR = float3(0.2125f, 0.7154f, 0.0721f); + + +//----------------------------------------------------------------------------- +// Functions +//----------------------------------------------------------------------------- + +// Calculates the Rayleigh phase function +float getRayleighPhase( float angle ) +{ + return 0.75 * ( 1.0 + pow( angle, 2 ) ); +} + +// Returns the output rgb color given a texCoord and parameters it uses +// for lighting calculation. +float3 ComputeIllumination( float2 texCoord, + float3 vLightTS, + float3 vViewTS, + float3 vNormalTS ) +{ + //return noiseNormal; + //return vNormalTS; + + float3 vLightTSAdj = float3( -vLightTS.x, -vLightTS.y, vLightTS.z ); + + float dp = dot( vNormalTS, vLightTSAdj ); + + // Calculate the amount of illumination (lightTerm)... + + // We do both a rim lighting effect and a halfLambertian lighting effect + // and combine the result. + float halfLambertTerm = saturate( pow( dp * 0.5 + 0.5, 1 ) ); + float rimLightTerm = pow( ( 1.0 - dp ), 1.0 ); + float lightTerm = saturate( halfLambertTerm * 1.0 + rimLightTerm * dp ); + lightTerm *= 0.5; + + // Use a simple RayleighPhase function to simulate single scattering towards + // the camera. + float angle = dot( vLightTS, vViewTS ); + lightTerm *= getRayleighPhase( angle ); + + // Combine terms and colors into the output color. + //float3 lightColor = ( lightTerm * sunColor * fOcclusionShadow ) + ambientColor; + float3 lightColor = lerp( ambientColor, sunColor, lightTerm ); + //lightColor = lerp( lightColor, ambientColor, cloudCoverage ); + float3 finalColor = cloudBaseColor * lightColor; + + return finalColor; +} + +float4 main( ConnectData IN ) : COLOR +{ + // Normalize the interpolated vectors: + float3 vViewTS = normalize( IN.vViewTS ); + float3 vLightTS = normalize( IN.vLightTS ); + + float4 cResultColor = float4( 0, 0, 0, 1 ); + + float2 texSample = IN.texCoord12.xy; + + float4 noise1 = tex2D( normalHeightMap, IN.texCoord12.zw ); + noise1 = normalize( ( noise1 - 0.5 ) * 2.0 ); + //return noise1; + + float4 noise2 = tex2D( normalHeightMap, IN.texCoord34.xy ); + noise2 = normalize( ( noise2 - 0.5 ) * 2.0 ); + //return noise2; + + float3 noiseNormal = normalize( noise1 + noise2 ).xyz; + //return float4( noiseNormal, 1.0 ); + + float noiseHeight = noise1.a * noise2.a * ( cloudCoverage / 2.0 + 0.5 ); + + float3 vNormalTS = normalize( tex2D( normalHeightMap, texSample ).xyz * 2.0 - 1.0 ); + vNormalTS += noiseNormal; + vNormalTS = normalize( vNormalTS ); + + // Compute resulting color for the pixel: + cResultColor.rgb = ComputeIllumination( texSample, vLightTS, vViewTS, vNormalTS ); + + float coverage = ( cloudCoverage - 0.5 ) * 2.0; + cResultColor.a = tex2D( normalHeightMap, texSample ).a + coverage + noiseHeight; + + if ( cloudCoverage > -1.0 ) + cResultColor.a /= 1.0 + coverage; + + cResultColor.a = saturate( cResultColor.a * pow( saturate(cloudCoverage), 0.25 ) ); + + cResultColor.a = lerp( cResultColor.a, 0.0, 1.0 - pow(IN.worldDist,2.0) ); + + cResultColor.rgb *= cloudExposure; + + return hdrEncode( cResultColor ); +} diff --git a/Templates/Empty/game/shaders/common/cloudLayerV.hlsl b/Templates/Empty/game/shaders/common/cloudLayerV.hlsl new file mode 100644 index 000000000..8c1cc555f --- /dev/null +++ b/Templates/Empty/game/shaders/common/cloudLayerV.hlsl @@ -0,0 +1,106 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- + +struct CloudVert +{ + float4 pos : POSITION; + float3 normal : NORMAL; + float3 binormal : BINORMAL; + float3 tangent : TANGENT; + float2 uv0 : TEXCOORD0; +}; + +struct ConnectData +{ + float4 hpos : POSITION; + float4 texCoord12 : TEXCOORD0; + float4 texCoord34 : TEXCOORD1; + float3 vLightTS : TEXCOORD2; // light vector in tangent space, denormalized + float3 vViewTS : TEXCOORD3; // view vector in tangent space, denormalized + float worldDist : TEXCOORD4; +}; + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- +uniform float4x4 modelview; +uniform float3 eyePosWorld; +uniform float3 sunVec; +uniform float2 texOffset0; +uniform float2 texOffset1; +uniform float2 texOffset2; +uniform float3 texScale; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( CloudVert IN ) +{ + ConnectData OUT; + + OUT.hpos = mul(modelview, IN.pos); + + // Offset the uv so we don't have a seam directly over our head. + float2 uv = IN.uv0 + float2( 0.5, 0.5 ); + + OUT.texCoord12.xy = uv * texScale.x; + OUT.texCoord12.xy += texOffset0; + + OUT.texCoord12.zw = uv * texScale.y; + OUT.texCoord12.zw += texOffset1; + + OUT.texCoord34.xy = uv * texScale.z; + OUT.texCoord34.xy += texOffset2; + + OUT.texCoord34.z = IN.pos.z; + OUT.texCoord34.w = 0.0; + + // Transform the normal, tangent and binormal vectors from object space to + // homogeneous projection space: + float3 vNormalWS = -IN.normal; + float3 vTangentWS = -IN.tangent; + float3 vBinormalWS = -IN.binormal; + + // Compute position in world space: + float4 vPositionWS = IN.pos + float4( eyePosWorld, 1 ); //mul( IN.pos, objTrans ); + + // Compute and output the world view vector (unnormalized): + float3 vViewWS = eyePosWorld - vPositionWS.xyz; + + // Compute denormalized light vector in world space: + float3 vLightWS = -sunVec; + + // Normalize the light and view vectors and transform it to the tangent space: + float3x3 mWorldToTangent = float3x3( vTangentWS, vBinormalWS, vNormalWS ); + + // Propagate the view and the light vectors (in tangent space): + OUT.vLightTS = mul( vLightWS, mWorldToTangent ); + OUT.vViewTS = mul( mWorldToTangent, vViewWS ); + + OUT.worldDist = saturate( pow( max( IN.pos.z, 0 ), 2 ) ); + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/debugInteriorsP.hlsl b/Templates/Empty/game/shaders/common/debugInteriorsP.hlsl new file mode 100644 index 000000000..c1f2c9065 --- /dev/null +++ b/Templates/Empty/game/shaders/common/debugInteriorsP.hlsl @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +struct ConnectData +{ + float2 texCoord : TEXCOORD0; +}; + + +struct Fragout +{ + float4 col : COLOR0; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Fragout main( ConnectData IN, + uniform sampler2D diffuseMap : register(S0), + uniform float4 shadeColor : register(C0) + +) +{ + Fragout OUT; + + OUT.col = shadeColor; + OUT.col *= tex2D(diffuseMap, IN.texCoord); + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/debugInteriorsV.hlsl b/Templates/Empty/game/shaders/common/debugInteriorsV.hlsl new file mode 100644 index 000000000..ae6066fc5 --- /dev/null +++ b/Templates/Empty/game/shaders/common/debugInteriorsV.hlsl @@ -0,0 +1,49 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "hlslStructs.h" + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- + +struct ConnectData +{ + float4 hpos : POSITION; + float2 outTexCoord : TEXCOORD0; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( VertexIn_PNTTTB IN, + uniform float4x4 modelview : register(C0) +) +{ + ConnectData OUT; + + OUT.hpos = mul(modelview, IN.pos); + OUT.outTexCoord = IN.uv0; + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/fixedFunction/addColorTextureP.hlsl b/Templates/Empty/game/shaders/common/fixedFunction/addColorTextureP.hlsl new file mode 100644 index 000000000..52ae4e955 --- /dev/null +++ b/Templates/Empty/game/shaders/common/fixedFunction/addColorTextureP.hlsl @@ -0,0 +1,28 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +float4 main( float4 color_in : COLOR0, + float2 texCoord_in : TEXCOORD0, + uniform sampler2D diffuseMap : register(S0) ) : COLOR0 +{ + return float4(color_in.rgb, color_in.a * tex2D(diffuseMap, texCoord_in).a); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/fixedFunction/addColorTextureV.hlsl b/Templates/Empty/game/shaders/common/fixedFunction/addColorTextureV.hlsl new file mode 100644 index 000000000..43a82dca6 --- /dev/null +++ b/Templates/Empty/game/shaders/common/fixedFunction/addColorTextureV.hlsl @@ -0,0 +1,42 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +struct Appdata +{ + float4 position : POSITION; + float4 color : COLOR; + float2 texCoord : TEXCOORD0; +}; +struct Conn +{ + float4 HPOS : POSITION; + float4 color : COLOR; + float2 texCoord : TEXCOORD0; +}; +Conn main( Appdata In, uniform float4x4 modelview : register(C0) ) +{ + Conn Out; + Out.HPOS = mul(modelview, In.position); + Out.color = In.color; + Out.texCoord = In.texCoord; + return Out; +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/fixedFunction/colorP.hlsl b/Templates/Empty/game/shaders/common/fixedFunction/colorP.hlsl new file mode 100644 index 000000000..90bb08112 --- /dev/null +++ b/Templates/Empty/game/shaders/common/fixedFunction/colorP.hlsl @@ -0,0 +1,26 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +float4 main( float4 color_in : COLOR0, uniform sampler2D diffuseMap : register(S0) ) : COLOR0 +{ + return color_in; +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/fixedFunction/colorV.hlsl b/Templates/Empty/game/shaders/common/fixedFunction/colorV.hlsl new file mode 100644 index 000000000..f0efe1493 --- /dev/null +++ b/Templates/Empty/game/shaders/common/fixedFunction/colorV.hlsl @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +struct Appdata +{ + float4 position : POSITION; + float4 color : COLOR; +}; +struct Conn +{ + float4 HPOS : POSITION; + float4 color : COLOR; +}; +Conn main( Appdata In, uniform float4x4 modelview : register(C0) ) +{ + Conn Out; + Out.HPOS = mul(modelview, In.position); + Out.color = In.color; + return Out; +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/fixedFunction/modColorTextureP.hlsl b/Templates/Empty/game/shaders/common/fixedFunction/modColorTextureP.hlsl new file mode 100644 index 000000000..ccf22845c --- /dev/null +++ b/Templates/Empty/game/shaders/common/fixedFunction/modColorTextureP.hlsl @@ -0,0 +1,28 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +float4 main( float4 color_in : COLOR0, + float2 texCoord_in : TEXCOORD0, + uniform sampler2D diffuseMap : register(S0) ) : COLOR0 +{ + return tex2D(diffuseMap, texCoord_in) * color_in; +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/fixedFunction/modColorTextureV.hlsl b/Templates/Empty/game/shaders/common/fixedFunction/modColorTextureV.hlsl new file mode 100644 index 000000000..43a82dca6 --- /dev/null +++ b/Templates/Empty/game/shaders/common/fixedFunction/modColorTextureV.hlsl @@ -0,0 +1,42 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +struct Appdata +{ + float4 position : POSITION; + float4 color : COLOR; + float2 texCoord : TEXCOORD0; +}; +struct Conn +{ + float4 HPOS : POSITION; + float4 color : COLOR; + float2 texCoord : TEXCOORD0; +}; +Conn main( Appdata In, uniform float4x4 modelview : register(C0) ) +{ + Conn Out; + Out.HPOS = mul(modelview, In.position); + Out.color = In.color; + Out.texCoord = In.texCoord; + return Out; +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/fixedFunction/targetRestoreP.hlsl b/Templates/Empty/game/shaders/common/fixedFunction/targetRestoreP.hlsl new file mode 100644 index 000000000..9ef44f426 --- /dev/null +++ b/Templates/Empty/game/shaders/common/fixedFunction/targetRestoreP.hlsl @@ -0,0 +1,31 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +uniform sampler2D colorTarget0Texture : register(s0); + +float4 main( float2 ScreenPos : VPOS ) : COLOR0 +{ + float2 TexCoord = ScreenPos; + float4 diffuse; + asm { tfetch2D diffuse, TexCoord, colorTarget0Texture, UnnormalizedTextureCoords = true }; + return diffuse; +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/fixedFunction/targetRestoreV.hlsl b/Templates/Empty/game/shaders/common/fixedFunction/targetRestoreV.hlsl new file mode 100644 index 000000000..3c4aefaec --- /dev/null +++ b/Templates/Empty/game/shaders/common/fixedFunction/targetRestoreV.hlsl @@ -0,0 +1,26 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +float4 main( const float2 inPosition : POSITION ) : POSITION +{ + return float4( inPosition, 0, 1 ); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/foliage.hlsl b/Templates/Empty/game/shaders/common/foliage.hlsl new file mode 100644 index 000000000..e875bb23f --- /dev/null +++ b/Templates/Empty/game/shaders/common/foliage.hlsl @@ -0,0 +1,186 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// CornerId corresponds to this arrangement +// from the perspective of the camera. +// +// 3 ---- 2 +// | | +// 0 ---- 1 +// + +#define MAX_COVERTYPES 8 + +uniform float3 gc_camRight; +uniform float3 gc_camUp; +uniform float4 gc_typeRects[MAX_COVERTYPES]; +uniform float2 gc_fadeParams; +uniform float2 gc_windDir; + +// .x = gust length +// .y = premultiplied simulation time and gust frequency +// .z = gust strength +uniform float3 gc_gustInfo; + +// .x = premultiplied simulation time and turbulance frequency +// .y = turbulance strength +uniform float2 gc_turbInfo; + + +static float sCornerRight[4] = { -0.5, 0.5, 0.5, -0.5 }; + +static float sCornerUp[4] = { 0, 0, 1, 1 }; + +static float sMovableCorner[4] = { 0, 0, 1, 1 }; + +static float2 sUVCornerExtent[4] = +{ + float2( 0, 1 ), + float2( 1, 1 ), + float2( 1, 0 ), + float2( 0, 0 ) +}; + + +/////////////////////////////////////////////////////////////////////////////// +// The following wind effect was derived from the GPU Gems 3 chapter... +// +// "Vegetation Procedural Animation and Shading in Crysis" +// by Tiago Sousa, Crytek +// + +float2 smoothCurve( float2 x ) +{ + return x * x * ( 3.0 - 2.0 * x ); +} + +float2 triangleWave( float2 x ) +{ + return abs( frac( x + 0.5 ) * 2.0 - 1.0 ); +} + +float2 smoothTriangleWave( float2 x ) +{ + return smoothCurve( triangleWave( x ) ); +} + +float windTurbulence( float bbPhase, float frequency, float strength ) +{ + // We create the input value for wave generation from the frequency and phase. + float2 waveIn = bbPhase.xx + frequency.xx; + + // We use two square waves to generate the effect which + // is then scaled by the overall strength. + float2 waves = ( frac( waveIn.xy * float2( 1.975, 0.793 ) ) * 2.0 - 1.0 ); + waves = smoothTriangleWave( waves ); + + // Sum up the two waves into a single wave. + return ( waves.x + waves.y ) * strength; +} + +float2 windEffect( float bbPhase, + float2 windDirection, + float gustLength, + float gustFrequency, + float gustStrength, + float turbFrequency, + float turbStrength ) +{ + // Calculate the ambient wind turbulence. + float turbulence = windTurbulence( bbPhase, turbFrequency, turbStrength ); + + // We simulate the overall gust via a sine wave. + float gustPhase = clamp( sin( ( bbPhase - gustFrequency ) / gustLength ) , 0, 1 ); + float gustOffset = ( gustPhase * gustStrength ) + ( ( 0.2 + gustPhase ) * turbulence ); + + // Return the final directional wind effect. + return gustOffset.xx * windDirection.xy; +} + +void foliageProcessVert( inout float3 position, + inout float4 diffuse, + inout float4 texCoord, + inout float3 normal, + inout float3 T, + in float3 eyePos ) +{ + // Assign the normal and tagent values. + //normal = float3( 0, 0, 1 );//cross( gc_camUp, gc_camRight ); + T = gc_camRight; + + // Pull out local vars we need for work. + int corner = ( diffuse.a * 255.0f ) + 0.5f; + float2 size = texCoord.xy; + int type = texCoord.z; + + // The billboarding is based on the camera direction. + float3 rightVec = gc_camRight * sCornerRight[corner]; + float3 upVec = gc_camUp * sCornerUp[corner]; + + // Figure out the corner position. + float3 outPos = ( upVec * size.y ) + ( rightVec * size.x ); + float len = length( outPos.xyz ); + + // We derive the billboard phase used for wind calculations from its position. + float bbPhase = dot( position.xyz, 1 ); + + // Get the overall wind gust and turbulence effects. + float3 wind; + wind.xy = windEffect( bbPhase, + gc_windDir, + gc_gustInfo.x, gc_gustInfo.y, gc_gustInfo.z, + gc_turbInfo.x, gc_turbInfo.y ); + wind.z = 0; + + // Add the summed wind effect into the point. + outPos.xyz += wind.xyz * texCoord.w; + + // Do a simple spherical clamp to keep the foliage + // from stretching too much by wind effect. + outPos.xyz = normalize( outPos.xyz ) * len; + + // Move the point into world space. + position += outPos; + + // Grab the uv set and setup the texture coord. + float4 uvSet = gc_typeRects[type]; + texCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x ); + texCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y ); + + // Animate the normal to get lighting changes + // across the the wind swept foliage. + // + // TODO: Expose the 10x as a factor to control + // how much the wind effects the lighting on the grass. + // + normal.xy += wind.xy * ( 10.0 * texCoord.w ); + normal = normalize( normal ); + + // Get the alpha fade value. + + float fadeStart = gc_fadeParams.x; + float fadeEnd = gc_fadeParams.y; + const float fadeRange = fadeEnd - fadeStart; + + float dist = distance( eyePos, position.xyz ) - fadeStart; + diffuse.a = 1 - clamp( dist / fadeRange, 0, 1 ); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/fxFoliageReplicatorP.hlsl b/Templates/Empty/game/shaders/common/fxFoliageReplicatorP.hlsl new file mode 100644 index 000000000..dfa2e4de0 --- /dev/null +++ b/Templates/Empty/game/shaders/common/fxFoliageReplicatorP.hlsl @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shdrConsts.h" + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +struct ConnectData +{ + float2 texCoord : TEXCOORD0; + float4 lum : COLOR0; + float4 groundAlphaCoeff : COLOR1; + float2 alphaLookup : TEXCOORD1; +}; + +struct Fragout +{ + float4 col : COLOR0; +}; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Fragout main( ConnectData IN, + uniform sampler2D diffuseMap : register(S0), + uniform sampler2D alphaMap : register(S1), + uniform float4 groundAlpha, + uniform float4 ambient ) +{ + Fragout OUT; + + float4 alpha = tex2D(alphaMap, IN.alphaLookup); + OUT.col = float4( ambient.rgb * IN.lum.rgb, 1.0 ) * tex2D(diffuseMap, IN.texCoord); + OUT.col.a = OUT.col.a * min(alpha, groundAlpha + IN.groundAlphaCoeff.x).x; + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/fxFoliageReplicatorV.hlsl b/Templates/Empty/game/shaders/common/fxFoliageReplicatorV.hlsl new file mode 100644 index 000000000..06a9cf5e5 --- /dev/null +++ b/Templates/Empty/game/shaders/common/fxFoliageReplicatorV.hlsl @@ -0,0 +1,126 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +struct VertData +{ + float2 texCoord : TEXCOORD0; + float2 waveScale : TEXCOORD1; + float3 normal : NORMAL; + float4 position : POSITION; +}; + +struct ConnectData +{ + float4 hpos : POSITION; + float2 outTexCoord : TEXCOORD0; + float4 color : COLOR0; + float4 groundAlphaCoeff : COLOR1; + float2 alphaLookup : TEXCOORD1; +}; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( VertData IN, + uniform float4x4 projection : register(C0), + uniform float4x4 world : register(C4), + uniform float GlobalSwayPhase : register(C8), + uniform float SwayMagnitudeSide : register(C9), + uniform float SwayMagnitudeFront : register(C10), + uniform float GlobalLightPhase : register(C11), + uniform float LuminanceMagnitude : register(C12), + uniform float LuminanceMidpoint : register(C13), + uniform float DistanceRange : register(C14), + uniform float3 CameraPos : register(C15), + uniform float TrueBillboard : register(C16) +) +{ + ConnectData OUT; + + // Init a transform matrix to be used in the following steps + float4x4 trans = 0; + trans[0][0] = 1; + trans[1][1] = 1; + trans[2][2] = 1; + trans[3][3] = 1; + trans[0][3] = IN.position.x; + trans[1][3] = IN.position.y; + trans[2][3] = IN.position.z; + + // Billboard transform * world matrix + float4x4 o = world; + o = mul(o, trans); + + // Keep only the up axis result and position transform. + // This gives us "cheating" cylindrical billboarding. + o[0][0] = 1; + o[1][0] = 0; + o[2][0] = 0; + o[3][0] = 0; + o[0][1] = 0; + o[1][1] = 1; + o[2][1] = 0; + o[3][1] = 0; + + // Unless the user specified TrueBillboard, + // in which case we want the z axis to also be camera facing. + +#ifdef TRUE_BILLBOARD + + o[0][2] = 0; + o[1][2] = 0; + o[2][2] = 1; + o[3][2] = 0; + +#endif + + // Handle sway. Sway is stored in a texture coord. The x coordinate is the sway phase multiplier, + // the y coordinate determines if this vertex actually sways or not. + float xSway, ySway; + float wavePhase = GlobalSwayPhase * IN.waveScale.x; + sincos(wavePhase, ySway, xSway); + xSway = xSway * IN.waveScale.y * SwayMagnitudeSide; + ySway = ySway * IN.waveScale.y * SwayMagnitudeFront; + float4 p; + p = mul(o, float4(IN.normal.x + xSway, ySway, IN.normal.z, 1)); + + // Project the point + OUT.hpos = mul(projection, p); + + // Lighting + float Luminance = LuminanceMidpoint + LuminanceMagnitude * cos(GlobalLightPhase + IN.normal.y); + + // Alpha + float3 worldPos = float3(IN.position.x, IN.position.y, IN.position.z); + float alpha = abs(distance(worldPos, CameraPos)) / DistanceRange; + alpha = clamp(alpha, 0.0f, 1.0f); //pass it through + + OUT.alphaLookup = float2(alpha, 0.0f); + OUT.groundAlphaCoeff = all(IN.normal.z); + OUT.outTexCoord = IN.texCoord; + OUT.color = float4(Luminance, Luminance, Luminance, 1.0f); + + return OUT; +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/gl/blurP.glsl b/Templates/Empty/game/shaders/common/gl/blurP.glsl new file mode 100644 index 000000000..bc05b992f --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/blurP.glsl @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//***************************************************************************** +// Glow Shader +//***************************************************************************** +uniform vec4 kernel; +uniform sampler2D diffuseMap; + +varying vec2 texc0, texc1, texc2, texc3; + +void main() +{ + gl_FragColor = texture2D(diffuseMap, texc0) * kernel.x; + gl_FragColor += texture2D(diffuseMap, texc1) * kernel.y; + gl_FragColor += texture2D(diffuseMap, texc2) * kernel.z; + gl_FragColor += texture2D(diffuseMap, texc3) * kernel.w; +} diff --git a/Templates/Empty/game/shaders/common/gl/blurV.glsl b/Templates/Empty/game/shaders/common/gl/blurV.glsl new file mode 100644 index 000000000..d5d615fb9 --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/blurV.glsl @@ -0,0 +1,43 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//***************************************************************************** +// Glow shader +//***************************************************************************** + +uniform mat4 modelview; +uniform vec2 offset0, offset1, offset2, offset3; + +varying vec2 texc0, texc1, texc2, texc3; + +void main() +{ + gl_Position = modelview * gl_Vertex; + + vec2 tc = gl_MultiTexCoord0.st; + tc.y = 1.0 - tc.y; + + texc0 = tc + offset0; + texc1 = tc + offset1; + texc2 = tc + offset2; + texc3 = tc + offset3; +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/gl/cloudLayerP.glsl b/Templates/Empty/game/shaders/common/gl/cloudLayerP.glsl new file mode 100644 index 000000000..326f2d3c6 --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/cloudLayerP.glsl @@ -0,0 +1,139 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "hlslCompat.glsl" + +varying vec4 texCoord12; +varying vec4 texCoord34; +varying vec3 vLightTS; // light vector in tangent space, denormalized +varying vec3 vViewTS; // view vector in tangent space, denormalized +varying vec3 vNormalWS; // Normal vector in world space +varying float worldDist; + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- +uniform sampler2D normalHeightMap; +uniform vec3 ambientColor; +uniform vec3 sunColor; +uniform float cloudCoverage; +uniform vec3 cloudBaseColor; + +//----------------------------------------------------------------------------- +// Globals +//----------------------------------------------------------------------------- +// The per-color weighting to be used for luminance calculations in RGB order. +const vec3 LUMINANCE_VECTOR = vec3(0.2125f, 0.7154f, 0.0721f); + + +//----------------------------------------------------------------------------- +// Functions +//----------------------------------------------------------------------------- + +// Calculates the Rayleigh phase function +float getRayleighPhase( float angle ) +{ + return 0.75 * ( 1.0 + pow( angle, 2.0 ) ); +} + +// Returns the output rgb color given a texCoord and parameters it uses +// for lighting calculation. +vec3 ComputeIllumination( vec2 texCoord, + vec3 vLightTS, + vec3 vViewTS, + vec3 vNormalTS ) +{ + //return noiseNormal; + //return vNormalTS; + + vec3 vLightTSAdj = vec3( -vLightTS.x, -vLightTS.y, vLightTS.z ); + + float dp = dot( vNormalTS, vLightTSAdj ); + + // Calculate the amount of illumination (lightTerm)... + + // We do both a rim lighting effect and a halfLambertian lighting effect + // and combine the result. + float halfLambertTerm = clamp( pow( dp * 0.5 + 0.5, 1.0 ), 0.0, 1.0 ); + float rimLightTerm = pow( ( 1.0 - dp ), 1.0 ); + float lightTerm = clamp( halfLambertTerm * 1.0 + rimLightTerm * dp, 0.0, 1.0 ); + lightTerm *= 0.5; + + // Use a simple RayleighPhase function to simulate single scattering towards + // the camera. + float angle = dot( vLightTS, vViewTS ); + lightTerm *= getRayleighPhase( angle ); + + // Combine terms and colors into the output color. + //vec3 lightColor = ( lightTerm * sunColor * fOcclusionShadow ) + ambientColor; + vec3 lightColor = mix( ambientColor, sunColor, lightTerm ); + //lightColor = mix( lightColor, ambientColor, cloudCoverage ); + vec3 finalColor = cloudBaseColor * lightColor; + + return finalColor; +} + +void main() +{ + // Normalize the interpolated vectors: + vec3 vViewTS = normalize( vViewTS ); + vec3 vLightTS = normalize( vLightTS ); + vec3 vNormalWS = normalize( vNormalWS ); + + vec4 cResultColor = float4( 0, 0, 0, 1 ); + + vec2 texSample = texCoord12.xy; + + vec4 noise1 = texture2D( normalHeightMap, texCoord12.zw ); + noise1 = normalize( ( noise1 - 0.5 ) * 2.0 ); + //return noise1; + + vec4 noise2 = texture2D( normalHeightMap, texCoord34.xy ); + noise2 = normalize( ( noise2 - 0.5 ) * 2.0 ); + //return noise2; + + vec3 noiseNormal = normalize( noise1 + noise2 ).xyz; + //return float4( noiseNormal, 1.0 ); + + float noiseHeight = noise1.a * noise2.a * ( cloudCoverage / 2.0 + 0.5 ); + + vec3 vNormalTS = normalize( texture2D( normalHeightMap, texSample ).xyz * 2.0 - 1.0 ); + vNormalTS += noiseNormal; + vNormalTS = normalize( vNormalTS ); + + // Compute resulting color for the pixel: + cResultColor.rgb = ComputeIllumination( texSample, vLightTS, vViewTS, vNormalTS ); + + float coverage = ( cloudCoverage - 0.5 ) * 2.0; + cResultColor.a = texture2D( normalHeightMap, texSample ).a + coverage + noiseHeight; + + if ( cloudCoverage > -1.0 ) + cResultColor.a /= 1.0 + coverage; + + cResultColor.a = saturate( cResultColor.a * pow( saturate(cloudCoverage), 0.25 ) ); + + cResultColor.a = mix( cResultColor.a, 0.0, 1.0 - pow(worldDist,2.0) ); + + // If using HDR rendering, make sure to tonemap the resuld color prior to outputting it. + // But since this example isn't doing that, we just output the computed result color here: + gl_FragColor = cResultColor; +} diff --git a/Templates/Empty/game/shaders/common/gl/cloudLayerV.glsl b/Templates/Empty/game/shaders/common/gl/cloudLayerV.glsl new file mode 100644 index 000000000..39a6f4ba8 --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/cloudLayerV.glsl @@ -0,0 +1,92 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +varying vec4 texCoord12; +varying vec4 texCoord34; +varying vec3 vLightTS; // light vector in tangent space, denormalized +varying vec3 vViewTS; // view vector in tangent space, denormalized +varying vec3 vNormalWS; // Normal vector in world space +varying float worldDist; + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- +uniform mat4 modelview; +uniform vec3 eyePosWorld; +uniform vec3 sunVec; +uniform vec2 texOffset0; +uniform vec2 texOffset1; +uniform vec2 texOffset2; +uniform vec3 texScale; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + vec4 pos = gl_Vertex; + vec3 normal = gl_Normal; + vec3 binormal = gl_MultiTexCoord0.xyz; + vec3 tangent = gl_MultiTexCoord1.xyz; + vec2 uv0 = gl_MultiTexCoord2.st; + + gl_Position = modelview * pos; + + // Offset the uv so we don't have a seam directly over our head. + vec2 uv = uv0 + vec2( 0.5, 0.5 ); + + texCoord12.xy = uv * texScale.x; + texCoord12.xy += texOffset0; + + texCoord12.zw = uv * texScale.y; + texCoord12.zw += texOffset1; + + texCoord34.xy = uv * texScale.z; + texCoord34.xy += texOffset2; + + texCoord34.z = pos.z; + texCoord34.w = 0.0; + + // Transform the normal, tangent and binormal vectors from object space to + // homogeneous projection space: + vNormalWS = -normal; + vec3 vTangentWS = -tangent; + vec3 vBinormalWS = -binormal; + + // Compute position in world space: + vec4 vPositionWS = pos + vec4( eyePosWorld, 1 ); //mul( pos, objTrans ); + + // Compute and output the world view vector (unnormalized): + vec3 vViewWS = eyePosWorld - vPositionWS.xyz; + + // Compute denormalized light vector in world space: + vec3 vLightWS = -sunVec; + + // Normalize the light and view vectors and transform it to the tangent space: + mat3 mWorldToTangent = mat3( vTangentWS, vBinormalWS, vNormalWS ); + + // Propagate the view and the light vectors (in tangent space): + vLightTS = mWorldToTangent * vLightWS; + vViewTS = vViewWS * mWorldToTangent; + + worldDist = clamp( pow( pos.z, 2.0 ), 0.0, 1.0 ); +} diff --git a/Templates/Empty/game/shaders/common/gl/debugInteriorsP.glsl b/Templates/Empty/game/shaders/common/gl/debugInteriorsP.glsl new file mode 100644 index 000000000..36725d38a --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/debugInteriorsP.glsl @@ -0,0 +1,34 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +uniform sampler2D diffuseMap; +uniform vec4 shadeColor; + +varying vec2 TEX0; + +void main() +{ + vec4 diffuseColor = texture2D( diffuseMap, TEX0 ); + + gl_FragColor = diffuseColor; + gl_FragColor *= shadeColor; +} diff --git a/Templates/Empty/game/shaders/common/gl/debugInteriorsV.glsl b/Templates/Empty/game/shaders/common/gl/debugInteriorsV.glsl new file mode 100644 index 000000000..8bfab07eb --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/debugInteriorsV.glsl @@ -0,0 +1,33 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +uniform mat4 modelview; + +varying vec2 TEX0; + +void main() +{ + gl_Position = modelview * gl_Vertex; + TEX0 = gl_MultiTexCoord0.st; +} + + diff --git a/Templates/Empty/game/shaders/common/gl/foliage.glsl b/Templates/Empty/game/shaders/common/gl/foliage.glsl new file mode 100644 index 000000000..2fee902e3 --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/foliage.glsl @@ -0,0 +1,196 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// CornerId corresponds to this arrangement +// from the perspective of the camera. +// +// 3 ---- 2 +// | | +// 0 ---- 1 +// + +#define MAX_COVERTYPES 8 + +uniform vec3 gc_camRight; +uniform vec3 gc_camUp; +uniform vec4 gc_typeRects[MAX_COVERTYPES]; +uniform vec2 gc_fadeParams; +uniform vec2 gc_windDir; + +// .x = gust length +// .y = premultiplied simulation time and gust frequency +// .z = gust strength +uniform vec3 gc_gustInfo; + +// .x = premultiplied simulation time and turbulance frequency +// .y = turbulance strength +uniform vec2 gc_turbInfo; + + +//static float sMovableCorner[4] = { 0.0, 0.0, 1.0, 1.0 }; + + +/////////////////////////////////////////////////////////////////////////////// +// The following wind effect was derived from the GPU Gems 3 chapter... +// +// "Vegetation Procedural Animation and Shading in Crysis" +// by Tiago Sousa, Crytek +// + +vec2 smoothCurve( vec2 x ) +{ + return x * x * ( 3.0 - 2.0 * x ); +} + +vec2 triangleWave( vec2 x ) +{ + return abs( fract( x + 0.5 ) * 2.0 - 1.0 ); +} + +vec2 smoothTriangleWave( vec2 x ) +{ + return smoothCurve( triangleWave( x ) ); +} + +float windTurbulence( float bbPhase, float frequency, float strength ) +{ + // We create the input value for wave generation from the frequency and phase. + vec2 waveIn = vec2( bbPhase + frequency ); + + // We use two square waves to generate the effect which + // is then scaled by the overall strength. + vec2 waves = ( fract( waveIn.xy * vec2( 1.975, 0.793 ) ) * 2.0 - 1.0 ); + waves = smoothTriangleWave( waves ); + + // Sum up the two waves into a single wave. + return ( waves.x + waves.y ) * strength; +} + +vec2 windEffect( float bbPhase, + vec2 windDirection, + float gustLength, + float gustFrequency, + float gustStrength, + float turbFrequency, + float turbStrength ) +{ + // Calculate the ambient wind turbulence. + float turbulence = windTurbulence( bbPhase, turbFrequency, turbStrength ); + + // We simulate the overall gust via a sine wave. + float gustPhase = clamp( sin( ( bbPhase - gustFrequency ) / gustLength ) , 0.0, 1.0 ); + float gustOffset = ( gustPhase * gustStrength ) + ( ( 0.2 + gustPhase ) * turbulence ); + + // Return the final directional wind effect. + return vec2(gustOffset) * windDirection.xy; +} + +void foliageProcessVert( inout vec3 position, + inout vec4 diffuse, + in vec4 texCoord, + out vec2 outTexCoord, + inout vec3 normal, + inout vec3 T, + in vec3 eyePos ) +{ + + float sCornerRight[4]; + sCornerRight[0] = -0.5; + sCornerRight[1] = 0.5; + sCornerRight[2] = 0.5; + sCornerRight[3] = -0.5; + + float sCornerUp[4]; + sCornerUp[0] = 0.0; + sCornerUp[1] = 0.0; + sCornerUp[2] = 1.0; + sCornerUp[3] = 1.0; + + vec2 sUVCornerExtent[4]; + sUVCornerExtent[0] = vec2( 0.0, 1.0 ); + sUVCornerExtent[1] = vec2( 1.0, 1.0 ); + sUVCornerExtent[2] = vec2( 1.0, 0.0 ); + sUVCornerExtent[3] = vec2( 0.0, 0.0 ); + + + // Assign the normal and tagent values. + //normal = cross( gc_camUp, gc_camRight ); + T = gc_camRight; + + // Pull out local vars we need for work. + int corner = int( ( diffuse.a * 255.0 ) + 0.5 ); + vec2 size = texCoord.xy; + int type = int( texCoord.z ); + + // The billboarding is based on the camera direction. + vec3 rightVec = gc_camRight * sCornerRight[corner]; + vec3 upVec = gc_camUp * sCornerUp[corner]; + + // Figure out the corner position. + vec3 outPos = ( upVec * size.y ) + ( rightVec * size.x ); + float len = length( outPos.xyz ); + + // We derive the billboard phase used for wind calculations from its position. + float bbPhase = dot( position.xyz, vec3( 1.0 ) ); + + // Get the overall wind gust and turbulence effects. + vec3 wind; + wind.xy = windEffect( bbPhase, + gc_windDir, + gc_gustInfo.x, gc_gustInfo.y, gc_gustInfo.z, + gc_turbInfo.x, gc_turbInfo.y ); + wind.z = 0.0; + + // Add the summed wind effect into the point. + outPos.xyz += wind.xyz * texCoord.w; + + // Do a simple spherical clamp to keep the foliage + // from stretching too much by wind effect. + outPos.xyz = normalize( outPos.xyz ) * len; + + // Move the point into world space. + position += outPos; + + // Grab the uv set and setup the texture coord. + vec4 uvSet = gc_typeRects[type]; + outTexCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x ); + outTexCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y ); + + // Animate the normal to get lighting changes + // across the the wind swept foliage. + // + // TODO: Expose the 10x as a factor to control + // how much the wind effects the lighting on the grass. + // + normal.xy += wind.xy * ( 10.0 * texCoord.w ); + normal = normalize( normal ); + + + // Get the alpha fade value. + + float fadeStart = gc_fadeParams.x; + float fadeEnd = gc_fadeParams.y; + float fadeRange = fadeEnd - fadeStart; + + float dist = distance( eyePos, position.xyz ) - fadeStart; + diffuse.a = 1.0 - clamp( dist / fadeRange, 0.0, 1.0 ); +} diff --git a/Templates/Empty/game/shaders/common/gl/fxFoliageReplicatorP.glsl b/Templates/Empty/game/shaders/common/gl/fxFoliageReplicatorP.glsl new file mode 100644 index 000000000..9e5b34caa --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/fxFoliageReplicatorP.glsl @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Data +//----------------------------------------------------------------------------- +uniform sampler2D diffuseMap, alphaMap; +uniform vec4 groundAlpha; + +varying vec4 color, groundAlphaCoeff; +varying vec2 outTexCoord, alphaLookup; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + vec4 alpha = texture2D(alphaMap, alphaLookup); + gl_FragColor = color * texture2D(diffuseMap, outTexCoord); + gl_FragColor.a = gl_FragColor.a * min(alpha, groundAlpha + groundAlphaCoeff.x).x; +} diff --git a/Templates/Empty/game/shaders/common/gl/fxFoliageReplicatorV.glsl b/Templates/Empty/game/shaders/common/gl/fxFoliageReplicatorV.glsl new file mode 100644 index 000000000..94a7af2b0 --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/fxFoliageReplicatorV.glsl @@ -0,0 +1,91 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Data +//----------------------------------------------------------------------------- +uniform mat4 projection, world; +uniform vec3 CameraPos; +uniform float GlobalSwayPhase, SwayMagnitudeSide, SwayMagnitudeFront, + GlobalLightPhase, LuminanceMagnitude, LuminanceMidpoint, DistanceRange; + +varying vec4 color, groundAlphaCoeff; +varying vec2 outTexCoord, alphaLookup; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + // Init a transform matrix to be used in the following steps + mat4 trans = mat4(0.0); + trans[0][0] = 1.0; + trans[1][1] = 1.0; + trans[2][2] = 1.0; + trans[3][3] = 1.0; + trans[3][0] = gl_Vertex.x; + trans[3][1] = gl_Vertex.y; + trans[3][2] = gl_Vertex.z; + + // Billboard transform * world matrix + mat4 o = world; + o = o * trans; + + // Keep only the up axis result and position transform. + // This gives us "cheating" cylindrical billboarding. + o[0][0] = 1.0; + o[0][1] = 0.0; + o[0][2] = 0.0; + o[0][3] = 0.0; + o[1][0] = 0.0; + o[1][1] = 1.0; + o[1][2] = 0.0; + o[1][3] = 0.0; + + // Handle sway. Sway is stored in a texture coord. The x coordinate is the sway phase multiplier, + // the y coordinate determines if this vertex actually sways or not. + float xSway, ySway; + float wavePhase = GlobalSwayPhase * gl_MultiTexCoord1.x; + ySway = sin(wavePhase); + xSway = cos(wavePhase); + xSway = xSway * gl_MultiTexCoord1.y * SwayMagnitudeSide; + ySway = ySway * gl_MultiTexCoord1.y * SwayMagnitudeFront; + vec4 p; + p = o * vec4(gl_Normal.x + xSway, ySway, gl_Normal.z, 1.0); + + // Project the point + gl_Position = projection * p; + + // Lighting + float Luminance = LuminanceMidpoint + LuminanceMagnitude * cos(GlobalLightPhase + gl_Normal.y); + + // Alpha + vec3 worldPos = vec3(gl_Vertex.x, gl_Vertex.y, gl_Vertex.z); + float alpha = abs(distance(worldPos, CameraPos)) / DistanceRange; + alpha = clamp(alpha, 0.0, 1.0); //pass it through + + alphaLookup = vec2(alpha, 0.0); + bool alphaCoeff = bool(gl_Normal.z); + groundAlphaCoeff = vec4(float(alphaCoeff)); + outTexCoord = gl_MultiTexCoord0.st; + color = vec4(Luminance, Luminance, Luminance, 1.0); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/gl/guiMaterialV.glsl b/Templates/Empty/game/shaders/common/gl/guiMaterialV.glsl new file mode 100644 index 000000000..cd44de2f2 --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/guiMaterialV.glsl @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +uniform mat4x4 modelview; + +varying vec4 hpos; +varying vec2 uv0; + + +void main() +{ + hpos = vec4( modelview * gl_Vertex ); + gl_Position = hpos; + + uv0 = gl_MultiTexCoord0.st; +} diff --git a/Templates/Empty/game/shaders/common/gl/hlslCompat.glsl b/Templates/Empty/game/shaders/common/gl/hlslCompat.glsl new file mode 100644 index 000000000..be5c63340 --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/hlslCompat.glsl @@ -0,0 +1,43 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// These are some simple wrappers for simple +// HLSL compatibility. + +#define float4 vec4 +#define float3 vec3 +#define float2 vec2 + +#define texCUBE textureCube +#define tex2D texture2D + +#define lerp mix + +float saturate( float val ) { return clamp( val, 0.0, 1.0 ); } +vec2 saturate( vec2 val ) { return clamp( val, 0.0, 1.0 ); } +vec3 saturate( vec3 val ) { return clamp( val, 0.0, 1.0 ); } +vec4 saturate( vec4 val ) { return clamp( val, 0.0, 1.0 ); } + +float round( float n ) { return sign( n ) * floor( abs( n ) + 0.5 ); } +vec2 round( vec2 n ) { return sign( n ) * floor( abs( n ) + 0.5 ); } +vec3 round( vec3 n ) { return sign( n ) * floor( abs( n ) + 0.5 ); } +vec4 round( vec4 n ) { return sign( n ) * floor( abs( n ) + 0.5 ); } diff --git a/Templates/Empty/game/shaders/common/gl/imposter.glsl b/Templates/Empty/game/shaders/common/gl/imposter.glsl new file mode 100644 index 000000000..20bc62688 --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/imposter.glsl @@ -0,0 +1,161 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "torque.glsl" + + +#define IMPOSTER_MAX_UVS 64 + + +void imposter_v( + // These parameters usually come from the vertex. + vec3 center, + int corner, + float halfSize, + vec3 imposterUp, + vec3 imposterRight, + + // These are from the imposter shader constant. + int numEquatorSteps, + int numPolarSteps, + float polarAngle, + bool includePoles, + + // Other shader constants. + vec3 camPos, + vec4 uvs[IMPOSTER_MAX_UVS], + + // The outputs of this function. + out vec3 outWsPosition, + out vec2 outTexCoord, + out mat3 outWorldToTangent + ) +{ + + float M_HALFPI_F = 1.57079632679489661923; + float M_PI_F = 3.14159265358979323846; + float M_2PI_F = 6.28318530717958647692; + + + float sCornerRight[4];// = float[]( -1.0, 1.0, 1.0, -1.0 ); + sCornerRight[0] = -1.0; + sCornerRight[1] = 1.0; + sCornerRight[2] = 1.0; + sCornerRight[3] = -1.0; + float sCornerUp[4];// = float[]( -1.0, -1.0, 1.0, 1.0 ); + sCornerUp[0] = -1.0; + sCornerUp[1] = -1.0; + sCornerUp[2] = 1.0; + sCornerUp[3] = 1.0; + vec2 sUVCornerExtent[4];// = vec2[](vec2( 0.0, 1.0 ), vec2( 1.0, 1.0 ), vec2( 1.0, 0.0 ), vec2( 0.0, 0.0 )); + sUVCornerExtent[0] = vec2( 0.0, 1.0 ); + sUVCornerExtent[1] = vec2( 1.0, 1.0 ); + sUVCornerExtent[2] = vec2( 1.0, 0.0 ); + sUVCornerExtent[3] = vec2( 0.0, 0.0 ); + + // TODO: This could all be calculated on the CPU. + float equatorStepSize = M_2PI_F / float( numEquatorSteps ); + float equatorHalfStep = ( equatorStepSize / 2.0 ) - 0.0001; + float polarStepSize = M_PI_F / float( numPolarSteps ); + float polarHalfStep = ( polarStepSize / 2.0 ) - 0.0001; + + // The vector between the camera and the billboard. + vec3 lookVec = normalize( camPos - center ); + + // Generate the camera up and right vectors from + // the object transform and camera forward. + vec3 camUp = imposterUp; + vec3 camRight = cross( -lookVec, camUp ); + + // The billboarding is based on the camera directions. + vec3 rightVec = camRight * sCornerRight[corner]; + vec3 upVec = camUp * sCornerUp[corner]; + + float lookPitch = acos( dot( imposterUp, lookVec ) ); + + // First check to see if we need to render the top billboard. + int index; + /* + if ( includePoles && ( lookPitch < polarAngle || lookPitch > sPi - polarAngle ) ) + { + index = numEquatorSteps * 3; + + // When we render the top/bottom billboard we always use + // a fixed vector that matches the rotation of the object. + rightVec = vec3( 1, 0, 0 ) * sCornerRight[corner]; + upVec = vec3( 0, 1, 0 ) * sCornerUp[corner]; + + if ( lookPitch > sPi - polarAngle ) + { + upVec = -upVec; + index++; + } + } + else + */ + { + // Calculate the rotation around the z axis then add the + // equator half step. This gets the images to switch a + // half step before the captured angle is met. + float lookAzimuth = atan( lookVec.y, lookVec.x ); + float azimuth = atan( imposterRight.y, imposterRight.x ); + float rotZ = ( lookAzimuth - azimuth ) + equatorHalfStep; + + // The y rotation is calculated from the look vector and + // the object up vector. + float rotY = lookPitch - polarHalfStep; + + // TODO: How can we do this without conditionals? + // Normalize the result to 0 to 2PI. + if ( rotZ < 0.0 ) + rotZ += M_2PI_F; + if ( rotZ > M_2PI_F ) + rotZ -= M_2PI_F; + if ( rotY < 0.0 ) + rotY += M_2PI_F; + if ( rotY > M_PI_F ) // Not M_2PI_F? + rotY -= M_2PI_F; + + float polarIdx = round( abs( rotY ) / polarStepSize ); + + // Get the index to the start of the right polar + // images for this viewing angle. + int numPolarOffset = int( float( numEquatorSteps ) * polarIdx ); + + // Calculate the final image index for lookup + // of the texture coords. + index = int( rotZ / equatorStepSize ) + numPolarOffset; + } + + // Generate the final world space position. + outWsPosition = center + ( upVec * halfSize ) + ( rightVec * halfSize ); + + // Grab the uv set and setup the texture coord. + vec4 uvSet = uvs[index]; + outTexCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x ); + outTexCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y ); + + // Needed for normal mapping and lighting. + outWorldToTangent[0] = vec3( 1, 0, 0 ); + outWorldToTangent[1] = vec3( 0, 1, 0 ); + outWorldToTangent[2] = vec3( 0, 0, -1 ); +} diff --git a/Templates/Empty/game/shaders/common/gl/lighting.glsl b/Templates/Empty/game/shaders/common/gl/lighting.glsl new file mode 100644 index 000000000..3f8867d3b --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/lighting.glsl @@ -0,0 +1,115 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// These are the uniforms used by most lighting shaders. + +uniform vec3 inLightPos[4]; +uniform vec4 inLightInvRadiusSq; +uniform vec4 inLightColor[4]; +uniform vec4 ambient; +uniform float specularPower; +uniform vec4 specularColor; + + +// This is used to limit the maximum processed +// lights in the compute4Lights down for really +// low end GPUs. +// +// NOTE: If you want to support 10.5.x, this needs to be changed to 2. +#define C4L_MAX_LIGHTS 4 + + +void compute4Lights( vec3 wsView, + vec3 wsPosition, + vec3 wsNormal, + out vec4 outDiffuse, + out vec4 outSpecular ) +{ + #ifdef PHONG_SPECULAR + // (R.V)^c + float reflected = reflect( wsView, wsNormal ); + #endif + + vec4 nDotL = vec4( 0.0 ); + vec4 rDotL = vec4( 0.0 ); + vec4 sqDists = vec4( 0.0 ); + int i; + + for ( i = 0; i < C4L_MAX_LIGHTS; ++i ) + { + vec3 lightVector = inLightPos[i] - wsPosition; + vec3 lightDirection = normalize( lightVector ); + + nDotL[i] = max( dot( lightDirection, wsNormal ), 0.0 ); + + #ifdef PHONG_SPECULAR + rDotL[i] = saturate( dot( lightDirection, reflected ) ); + #else + // (N.H)^c [Blinn-Phong, TGEA style, default] + rDotL[i] = dot( wsNormal, normalize( lightDirection + wsView ) ); + #endif + + sqDists[i] = dot( lightVector, lightVector ); + } + + // Attenuation + vec4 atten = vec4( 1.0 ) - ( sqDists * inLightInvRadiusSq ); + + // Combine the light colors for output. + vec4 diffuse = clamp( nDotL * atten, vec4( 0.0 ), vec4( 1.0 ) ); + outDiffuse = vec4( 0.0 ); + for ( i = 0; i < C4L_MAX_LIGHTS; ++i ) + outDiffuse += vec4( diffuse[i] ) * inLightColor[i]; + + // Output the specular power. + rDotL = max( rDotL, vec4( 0.00001 ) ); + outSpecular = pow( rDotL, vec4( specularPower ) ); +} + + +/// The standard specular calculation. +/// +/// @param toLight Normalized vector representing direction from the pixel +/// being lit, to the light source, in world space. +/// +/// @param normal Normalized surface normal. +/// +/// @param toEye The normalized vector representing direction from the pixel +/// being lit to the camera. +/// +/// @param specPwr The specular exponent. +/// +/// @param specScale A scalar on the specular output used in RGB accumulation. +/// +float calcSpecular( vec3 toLight, vec3 normal, vec3 toEye, float specPwr ) +{ + #ifdef PHONG_SPECULAR + // (R.V)^c + float specVal = dot( normalize( -reflect( toLight, normal ) ), toEye ); + #else + // (N.H)^c [Blinn-Phong, TGEA style, default] + float specVal = dot( normal, normalize( toLight + toEye ) ); + #endif + + // Return the specular factor. + return pow( max( specVal, 0.00001f ), specPwr ); +} diff --git a/Templates/Empty/game/shaders/common/gl/particleCompositeP.glsl b/Templates/Empty/game/shaders/common/gl/particleCompositeP.glsl new file mode 100644 index 000000000..4f2d9b359 --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/particleCompositeP.glsl @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "torque.glsl" + +uniform sampler2D colorSource; +uniform vec4 offscreenTargetParams; + +#ifdef TORQUE_LINEAR_DEPTH +#define REJECT_EDGES +uniform sampler2D edgeSource; +uniform vec4 edgeTargetParams; +#endif + +varying vec4 backbufferPos; +varying vec4 offscreenPos; + +void main() +{ + // Off-screen particle source screenspace position in XY + // Back-buffer screenspace position in ZW + vec4 ssPos = vec4(offscreenPos.xy / offscreenPos.w, backbufferPos.xy / backbufferPos.w); + + vec4 uvScene = ( ssPos + 1.0 ) / 2.0; + uvScene.yw = 1.0 - uvScene.yw; + uvScene.xy = viewportCoordToRenderTarget(uvScene.xy, offscreenTargetParams); + +#ifdef REJECT_EDGES + // Cut out particles along the edges, this will create the stencil mask + uvScene.zw = viewportCoordToRenderTarget(uvScene.zw, edgeTargetParams); + float edge = texture2D( edgeSource, uvScene.zw ).r; + if (-edge < 0.0) + discard; +#endif + + // Sample offscreen target and return + gl_FragColor = texture2D( colorSource, uvScene.xy ); +} diff --git a/Templates/Empty/game/shaders/common/gl/particleCompositeV.glsl b/Templates/Empty/game/shaders/common/gl/particleCompositeV.glsl new file mode 100644 index 000000000..88a9431d1 --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/particleCompositeV.glsl @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +uniform mat4 modelViewProj; +uniform mat4 targetModelViewProj; + +varying vec4 offscreenPos; +varying vec4 backbufferPos; + +void main() +{ + gl_Position = modelViewProj * gl_Vertex; + backbufferPos = gl_Position; + offscreenPos = targetModelViewProj * gl_Vertex; +} + diff --git a/Templates/Empty/game/shaders/common/gl/particlesP.glsl b/Templates/Empty/game/shaders/common/gl/particlesP.glsl new file mode 100644 index 000000000..66a3fee28 --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/particlesP.glsl @@ -0,0 +1,82 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "hlslCompat.glsl" +#include "torque.glsl" + +// With advanced lighting we get soft particles. +#ifdef TORQUE_LINEAR_DEPTH + #define SOFTPARTICLES +#endif + +#define CLIP_Z // TODO: Make this a proper macro + +uniform sampler2D diffuseMap; + +#ifdef SOFTPARTICLES + + #include "shadergen:/autogenConditioners.h" + + uniform float oneOverSoftness; + uniform float oneOverFar; + uniform sampler2D prepassTex; + //uniform vec3 vEye; + uniform vec4 prePassTargetParams; +#endif + +uniform float alphaFactor; +uniform float alphaScale; + +varying vec4 color; +varying vec2 uv0; +varying vec4 pos; + + +void main() +{ + float softBlend = 1.0; + + #ifdef SOFTPARTICLES + float2 tc = pos.xy * vec2(1.0, -1.0 ) / pos.w; + tc = viewportCoordToRenderTarget(saturate( ( tc + 1.0 ) * 0.5 ), prePassTargetParams); + + float sceneDepth = prepassUncondition( prepassTex, tc ).w; + float depth = pos.w * oneOverFar; + float diff = sceneDepth - depth; + #ifdef CLIP_Z + // If drawing offscreen, this acts as the depth test, since we don't line up with the z-buffer + // When drawing high-res, though, we want to be able to take advantage of hi-z + // so this is #ifdef'd out + if (diff < 0.0) + discard; + #endif + softBlend = saturate( diff * oneOverSoftness ); + #endif + + vec4 diffuse = texture2D( diffuseMap, uv0 ); + + // Scale output color by the alpha factor (turn LerpAlpha into pre-multiplied alpha) + vec3 colorScale = ( alphaFactor < 0.0 ? color.rgb * diffuse.rgb : ( alphaFactor > 0.0 ? vec3(color.a * alphaFactor * diffuse.a * softBlend) : vec3(softBlend) ) ); + + gl_FragColor = hdrEncode( vec4(color.rgb * diffuse.rgb * colorScale, softBlend * color.a * diffuse.a * alphaScale) ); +} + diff --git a/Templates/Empty/game/shaders/common/gl/particlesV.glsl b/Templates/Empty/game/shaders/common/gl/particlesV.glsl new file mode 100644 index 000000000..da896431f --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/particlesV.glsl @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +varying vec4 color; +varying vec2 uv0; +varying vec4 pos; + +uniform mat4 modelViewProj; +uniform mat4 fsModelViewProj; + +void main() +{ + gl_Position = modelViewProj * gl_Vertex; + pos = fsModelViewProj * gl_Vertex; + color = gl_Color; + uv0 = gl_MultiTexCoord0.st; +} + diff --git a/Templates/Empty/game/shaders/common/gl/planarReflectBumpP.glsl b/Templates/Empty/game/shaders/common/gl/planarReflectBumpP.glsl new file mode 100644 index 000000000..00413aa3b --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/planarReflectBumpP.glsl @@ -0,0 +1,68 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Data +//----------------------------------------------------------------------------- +uniform sampler2D diffuseMap, refractMap, bumpMap; +uniform vec4 shadeColor; + +varying vec2 TEX0; +varying vec4 TEX1; + +//----------------------------------------------------------------------------- +// Fade edges of axis for texcoord passed in +//----------------------------------------------------------------------------- +float fadeAxis( float val ) +{ + // Fades from 1.0 to 0.0 when less than 0.1 + float fadeLow = clamp( val * 10.0, 0.0, 1.0 ); + + // Fades from 1.0 to 0.0 when greater than 0.9 + float fadeHigh = 1.0 - clamp( (val - 0.9) * 10.0, 0.0, 1.0 ); + + return fadeLow * fadeHigh; +} + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + vec3 bumpNorm = texture2D( bumpMap, TEX0 ).rgb * 2.0 - 1.0; + vec2 offset = vec2( bumpNorm.x, bumpNorm.y ); + vec4 texIndex = TEX1; + + // The fadeVal is used to "fade" the distortion at the edges of the screen. + // This is done so it won't sample the reflection texture out-of-bounds and create artifacts + // Note - this can be done more efficiently with a texture lookup + float fadeVal = fadeAxis( texIndex.x / texIndex.w ) * fadeAxis( texIndex.y / texIndex.w ); + + const float distortion = 0.2; + texIndex.xy += offset * distortion * fadeVal; + + vec4 diffuseColor = texture2D( diffuseMap, TEX0 ); + vec4 reflectColor = texture2DProj( refractMap, texIndex ); + + gl_FragColor = diffuseColor + reflectColor * diffuseColor.a; +} diff --git a/Templates/Empty/game/shaders/common/gl/planarReflectBumpV.glsl b/Templates/Empty/game/shaders/common/gl/planarReflectBumpV.glsl new file mode 100644 index 000000000..820bdf698 --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/planarReflectBumpV.glsl @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Data +//----------------------------------------------------------------------------- +uniform mat4 modelview; + +varying vec2 TEX0; +varying vec4 TEX1; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + mat4 texGenTest = mat4(0.5, 0.0, 0.0, 0.0, + 0.0, -0.5, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.5, 0.5, 0.0, 1.0); + + gl_Position = modelview * gl_Vertex; + + TEX0 = gl_MultiTexCoord0.st; + + TEX1 = texGenTest * gl_Position; + TEX1.y = -TEX1.y; + +} diff --git a/Templates/Empty/game/shaders/common/gl/planarReflectP.glsl b/Templates/Empty/game/shaders/common/gl/planarReflectP.glsl new file mode 100644 index 000000000..b4f4fab39 --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/planarReflectP.glsl @@ -0,0 +1,41 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Data +//----------------------------------------------------------------------------- +uniform sampler2D diffuseMap, refractMap; +uniform vec4 shadeColor; + +varying vec2 TEX0; +varying vec4 TEX1; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + vec4 diffuseColor = texture2D( diffuseMap, TEX0 ); + vec4 reflectColor = texture2DProj( refractMap, TEX1 ); + + gl_FragColor = diffuseColor + reflectColor * diffuseColor.a; +} diff --git a/Templates/Empty/game/shaders/common/gl/planarReflectV.glsl b/Templates/Empty/game/shaders/common/gl/planarReflectV.glsl new file mode 100644 index 000000000..820bdf698 --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/planarReflectV.glsl @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Data +//----------------------------------------------------------------------------- +uniform mat4 modelview; + +varying vec2 TEX0; +varying vec4 TEX1; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + mat4 texGenTest = mat4(0.5, 0.0, 0.0, 0.0, + 0.0, -0.5, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.5, 0.5, 0.0, 1.0); + + gl_Position = modelview * gl_Vertex; + + TEX0 = gl_MultiTexCoord0.st; + + TEX1 = texGenTest * gl_Position; + TEX1.y = -TEX1.y; + +} diff --git a/Templates/Empty/game/shaders/common/gl/precipP.glsl b/Templates/Empty/game/shaders/common/gl/precipP.glsl new file mode 100644 index 000000000..a04f16e4b --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/precipP.glsl @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Data +//----------------------------------------------------------------------------- +uniform sampler2D diffuseMap; + +varying vec4 color; +varying vec2 texCoord; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + gl_FragColor = texture2D(diffuseMap, texCoord) * color; +} diff --git a/Templates/Empty/game/shaders/common/gl/precipV.glsl b/Templates/Empty/game/shaders/common/gl/precipV.glsl new file mode 100644 index 000000000..3535f2f38 --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/precipV.glsl @@ -0,0 +1,50 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Data +//----------------------------------------------------------------------------- +uniform mat4 modelview; +uniform vec3 cameraPos, ambient; +uniform vec2 fadeStartEnd; + +varying vec4 color; +varying vec2 texCoord; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + gl_Position = modelview * gl_Vertex; + texCoord = gl_MultiTexCoord0.st; + color = vec4( ambient.r, ambient.g, ambient.b, 1.0 ); + + // Do we need to do a distance fade? + if ( fadeStartEnd.x < fadeStartEnd.y ) + { + + float distance = length( cameraPos - gl_Vertex.xyz ); + color.a = abs( clamp( ( distance - fadeStartEnd.x ) / ( fadeStartEnd.y - fadeStartEnd.x ), 0.0, 1.0 ) - 1.0 ); + } +} + diff --git a/Templates/Empty/game/shaders/common/gl/projectedShadowP.glsl b/Templates/Empty/game/shaders/common/gl/projectedShadowP.glsl new file mode 100644 index 000000000..1dc963a4f --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/projectedShadowP.glsl @@ -0,0 +1,46 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +varying vec2 texCoord; +varying vec4 color; +varying float fade; + +uniform sampler2D inputTex; +uniform vec4 ambient; + + +void main() +{ + vec3 LUMINANCE_VECTOR = vec3(0.2125f, 0.4154f, 0.1721f); + float esmFactor = 200.0; + + float lum = dot( ambient.rgb, LUMINANCE_VECTOR ); + + gl_FragColor.rgb = ambient.rgb * lum; + gl_FragColor.a = 0.0; + float depth = texture2D(inputTex, texCoord).a; + + depth = depth * exp(depth - 10.0); + depth = exp(esmFactor * depth) - 1.0; + + gl_FragColor.a = clamp(depth * 300.0, 0.0, 1.0) * (1.0 - lum) * fade * color.a; +} diff --git a/Templates/Empty/game/shaders/common/gl/projectedShadowV.glsl b/Templates/Empty/game/shaders/common/gl/projectedShadowV.glsl new file mode 100644 index 000000000..c8abde742 --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/projectedShadowV.glsl @@ -0,0 +1,44 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//***************************************************************************** +// Precipitation vertex shader +//***************************************************************************** + +varying vec2 texCoord; +varying vec4 color; +varying float fade; + +uniform mat4 modelview; +uniform float shadowLength; +uniform vec3 shadowCasterPosition; + +void main() +{ + gl_Position = modelview * vec4(gl_Vertex.xyz, 1.0); + + color = gl_Color; + texCoord = gl_MultiTexCoord1.st; + + float fromCasterDist = length(gl_Vertex.xyz - shadowCasterPosition) - shadowLength; + fade = 1.0 - clamp(fromCasterDist/shadowLength, 0.0, 1.0); +} diff --git a/Templates/Empty/game/shaders/common/gl/scatterSkyP.glsl b/Templates/Empty/game/shaders/common/gl/scatterSkyP.glsl new file mode 100644 index 000000000..6a6b9b97c --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/scatterSkyP.glsl @@ -0,0 +1,79 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "torque.glsl" + +// Calculates the Mie phase function +float getMiePhase(float fCos, float fCos2, float g, float g2) +{ + return 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos2) / pow(abs(1.0 + g2 - 2.0*g*fCos), 1.5); +} + +// Calculates the Rayleigh phase function +float getRayleighPhase(float fCos2) +{ + //return 1.0; + return 0.75 + 0.75*fCos2; +} + +varying vec4 rayleighColor; +varying vec4 mieColor; +varying vec3 v3Direction; +varying float zPosition; +varying vec3 pos; + +uniform samplerCube nightSky; +uniform vec4 nightColor; +uniform vec2 nightInterpAndExposure; +uniform float useCubemap; +uniform vec3 lightDir; +uniform vec3 sunDir; + +void main() +{ + float fCos = dot( lightDir, v3Direction ) / length(v3Direction); + float fCos2 = fCos*fCos; + + float g = -0.991; + float g2 = -0.991 * -0.991; + + float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos2) / pow(abs(1.0 + g2 - 2.0*g*fCos), 1.5); + + vec4 color = rayleighColor + fMiePhase * mieColor; + color.a = color.b; + + vec4 nightSkyColor = textureCube(nightSky, -v3Direction); + nightSkyColor = mix(nightColor, nightSkyColor, useCubemap); + + float fac = dot( normalize( pos ), sunDir ); + fac = max( nightInterpAndExposure.y, pow( clamp( fac, 0.0, 1.0 ), 2 ) ); + gl_FragColor = mix( color, nightSkyColor, nightInterpAndExposure.y ); + + // Clip based on the camera-relative + // z position of the vertex, passed through + // from the vertex position. + if(zPosition < 0.0) + discard; + + gl_FragColor.a = 1; + gl_FragColor = hdrEncode( gl_FragColor ); +} diff --git a/Templates/Empty/game/shaders/common/gl/scatterSkyV.glsl b/Templates/Empty/game/shaders/common/gl/scatterSkyV.glsl new file mode 100644 index 000000000..53abd5a6b --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/scatterSkyV.glsl @@ -0,0 +1,165 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +const int nSamples = 4; +const float fSamples = 4.0; + +// The scale depth (the altitude at which the average atmospheric density is found) +const float fScaleDepth = 0.25; +const float fInvScaleDepth = 1.0 / 0.25; + +// The scale equation calculated by Vernier's Graphical Analysis +float vernierScale(float fCos) +{ + float x = 1.0 - fCos; + float x5 = x * 5.25; + float x5p6 = (-6.80 + x5); + float xnew = (3.83 + x * x5p6); + float xfinal = (0.459 + x * xnew); + float xfinal2 = -0.00287 + x * xfinal; + float outx = exp( xfinal2 ); + return 0.25 * outx; +} + +// This is the shader output data. +varying vec4 rayleighColor; +varying vec4 mieColor; +varying vec3 v3Direction; +varying float zPosition; +varying vec3 pos; + +uniform mat4 modelView; +uniform vec4 misc; +uniform vec4 sphereRadii; +uniform vec4 scatteringCoeffs; +uniform vec3 camPos; +uniform vec3 lightDir; +uniform vec4 invWaveLength; + +void main() +{ + vec4 position = gl_Vertex.xyzw; + vec3 normal = gl_Normal.xyz; + vec4 color = gl_MultiTexCoord0.xyzw; + + // Pull some variables out: + float camHeight = misc.x; + float camHeightSqr = misc.y; + + float scale = misc.z; + float scaleOverScaleDepth = misc.w; + + float outerRadius = sphereRadii.x; + float outerRadiusSqr = sphereRadii.y; + + float innerRadius = sphereRadii.z; + float innerRadiusSqr = sphereRadii.w; + + float rayleighBrightness = scatteringCoeffs.x; // Kr * ESun + float rayleigh4PI = scatteringCoeffs.y; // Kr * 4 * PI + + float mieBrightness = scatteringCoeffs.z; // Km * ESun + float mie4PI = scatteringCoeffs.w; // Km * 4 * PI + + // Get the ray from the camera to the vertex, + // and its length (which is the far point of the ray + // passing through the atmosphere). + vec3 v3Pos = position.xyz / 6378000.0;// / outerRadius; + vec3 newCamPos = vec3( 0, 0, camHeight ); + v3Pos.z += innerRadius; + vec3 v3Ray = v3Pos.xyz - newCamPos; + float fFar = length(v3Ray); + v3Ray /= fFar; + + // Calculate the ray's starting position, + // then calculate its scattering offset. + vec3 v3Start = newCamPos; + float fHeight = length(v3Start); + float fDepth = exp(scaleOverScaleDepth * (innerRadius - camHeight)); + float fStartAngle = dot(v3Ray, v3Start) / fHeight; + + float x = 1.0 - fStartAngle; + float x5 = x * 5.25; + float x5p6 = (-6.80 + x5); + float xnew = (3.83 + x * x5p6); + float xfinal = (0.459 + x * xnew); + float xfinal2 = -0.00287 + x * xfinal; + float othx = exp( xfinal2 ); + float vscale1 = 0.25 * othx; + + float fStartOffset = fDepth * vscale1;//vernierScale(fStartAngle); + + // Initialize the scattering loop variables. + float fSampleLength = fFar / 2.0; + float fScaledLength = fSampleLength * scale; + vec3 v3SampleRay = v3Ray * fSampleLength; + vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5; + + // Now loop through the sample rays + vec3 v3FrontColor = vec3(0.0, 0.0, 0.0); + for(int i=0; i<2; i++) + { + float fHeight = length(v3SamplePoint); + float fDepth = exp(scaleOverScaleDepth * (innerRadius - fHeight)); + float fLightAngle = dot(lightDir, v3SamplePoint) / fHeight; + float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight; + + x = 1.0 - fCameraAngle; + x5 = x * 5.25; + x5p6 = (-6.80 + x5); + xnew = (3.83 + x * x5p6); + xfinal = (0.459 + x * xnew); + xfinal2 = -0.00287 + x * xfinal; + othx = exp( xfinal2 ); + float vscale3 = 0.25 * othx; + + + x = 1.0 - fLightAngle; + x5 = x * 5.25; + x5p6 = (-6.80 + x5); + xnew = (3.83 + x * x5p6); + xfinal = (0.459 + x * xnew); + xfinal2 = -0.00287 + x * xfinal; + othx = exp( xfinal2 ); + float vscale2 = 0.25 * othx; + + float fScatter = (fStartOffset + fDepth*(vscale2 - vscale3)); + vec3 v3Attenuate = exp(-fScatter * (invWaveLength.xyz * rayleigh4PI + mie4PI)); + v3FrontColor += v3Attenuate * (fDepth * fScaledLength); + v3SamplePoint += v3SampleRay; + } + + // Finally, scale the Mie and Rayleigh colors + // and set up the varying variables for the pixel shader. + gl_Position = modelView * position; + mieColor.rgb = v3FrontColor * mieBrightness; + mieColor.a = 1.0; + rayleighColor.rgb = v3FrontColor * (invWaveLength.xyz * rayleighBrightness); + rayleighColor.a = 1.0; + v3Direction = newCamPos - v3Pos.xyz; + + // This offset is to get rid of the black line between the atmosky and the waterPlane + // along the horizon. + zPosition = position.z + 4000.0; + pos = position.xyz; +} + diff --git a/Templates/Empty/game/shaders/common/gl/torque.glsl b/Templates/Empty/game/shaders/common/gl/torque.glsl new file mode 100644 index 000000000..dc73a706f --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/torque.glsl @@ -0,0 +1,246 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#ifndef _TORQUE_GLSL_ +#define _TORQUE_GLSL_ + + +float M_HALFPI_F = 1.57079632679489661923; +float M_PI_F = 3.14159265358979323846; +float M_2PI_F = 6.28318530717958647692; + +/// Calculate fog based on a start and end positions in worldSpace. +float computeSceneFog( vec3 startPos, + vec3 endPos, + float fogDensity, + float fogDensityOffset, + float fogHeightFalloff ) +{ + float f = length( startPos - endPos ) - fogDensityOffset; + float h = 1.0 - ( endPos.z * fogHeightFalloff ); + return exp( -fogDensity * f * h ); +} + + +/// Calculate fog based on a start and end position and a height. +/// Positions do not need to be in worldSpace but height does. +float computeSceneFog( vec3 startPos, + vec3 endPos, + float height, + float fogDensity, + float fogDensityOffset, + float fogHeightFalloff ) +{ + float f = length( startPos - endPos ) - fogDensityOffset; + float h = 1.0 - ( height * fogHeightFalloff ); + return exp( -fogDensity * f * h ); +} + + +/// Calculate fog based on a distance, height is not used. +float computeSceneFog( float dist, float fogDensity, float fogDensityOffset ) +{ + float f = dist - fogDensityOffset; + return exp( -fogDensity * f ); +} + + +/// Convert a vec4 uv in viewport space to render target space. +vec2 viewportCoordToRenderTarget( vec4 inCoord, vec4 rtParams ) +{ + vec2 outCoord = inCoord.xy / inCoord.w; + outCoord = ( outCoord * rtParams.zw ) + rtParams.xy; + return outCoord; +} + + +/// Convert a vec2 uv in viewport space to render target space. +vec2 viewportCoordToRenderTarget( vec2 inCoord, vec4 rtParams ) +{ + vec2 outCoord = ( inCoord * rtParams.zw ) + rtParams.xy; + return outCoord; +} + + +/// Convert a vec4 quaternion into a 3x3 matrix. +mat3x3 quatToMat( vec4 quat ) +{ + float xs = quat.x * 2.0; + float ys = quat.y * 2.0; + float zs = quat.z * 2.0; + + float wx = quat.w * xs; + float wy = quat.w * ys; + float wz = quat.w * zs; + + float xx = quat.x * xs; + float xy = quat.x * ys; + float xz = quat.x * zs; + + float yy = quat.y * ys; + float yz = quat.y * zs; + float zz = quat.z * zs; + + mat3x3 mat; + + mat[0][0] = 1.0 - (yy + zz); + mat[1][0] = xy - wz; + mat[2][0] = xz + wy; + + mat[0][1] = xy + wz; + mat[1][1] = 1.0 - (xx + zz); + mat[2][1] = yz - wx; + + mat[0][2] = xz - wy; + mat[1][2] = yz + wx; + mat[2][2] = 1.0 - (xx + yy); + + return mat; +} + +/// The number of additional substeps we take when refining +/// the results of the offset parallax mapping function below. +/// +/// You should turn down the number of steps if your needing +/// more performance out of your parallax surfaces. Increasing +/// the number doesn't yeild much better results and is rarely +/// worth the additional cost. +/// +#define PARALLAX_REFINE_STEPS 3 + +/// Performs fast parallax offset mapping using +/// multiple refinement steps. +////// @param texMap The texture map whos alpha channel we sample the parallax depth. +/// @param texCoord The incoming texture coordinate for sampling the parallax depth. +/// @param negViewTS The negative view vector in tangent space. +/// @param depthScale The parallax factor used to scale the depth result. +/// +vec2 parallaxOffset( sampler2D texMap, vec2 texCoord, vec3 negViewTS, float depthScale ) +{ + float depth = texture2D( texMap, texCoord ).a; + vec2 offset = negViewTS.xy * ( depth * depthScale ); + + for ( int i=0; i < PARALLAX_REFINE_STEPS; i++ ) + { + depth = ( depth + texture2D( texMap, texCoord + offset ).a ) * 0.5; + offset = negViewTS.xy * ( depth * depthScale ); + } + + return offset; +} + + +/// The maximum value for 16bit per component integer HDR encoding. +const float HDR_RGB16_MAX = 100.0; +/// The maximum value for 10bit per component integer HDR encoding.const float HDR_RGB10_MAX = 4.0; + +/// Encodes an HDR color for storage into a target. +vec3 hdrEncode( vec3 sample ){ + #if defined( TORQUE_HDR_RGB16 ) + + return sample / HDR_RGB16_MAX; + + #elif defined( TORQUE_HDR_RGB10 ) + + return sample / HDR_RGB10_MAX; + + #else + + // No encoding. + return sample; + + #endif +} + +/// Encodes an HDR color for storage into a target. +vec4 hdrEncode( vec4 sample ) +{ + return vec4( hdrEncode( sample.rgb ), sample.a ); +} + +/// Decodes an HDR color from a target. +vec3 hdrDecode( vec3 sample ) +{ + #if defined( TORQUE_HDR_RGB16 ) + + return sample * HDR_RGB16_MAX; + + #elif defined( TORQUE_HDR_RGB10 ) + + return sample * HDR_RGB10_MAX; + + #else + + // No encoding. + return sample; + + #endif +} + +/// Decodes an HDR color from a target. +vec4 hdrDecode( vec4 sample ) +{ + return vec4( hdrDecode( sample.rgb ), sample.a ); +} + +/// Returns the luminance for an HDR pixel. +float hdrLuminance( vec3 sample ) +{ + // There are quite a few different ways to + // calculate luminance from an rgb value. + // + // If you want to use a different technique + // then plug it in here. + // + + //////////////////////////////////////////////////////////////////////////// + // + // Max component luminance. + // + //float lum = max( sample.r, max( sample.g, sample.b ) ); + + //////////////////////////////////////////////////////////////////////////// + // The perceptual relative luminance. + // + // See http://en.wikipedia.org/wiki/Luminance_(relative) + // + const vec3 RELATIVE_LUMINANCE = vec3( 0.2126, 0.7152, 0.0722 ); + float lum = dot( sample, RELATIVE_LUMINANCE ); + + //////////////////////////////////////////////////////////////////////////// + // + // The average component luminance. + // + //const vec3 AVERAGE_LUMINANCE = vec3( 0.3333, 0.3333, 0.3333 ); + //float lum = dot( sample, AVERAGE_LUMINANCE ); + + return lum; +} + + +/// Basic assert macro. If the condition fails, then the shader will output color. +/// @param condition This should be a bvec[2-4]. If any items is false, condition is considered to fail. +/// @param color The color that should be outputted if the condition fails. +/// @note This macro will only work in the void main() method of a pixel shader. +#define assert(condition, color) { if(!any(condition)) { gl_FragColor = color; return; } } + +#endif // _TORQUE_GLSL_ diff --git a/Templates/Empty/game/shaders/common/gl/wavesP.glsl b/Templates/Empty/game/shaders/common/gl/wavesP.glsl new file mode 100644 index 000000000..24bd8cbb4 --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/wavesP.glsl @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +uniform sampler2D diffMap; +uniform sampler2D bumpMap; +uniform samplerCube cubeMap; +uniform vec4 specularColor; +uniform float specularPower; +uniform vec4 ambient; +uniform float accumTime; + +varying vec2 TEX0; +varying vec4 outLightVec; +varying vec3 outPos; +varying vec3 outEyePos; + +void main() +{ + vec2 texOffset; + float sinOffset1 = sin( accumTime * 1.5 + TEX0.y * 6.28319 * 3.0 ) * 0.03; + float sinOffset2 = sin( accumTime * 3.0 + TEX0.y * 6.28319 ) * 0.04; + + texOffset.x = TEX0.x + sinOffset1 + sinOffset2; + texOffset.y = TEX0.y + cos( accumTime * 3.0 + TEX0.x * 6.28319 * 2.0 ) * 0.05; + + vec4 bumpNorm = texture2D(bumpMap, texOffset) * 2.0 - 1.0; + vec4 diffuse = texture2D(diffMap, texOffset); + + gl_FragColor = diffuse * (clamp(dot(outLightVec.xyz, bumpNorm.xyz), 0.0, 1.0) + ambient); + + vec3 eyeVec = normalize(outEyePos - outPos); + vec3 halfAng = normalize(eyeVec + outLightVec.xyz); + float specular = clamp(dot(bumpNorm.xyz, halfAng), 0.0, 1.0) * outLightVec.w; + specular = pow(specular, specularPower); + gl_FragColor += specularColor * specular; +} diff --git a/Templates/Empty/game/shaders/common/gl/wind.glsl b/Templates/Empty/game/shaders/common/gl/wind.glsl new file mode 100644 index 000000000..0ddb492b9 --- /dev/null +++ b/Templates/Empty/game/shaders/common/gl/wind.glsl @@ -0,0 +1,101 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// +// A tip of the hat.... +// +// The following wind effects were derived from the GPU Gems +// 3 chapter "Vegetation Procedural Animation and Shading in Crysis" +// by Tiago Sousa of Crytek. +// + +vec4 smoothCurve( vec4 x ) +{ + return x * x * ( 3.0 - 2.0 * x ); +} + +vec4 triangleWave( vec4 x ) +{ + return abs( fract( x + 0.5 ) * 2.0 - 1.0 ); +} + +vec4 smoothTriangleWave( vec4 x ) +{ + return smoothCurve( triangleWave( x ) ); +} + +vec3 windTrunkBending( vec3 vPos, vec2 vWind, float fBendFactor ) +{ + // Smooth the bending factor and increase + // the near by height limit. + fBendFactor += 1.0; + fBendFactor *= fBendFactor; + fBendFactor = fBendFactor * fBendFactor - fBendFactor; + + // Displace the vert. + vec3 vNewPos = vPos; + vNewPos.xy += vWind * fBendFactor; + + // Limit the length which makes the bend more + // spherical and prevents stretching. + float fLength = length( vPos ); + vPos = normalize( vNewPos ) * fLength; + + return vPos; +} + +vec3 windBranchBending( vec3 vPos, + vec3 vNormal, + + float fTime, + float fWindSpeed, + + float fBranchPhase, + float fBranchAmp, + float fBranchAtten, + + float fDetailPhase, + float fDetailAmp, + float fDetailFreq, + + float fEdgeAtten ) +{ + float fVertPhase = dot( vPos, vec3( fDetailPhase + fBranchPhase ) ); + + vec2 vWavesIn = fTime + vec2( fVertPhase, fBranchPhase ); + + vec4 vWaves = ( fract( vWavesIn.xxyy * + vec4( 1.975, 0.793, 0.375, 0.193 ) ) * + 2.0 - 1.0 ) * fWindSpeed * fDetailFreq; + + vWaves = smoothTriangleWave( vWaves ); + + vec2 vWavesSum = vWaves.xz + vWaves.yw; + + // We want the branches to bend both up and down. + vWavesSum.y = 1.0 - ( vWavesSum.y * 2.0 ); + + vPos += vWavesSum.xxy * vec3( fEdgeAtten * fDetailAmp * vNormal.xy, + fBranchAtten * fBranchAmp ); + + return vPos; +} diff --git a/Templates/Empty/game/shaders/common/guiMaterialV.hlsl b/Templates/Empty/game/shaders/common/guiMaterialV.hlsl new file mode 100644 index 000000000..425da5da4 --- /dev/null +++ b/Templates/Empty/game/shaders/common/guiMaterialV.hlsl @@ -0,0 +1,43 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "hlslStructs.h" + +struct MaterialDecoratorConnectV +{ + float4 hpos : POSITION; + float2 uv0 : TEXCOORD0; +}; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +MaterialDecoratorConnectV main( VertexIn_PCT IN, + uniform float4x4 modelview : register(C0) ) +{ + MaterialDecoratorConnectV OUT; + + OUT.hpos = mul(modelview, IN.pos); + OUT.uv0 = IN.uv0; + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/hlslStructs.h b/Templates/Empty/game/shaders/common/hlslStructs.h new file mode 100644 index 000000000..7d66a0481 --- /dev/null +++ b/Templates/Empty/game/shaders/common/hlslStructs.h @@ -0,0 +1,108 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// The purpose of this file is to get all of our HLSL structures into one place. +// Please use the structures here instead of redefining input and output structures +// in each shader file. If structures are added, please adhere to the naming convention. + +//------------------------------------------------------------------------------ +// Vertex Input Structures +// +// These structures map to FVFs/Vertex Declarations in Torque. See gfxStructs.h +//------------------------------------------------------------------------------ + +// Notes +// +// Position should be specified as a float4. Right now our vertex structures in +// the engine output float3s for position. This does NOT mean that the POSITION +// binding should be float3, because it will assign 0 to the w coordinate, which +// results in the vertex not getting translated when it is transformed. + +struct VertexIn_P +{ + float4 pos : POSITION; +}; + +struct VertexIn_PT +{ + float4 pos : POSITION; + float2 uv0 : TEXCOORD0; +}; + +struct VertexIn_PTTT +{ + float4 pos : POSITION; + float2 uv0 : TEXCOORD0; + float2 uv1 : TEXCOORD1; + float2 uv2 : TEXCOORD2; +}; + +struct VertexIn_PC +{ + float4 pos : POSITION; + float4 color : DIFFUSE; +}; + +struct VertexIn_PNC +{ + float4 pos : POSITION; + float3 normal : NORMAL; + float4 color : DIFFUSE; +}; + +struct VertexIn_PCT +{ + float4 pos : POSITION; + float4 color : DIFFUSE; + float2 uv0 : TEXCOORD0; +}; + +struct VertexIn_PN +{ + float4 pos : POSITION; + float3 normal : NORMAL; +}; + +struct VertexIn_PNT +{ + float4 pos : POSITION; + float3 normal : NORMAL; + float2 uv0 : TEXCOORD0; +}; + +struct VertexIn_PNCT +{ + float4 pos : POSITION; + float3 normal : NORMAL; + float4 color : DIFFUSE; + float2 uv0 : TEXCOORD0; +}; + +struct VertexIn_PNTTTB +{ + float4 pos : POSITION; + float3 normal : NORMAL; + float2 uv0 : TEXCOORD0; + float2 uv1 : TEXCOORD1; + float3 T : TEXCOORD2; + float3 B : TEXCOORD3; +}; \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/imposter.hlsl b/Templates/Empty/game/shaders/common/imposter.hlsl new file mode 100644 index 000000000..bc700ba03 --- /dev/null +++ b/Templates/Empty/game/shaders/common/imposter.hlsl @@ -0,0 +1,149 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "torque.hlsl" + + +static float sCornerRight[4] = { -1, 1, 1, -1 }; +static float sCornerUp[4] = { -1, -1, 1, 1 }; +static float2 sUVCornerExtent[4] = +{ + float2( 0, 1 ), + float2( 1, 1 ), + float2( 1, 0 ), + float2( 0, 0 ) +}; + +#define IMPOSTER_MAX_UVS 64 + + +void imposter_v( + // These parameters usually come from the vertex. + float3 center, + int corner, + float halfSize, + float3 imposterUp, + float3 imposterRight, + + // These are from the imposter shader constant. + int numEquatorSteps, + int numPolarSteps, + float polarAngle, + bool includePoles, + + // Other shader constants. + float3 camPos, + float4 uvs[IMPOSTER_MAX_UVS], + + // The outputs of this function. + out float3 outWsPosition, + out float2 outTexCoord, + out float3x3 outWorldToTangent + ) +{ + // TODO: This could all be calculated on the CPU. + float equatorStepSize = M_2PI_F / numEquatorSteps; + float equatorHalfStep = ( equatorStepSize / 2.0 ) - 0.0001; + float polarStepSize = M_PI_F / numPolarSteps; + float polarHalfStep = ( polarStepSize / 2.0 ) - 0.0001; + + // The vector between the camera and the billboard. + float3 lookVec = normalize( camPos - center ); + + // Generate the camera up and right vectors from + // the object transform and camera forward. + float3 camUp = imposterUp; + float3 camRight = normalize( cross( -lookVec, camUp ) ); + + // The billboarding is based on the camera directions. + float3 rightVec = camRight * sCornerRight[corner]; + float3 upVec = camUp * sCornerUp[corner]; + + float lookPitch = acos( dot( imposterUp, lookVec ) ); + + // First check to see if we need to render the top billboard. + int index; + /* + if ( includePoles && ( lookPitch < polarAngle || lookPitch > sPi - polarAngle ) ) + { + index = numEquatorSteps * 3; + + // When we render the top/bottom billboard we always use + // a fixed vector that matches the rotation of the object. + rightVec = float3( 1, 0, 0 ) * sCornerRight[corner]; + upVec = float3( 0, 1, 0 ) * sCornerUp[corner]; + + if ( lookPitch > sPi - polarAngle ) + { + upVec = -upVec; + index++; + } + } + else + */ + { + // Calculate the rotation around the z axis then add the + // equator half step. This gets the images to switch a + // half step before the captured angle is met. + float lookAzimuth = atan2( lookVec.y, lookVec.x ); + float azimuth = atan2( imposterRight.y, imposterRight.x ); + float rotZ = ( lookAzimuth - azimuth ) + equatorHalfStep; + + // The y rotation is calculated from the look vector and + // the object up vector. + float rotY = lookPitch - polarHalfStep; + + // TODO: How can we do this without conditionals? + // Normalize the result to 0 to 2PI. + if ( rotZ < 0 ) + rotZ += M_2PI_F; + if ( rotZ > M_2PI_F ) + rotZ -= M_2PI_F; + if ( rotY < 0 ) + rotY += M_2PI_F; + if ( rotY > M_PI_F ) // Not M_2PI_F? + rotY -= M_2PI_F; + + float polarIdx = round( abs( rotY ) / polarStepSize ); + + // Get the index to the start of the right polar + // images for this viewing angle. + int numPolarOffset = numEquatorSteps * polarIdx; + + // Calculate the final image index for lookup + // of the texture coords. + index = ( rotZ / equatorStepSize ) + numPolarOffset; + } + + // Generate the final world space position. + outWsPosition = center + ( upVec * halfSize ) + ( rightVec * halfSize ); + + // Grab the uv set and setup the texture coord. + float4 uvSet = uvs[index]; + outTexCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x ); + outTexCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y ); + + // Needed for normal mapping and lighting. + outWorldToTangent[0] = float3( 1, 0, 0 ); + outWorldToTangent[1] = float3( 0, 1, 0 ); + outWorldToTangent[2] = float3( 0, 0, -1 ); +} diff --git a/Templates/Empty/game/shaders/common/lighting.hlsl b/Templates/Empty/game/shaders/common/lighting.hlsl new file mode 100644 index 000000000..fc8470b7d --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting.hlsl @@ -0,0 +1,219 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +#ifndef TORQUE_SHADERGEN + +// These are the uniforms used by most lighting shaders. + +uniform float4 inLightPos[3]; +uniform float4 inLightInvRadiusSq; +uniform float4 inLightColor[4]; + +#ifndef TORQUE_BL_NOSPOTLIGHT + uniform float4 inLightSpotDir[3]; + uniform float4 inLightSpotAngle; + uniform float4 inLightSpotFalloff; +#endif + +uniform float4 ambient; +uniform float specularPower; +uniform float4 specularColor; + +#endif // !TORQUE_SHADERGEN + + +void compute4Lights( float3 wsView, + float3 wsPosition, + float3 wsNormal, + float4 shadowMask, + + #ifdef TORQUE_SHADERGEN + + float4 inLightPos[3], + float4 inLightInvRadiusSq, + float4 inLightColor[4], + float4 inLightSpotDir[3], + float4 inLightSpotAngle, + float4 inLightSpotFalloff, + float specularPower, + float4 specularColor, + + #endif // TORQUE_SHADERGEN + + out float4 outDiffuse, + out float4 outSpecular ) +{ + // NOTE: The light positions and spotlight directions + // are stored in SoA order, so inLightPos[0] is the + // x coord for all 4 lights... inLightPos[1] is y... etc. + // + // This is the key to fully utilizing the vector units and + // saving a huge amount of instructions. + // + // For example this change saved more than 10 instructions + // over a simple for loop for each light. + + int i; + + float4 lightVectors[3]; + for ( i = 0; i < 3; i++ ) + lightVectors[i] = wsPosition[i] - inLightPos[i]; + + float4 squareDists = 0; + for ( i = 0; i < 3; i++ ) + squareDists += lightVectors[i] * lightVectors[i]; + + // Accumulate the dot product between the light + // vector and the normal. + // + // The normal is negated because it faces away from + // the surface and the light faces towards the + // surface... this keeps us from needing to flip + // the light vector direction which complicates + // the spot light calculations. + // + // We normalize the result a little later. + // + float4 nDotL = 0; + for ( i = 0; i < 3; i++ ) + nDotL += lightVectors[i] * -wsNormal[i]; + + float4 rDotL = 0; + #ifndef TORQUE_BL_NOSPECULAR + + // We're using the Phong specular reflection model + // here where traditionally Torque has used Blinn-Phong + // which has proven to be more accurate to real materials. + // + // We do so because its cheaper as do not need to + // calculate the half angle for all 4 lights. + // + // Advanced Lighting still uses Blinn-Phong, but the + // specular reconstruction it does looks fairly similar + // to this. + // + float3 R = reflect( wsView, -wsNormal ); + + for ( i = 0; i < 3; i++ ) + rDotL += lightVectors[i] * R[i]; + + #endif + + // Normalize the dots. + // + // Notice we're using the half type here to get a + // much faster sqrt via the rsq_pp instruction at + // the loss of some precision. + // + // Unless we have some extremely large point lights + // i don't believe the precision loss will matter. + // + half4 correction = (half4)rsqrt( squareDists ); + nDotL = saturate( nDotL * correction ); + rDotL = clamp( rDotL * correction, 0.00001, 1.0 ); + + // First calculate a simple point light linear + // attenuation factor. + // + // If this is a directional light the inverse + // radius should be greater than the distance + // causing the attenuation to have no affect. + // + float4 atten = saturate( 1.0 - ( squareDists * inLightInvRadiusSq ) ); + + #ifndef TORQUE_BL_NOSPOTLIGHT + + // The spotlight attenuation factor. This is really + // fast for what it does... 6 instructions for 4 spots. + + float4 spotAtten = 0; + for ( i = 0; i < 3; i++ ) + spotAtten += lightVectors[i] * inLightSpotDir[i]; + + float4 cosAngle = ( spotAtten * correction ) - inLightSpotAngle; + atten *= saturate( cosAngle * inLightSpotFalloff ); + + #endif + + // Finally apply the shadow masking on the attenuation. + atten *= shadowMask; + + // Get the final light intensity. + float4 intensity = nDotL * atten; + + // Combine the light colors for output. + outDiffuse = 0; + for ( i = 0; i < 4; i++ ) + outDiffuse += intensity[i] * inLightColor[i]; + + // Output the specular power. + float4 specularIntensity = pow( rDotL, specularPower.xxxx ) * atten; + + // Apply the per-light specular attenuation. + float4 specular = float4(0,0,0,1); + for ( i = 0; i < 4; i++ ) + specular += float4( inLightColor[i].rgb * inLightColor[i].a * specularIntensity[i], 1 ); + + // Add the final specular intensity values together + // using a single dot product operation then get the + // final specular lighting color. + outSpecular = specularColor * specular; +} + + +// This value is used in AL as a constant power to raise specular values +// to, before storing them into the light info buffer. The per-material +// specular value is then computer by using the integer identity of +// exponentiation: +// +// (a^m)^n = a^(m*n) +// +// or +// +// (specular^constSpecular)^(matSpecular/constSpecular) = specular^(matSpecular*constSpecular) +// +#define AL_ConstantSpecularPower 12.0f + +/// The specular calculation used in Advanced Lighting. +/// +/// @param toLight Normalized vector representing direction from the pixel +/// being lit, to the light source, in world space. +/// +/// @param normal Normalized surface normal. +/// +/// @param toEye The normalized vector representing direction from the pixel +/// being lit to the camera. +/// +float AL_CalcSpecular( float3 toLight, float3 normal, float3 toEye ) +{ + #ifdef PHONG_SPECULAR + // (R.V)^c + float specVal = dot( normalize( -reflect( toLight, normal ) ), toEye ); + #else + // (N.H)^c [Blinn-Phong, TGEA style, default] + float specVal = dot( normal, normalize( toLight + toEye ) ); + #endif + + // Return the specular factor. + return pow( max( specVal, 0.00001f ), AL_ConstantSpecularPower ); +} diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/convexGeometryV.hlsl b/Templates/Empty/game/shaders/common/lighting/advanced/convexGeometryV.hlsl new file mode 100644 index 000000000..c86cd4e89 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/convexGeometryV.hlsl @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "../../hlslStructs.h" + +struct ConvexConnectV +{ + float4 hpos : POSITION; + float4 wsEyeDir : TEXCOORD0; + float4 ssPos : TEXCOORD1; + float4 vsEyeDir : TEXCOORD2; +}; + +ConvexConnectV main( VertexIn_P IN, + uniform float4x4 modelview, + uniform float4x4 objTrans, + uniform float4x4 worldViewOnly, + uniform float3 eyePosWorld ) +{ + ConvexConnectV OUT; + + OUT.hpos = mul( modelview, IN.pos ); + OUT.wsEyeDir = mul( objTrans, IN.pos ) - float4( eyePosWorld, 0.0 ); + OUT.vsEyeDir = mul( worldViewOnly, IN.pos ); + OUT.ssPos = OUT.hpos; + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/dbgDepthVisualizeP.hlsl b/Templates/Empty/game/shaders/common/lighting/advanced/dbgDepthVisualizeP.hlsl new file mode 100644 index 000000000..a2b2b5d7d --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/dbgDepthVisualizeP.hlsl @@ -0,0 +1,33 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" +#include "../../postfx/postFx.hlsl" + + +float4 main( PFXVertToPix IN, + uniform sampler2D prepassTex : register(S0), + uniform sampler1D depthViz : register(S1) ) : COLOR0 +{ + float depth = prepassUncondition( prepassTex, IN.uv0 ).w; + return float4( tex1D( depthViz, depth ).rgb, 1.0 ); +} diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/dbgLightColorVisualizeP.hlsl b/Templates/Empty/game/shaders/common/lighting/advanced/dbgLightColorVisualizeP.hlsl new file mode 100644 index 000000000..487b4c740 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/dbgLightColorVisualizeP.hlsl @@ -0,0 +1,34 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" +#include "../../postfx/postFx.hlsl" + + +float4 main( PFXVertToPix IN, + uniform sampler2D lightPrePassTex : register(S0) ) : COLOR0 +{ + float3 lightcolor; + float nl_Att, specular; + lightinfoUncondition( tex2D( lightPrePassTex, IN.uv0 ), lightcolor, nl_Att, specular ); + return float4( lightcolor, 1.0 ); +} diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/dbgLightSpecularVisualizeP.hlsl b/Templates/Empty/game/shaders/common/lighting/advanced/dbgLightSpecularVisualizeP.hlsl new file mode 100644 index 000000000..edc25ed03 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/dbgLightSpecularVisualizeP.hlsl @@ -0,0 +1,34 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" +#include "../../postfx/postFx.hlsl" + + +float4 main( PFXVertToPix IN, + uniform sampler2D lightPrePassTex : register(S0) ) : COLOR0 +{ + float3 lightcolor; + float nl_Att, specular; + lightinfoUncondition( tex2D( lightPrePassTex, IN.uv0 ), lightcolor, nl_Att, specular ); + return float4( specular, specular, specular, 1.0 ); +} diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/dbgNormalVisualizeP.hlsl b/Templates/Empty/game/shaders/common/lighting/advanced/dbgNormalVisualizeP.hlsl new file mode 100644 index 000000000..c160045b4 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/dbgNormalVisualizeP.hlsl @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" +#include "../../postfx/postFx.hlsl" + + +float4 main( PFXVertToPix IN, + uniform sampler2D prepassTex : register(S0) ) : COLOR0 +{ + float3 normal = prepassUncondition( prepassTex, IN.uv0 ).xyz; + return float4( ( normal + 1.0 ) * 0.5, 1.0 ); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/dbgShadowVisualizeP.hlsl b/Templates/Empty/game/shaders/common/lighting/advanced/dbgShadowVisualizeP.hlsl new file mode 100644 index 000000000..b1f2bca29 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/dbgShadowVisualizeP.hlsl @@ -0,0 +1,34 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +struct MaterialDecoratorConnectV +{ + float2 uv0 : TEXCOORD0; +}; + +float4 main( MaterialDecoratorConnectV IN, + uniform sampler2D shadowMap : register(S0), + uniform sampler1D depthViz : register(S1) ) : COLOR0 +{ + float depth = saturate( tex2D( shadowMap, IN.uv0 ).r ); + return float4( tex1D( depthViz, depth ).rgb, 1 ); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/farFrustumQuad.hlsl b/Templates/Empty/game/shaders/common/lighting/advanced/farFrustumQuad.hlsl new file mode 100644 index 000000000..567dd11ce --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/farFrustumQuad.hlsl @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +struct FarFrustumQuadConnectV +{ + float4 hpos : POSITION; + float2 uv0 : TEXCOORD0; + float3 wsEyeRay : TEXCOORD1; + float3 vsEyeRay : TEXCOORD2; +}; + +struct FarFrustumQuadConnectP +{ + float2 uv0 : TEXCOORD0; + float3 wsEyeRay : TEXCOORD1; + float3 vsEyeRay : TEXCOORD2; +}; + + +float2 getUVFromSSPos( float3 ssPos, float4 rtParams ) +{ + float2 outPos = ( ssPos.xy + 1.0 ) / 2.0; + outPos.y = 1.0 - outPos.y; + outPos = ( outPos * rtParams.zw ) + rtParams.xy; + return outPos; +} diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/farFrustumQuadV.hlsl b/Templates/Empty/game/shaders/common/lighting/advanced/farFrustumQuadV.hlsl new file mode 100644 index 000000000..bf6fa9619 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/farFrustumQuadV.hlsl @@ -0,0 +1,43 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "../../hlslStructs.h" +#include "farFrustumQuad.hlsl" + + +FarFrustumQuadConnectV main( VertexIn_PNT IN, + uniform float4 rtParams0 ) +{ + FarFrustumQuadConnectV OUT; + + OUT.hpos = float4( IN.uv0, 0, 1 ); + + // Get a RT-corrected UV from the SS coord + OUT.uv0 = getUVFromSSPos( OUT.hpos.xyz, rtParams0 ); + + // Interpolators will generate eye rays the + // from far-frustum corners. + OUT.wsEyeRay = IN.pos.xyz; + OUT.vsEyeRay = IN.normal.xyz; + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/convexGeometryV.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/convexGeometryV.glsl new file mode 100644 index 000000000..6d3e36e7e --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/convexGeometryV.glsl @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +varying vec4 wsEyeDir; +varying vec4 ssPos; + +uniform mat4 modelview; +uniform mat4 objTrans; +uniform vec3 eyePosWorld; + +void main() +{ + gl_Position = modelview * gl_Vertex; + wsEyeDir = objTrans * gl_Vertex - vec4( eyePosWorld, 0.0 ); + ssPos = gl_Position; +} diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgDepthVisualizeP.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgDepthVisualizeP.glsl new file mode 100644 index 000000000..4a954ae84 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgDepthVisualizeP.glsl @@ -0,0 +1,33 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" + +varying vec2 uv0; +uniform sampler2D prepassBuffer; +uniform sampler1D depthViz; + +void main() +{ + float depth = prepassUncondition( prepassBuffer, uv0 ).w; + gl_FragColor = vec4( texture1D( depthViz, depth ).rgb, 1 ); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgLightColorVisualizeP.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgLightColorVisualizeP.glsl new file mode 100644 index 000000000..580204487 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgLightColorVisualizeP.glsl @@ -0,0 +1,34 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" + +varying vec2 uv0; +uniform sampler2D lightInfoBuffer; + +void main() +{ + vec3 lightcolor; + float nl_Att, specular; + lightinfoUncondition( texture2DLod( lightInfoBuffer, uv0 ), lightcolor, nl_Att, specular ); + gl_FragColor = vec4( lightcolor, 1.0 ); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgLightSpecularVisualizeP.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgLightSpecularVisualizeP.glsl new file mode 100644 index 000000000..6f7c52486 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgLightSpecularVisualizeP.glsl @@ -0,0 +1,34 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" + +varying vec2 uv0; +uniform sampler2D lightInfoBuffer; + +void main() +{ + vec3 lightcolor; + float nl_Att, specular; + lightinfoUncondition( texture2DLod( lightInfoBuffer, uv0 ), lightcolor, nl_Att, specular ); + gl_FragColor = vec4( specular, specular, specular, 1.0 ); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgNormalVisualizeP.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgNormalVisualizeP.glsl new file mode 100644 index 000000000..96b645524 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgNormalVisualizeP.glsl @@ -0,0 +1,33 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" + + +varying vec2 uv0; +uniform sampler2D prepassTex; + +void main() +{ + vec3 normal = prepassUncondition( prepassTex, uv0 ).xyz; + gl_FragColor = vec4( ( normal + 1.0 ) * 0.5, 1.0 ); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgShadowVisualizeP.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgShadowVisualizeP.glsl new file mode 100644 index 000000000..51609fc6b --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgShadowVisualizeP.glsl @@ -0,0 +1,31 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +varying vec2 uv0; +uniform sampler2D shadowMap; +uniform sampler1D depthViz; + +void main() +{ + float depth = clamp( texture2DLod( shadowMap, uv0, 0 ).r, 0.0, 1.0 ); + gl_FragColor = vec4( texture1D( depthViz, depth ).rgb, 1.0 ); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/farFrustumQuad.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/farFrustumQuad.glsl new file mode 100644 index 000000000..866a39b0b --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/farFrustumQuad.glsl @@ -0,0 +1,30 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +vec2 getUVFromSSPos( vec3 ssPos, vec4 rtParams ) +{ + vec2 outPos = ( ssPos.xy + 1.0 ) / 2.0; + outPos = ( outPos * rtParams.zw ) + rtParams.xy; + //outPos.y = 1.0 - outPos.y; + return outPos; +} diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/farFrustumQuadV.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/farFrustumQuadV.glsl new file mode 100644 index 000000000..ce5c2ad81 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/farFrustumQuadV.glsl @@ -0,0 +1,43 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "farFrustumQuad.glsl" + +uniform vec4 renderTargetParams; + +varying vec4 hpos; +varying vec2 uv0; +varying vec3 wsEyeRay; + + +void main() +{ + // Expand the SS coordinate (stored in uv0) + hpos = vec4( gl_MultiTexCoord0.st * 2.0 - 1.0, 1.0, 1.0 ); + gl_Position = hpos; + + // Get a RT-corrected UV from the SS coord + uv0 = getUVFromSSPos( hpos.xyz, renderTargetParams ); + + // Interpolators will generate eye ray from far-frustum corners + wsEyeRay = gl_Vertex.xyz; +} diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/lightingUtils.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/lightingUtils.glsl new file mode 100644 index 000000000..08af9231b --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/lightingUtils.glsl @@ -0,0 +1,79 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +float attenuate( vec4 lightColor, vec2 attParams, float dist ) +{ + // We're summing the results of a scaled constant, + // linear, and quadratic attenuation. + + #ifdef ACCUMULATE_LUV + return lightColor.w * ( 1.0 - dot( attParams, vec2( dist, dist * dist ) ) ); + #else + return 1.0 - dot( attParams, vec2( dist, dist * dist ) ); + #endif +} + +// Calculate the specular coefficent +// +// pxlToLight - Normalized vector representing direction from the pixel being lit, to the light source, in world space +// normal - Normalized surface normal +// pxlToEye - Normalized vector representing direction from pixel being lit, to the camera, in world space +// specPwr - Specular exponent +// specularScale - A scalar on the specular output used in RGB accumulation. +// +float calcSpecular( vec3 pxlToLight, vec3 normal, vec3 pxlToEye, float specPwr, float specularScale ) +{ +#ifdef PHONG_SPECULAR + // (R.V)^c + float specVal = dot( normalize( -reflect( pxlToLight, normal ) ), pxlToEye ); +#else + // (N.H)^c [Blinn-Phong, TGEA style, default] + float specVal = dot( normal, normalize( pxlToLight + pxlToEye ) ); +#endif + +#ifdef ACCUMULATE_LUV + return pow( max( specVal, 0.00001f ), specPwr ); +#else + // If this is RGB accumulation, than there is no facility for the luminance + // of the light to play in to the specular intensity. In LUV, the luminance + // of the light color gets rolled into N.L * Attenuation + return specularScale * pow( max( specVal, 0.00001f ), specPwr ); +#endif +} + +vec3 getDistanceVectorToPlane( vec3 origin, vec3 direction, vec4 plane ) +{ + float denum = dot( plane.xyz, direction.xyz ); + float num = dot( plane, vec4( origin, 1.0 ) ); + float t = -num / denum; + + return direction.xyz * t; +} + +vec3 getDistanceVectorToPlane( float negFarPlaneDotEye, vec3 direction, vec4 plane ) +{ + float denum = dot( plane.xyz, direction.xyz ); + float t = negFarPlaneDotEye / denum; + + return direction.xyz * t; +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/pointLightP.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/pointLightP.glsl new file mode 100644 index 000000000..f38d62fa5 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/pointLightP.glsl @@ -0,0 +1,241 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "farFrustumQuad.glsl" +#include "lightingUtils.glsl" +#include "../../shadowMap/shadowMapIO_GLSL.h" +#include "shadergen:/autogenConditioners.h" + + +#if TORQUE_SM >= 30 + + // Enables high quality soft shadow + // filtering for SM3.0 and above. + #define SOFTSHADOW_SM3 + + #include "softShadow.glsl" + +#else + + +#endif + + + +// I am not sure if we should do this in a better way +//#define SHADOW_CUBE +//#define SHADOW_PARABOLOID +#define SHADOW_DUALPARABOLOID +#define SHADOW_DUALPARABOLOID_SINGLE_PASS + + +#ifdef SHADOW_CUBE + + vec3 decodeShadowCoord( vec3 shadowCoord ) + { + return shadowCoord; + } + + vec4 shadowSample( samplerCUBE shadowMap, vec3 shadowCoord ) + { + return textureCUBE( shadowMap, shadowCoord ); + } + +#elif defined( SHADOW_DUALPARABOLOID ) + + vec3 decodeShadowCoord( vec3 paraVec ) + { + // Swizzle z and y + paraVec = paraVec.xzy; + + #ifdef SHADOW_DUALPARABOLOID_SINGLE_PASS + + bool calcBack = (paraVec.z < 0.0); + if(calcBack) + paraVec.z = paraVec.z * -1.0; + + #endif + + vec3 shadowCoord; + shadowCoord.x = (paraVec.x / (2.0*(1.0 + paraVec.z))) + 0.5; + shadowCoord.y = ((paraVec.y / (2.0*(1.0 + paraVec.z))) + 0.5); + shadowCoord.z = 0; + + // adjust the co-ordinate slightly if it is near the extent of the paraboloid + // this value was found via experementation + shadowCoord.xy *= 0.997; + + #ifdef SHADOW_DUALPARABOLOID_SINGLE_PASS + + // If this is the back, offset in the atlas + if(calcBack) + shadowCoord.x += 1.0; + + // Atlasing front and back maps, so scale + shadowCoord.x *= 0.5; + + #endif + + return shadowCoord; + } + +#else + + #error Unknown shadow type! + +#endif + +varying vec4 wsEyeDir; +varying vec4 ssPos; + + +uniform sampler2D prePassBuffer; + +#ifdef SHADOW_CUBE + uniform samplerCube shadowMap; +#else + uniform sampler2D shadowMap; +#endif +#ifdef ACCUMULATE_LUV + uniform sampler2D scratchTarget; +#endif + +uniform vec4 renderTargetParams; + +uniform vec3 lightPosition; +uniform vec4 lightColor; +uniform float lightBrightness; +uniform float lightRange; +uniform vec2 lightAttenuation; +uniform vec4 lightMapParams; + +uniform vec3 eyePosWorld; +uniform vec4 farPlane; +uniform float negFarPlaneDotEye; +uniform mat3x3 worldToLightProj; + +uniform vec4 lightParams; +uniform float shadowSoftness; +uniform float constantSpecularPower; + + +void main() +{ + // Compute scene UV + vec3 ssPosP = ssPos.xyz / ssPos.w; + vec2 uvScene = getUVFromSSPos( ssPosP, renderTargetParams ); + + // Sample/unpack the normal/z data + vec4 prepassSample = prepassUncondition( prePassBuffer, uvScene ); + vec3 normal = prepassSample.rgb; + float depth = prepassSample.a; + + // Eye ray - Eye -> Pixel + vec3 eyeRay = getDistanceVectorToPlane( negFarPlaneDotEye, wsEyeDir.xyz / wsEyeDir.w , farPlane ); + + // Get world space pixel position + vec3 worldPos = eyePosWorld + eyeRay * depth; + + // Build light vec, get length, clip pixel if needed + vec3 lightVec = lightPosition - worldPos; + float lenLightV = length( lightVec ); + if ( lightRange - lenLightV < 0.0 ) + discard; + + // Get the attenuated falloff. + float atten = attenuate( lightColor, lightAttenuation, lenLightV ); + if ( atten - 1e-6 < 0.0 ) + discard; + + // Normalize lightVec + lightVec /= lenLightV; + + // If we can do dynamic branching then avoid wasting + // fillrate on pixels that are backfacing to the light. + float nDotL = dot( lightVec, normal ); + //DB_CLIP( nDotL < 0 ); + + #ifdef NO_SHADOW + + float shadowed = 1.0; + + #else + + // Convert the light vector into a shadow map + // here once instead of in the filtering loop. + vec4 shadowCoord = vec4(0.0); + #ifdef SHADOW_CUBE + shadowCoord.xy = decodeShadowCoord( -lightVec ); + #else + shadowCoord.xy = decodeShadowCoord( worldToLightProj * -lightVec ).xy; + #endif + + // Get a linear depth from the light source. + float distToLight = lenLightV / lightRange; + + #ifdef SOFTSHADOW_SM3 + + float shadowed = softShadow_filter( shadowMap, + gTapRotationTex, + ssPosP.xy, + shadowCoord.xy, + shadowSoftness, + distToLight, + nDotL, + lightParams.y ); + + #else // !SOFTSHADOW_SM3 + + // TODO: Implement the SM2 lower quality + // shadow filtering method. + + #endif + + #endif // !NO_SHADOW + + // NOTE: Do not clip on fully shadowed pixels as it would + // cause the hardware occlusion query to disable the shadow. + + // Specular term + float specular = calcSpecular( lightVec, + normal, + normalize( -eyeRay ), + constantSpecularPower, + lightColor.a * lightBrightness ); + + // N.L * Attenuation + float Sat_NL_Att = clamp( nDotL * atten * shadowed, 0.0, 1.0 ); + + // In LUV color mode we need to blend in the + // output from the previous target. + vec4 previousPix = vec4(0.0); + #ifdef ACCUMULATE_LUV + previousPix = texture2DLod( scratchTarget, uvScene, 0 ); + #endif + + // Output + gl_FragColor = lightinfoCondition( lightColor.rgb * lightBrightness, + Sat_NL_Att, + specular, + previousPix ) * lightMapParams; +} diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/softShadow.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/softShadow.glsl new file mode 100644 index 000000000..8ef09ed2f --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/softShadow.glsl @@ -0,0 +1,131 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +#define NUM_TAPS 12 + +#define NUM_PRE_TAPS 4 + +/// The non-uniform poisson disk used in the +/// high quality shadow filtering. +vec2 sNonUniformTaps[NUM_TAPS]; + +void initNonUniformTaps() +{ + // These first 4 taps are located around the edges + // of the disk and are used to predict fully shadowed + // or unshadowed areas. + sNonUniformTaps[0] = vec2( 0.992833, 0.979309 ); + sNonUniformTaps[1] = vec2( -0.998585, 0.985853 ); + sNonUniformTaps[2] = vec2( 0.949299, -0.882562 ); + sNonUniformTaps[3] = vec2( -0.941358, -0.893924 ); + + // The rest of the samples. + sNonUniformTaps[4] = vec2( 0.545055, -0.589072 ); + sNonUniformTaps[5] = vec2( 0.346526, 0.385821 ); + sNonUniformTaps[6] = vec2( -0.260183, 0.334412 ); + sNonUniformTaps[7] = vec2( 0.248676, -0.679605 ); + sNonUniformTaps[8] = vec2( -0.569502, -0.390637 ); + sNonUniformTaps[9] = vec2( -0.014096, 0.012577 ); + sNonUniformTaps[10] = vec2( -0.259178, 0.876272 ); + sNonUniformTaps[11] = vec2( 0.649526, 0.664333 ); +} + +/// The texture used to do per-pixel pseudorandom +/// rotations of the filter taps. +uniform sampler2D gTapRotationTex; + + +float softShadow_sampleTaps( sampler2D shadowMap, + vec2 sinCos, + vec2 shadowPos, + float filterRadius, + float distToLight, + float esmFactor, + int startTap, + int endTap ) +{ + initNonUniformTaps(); + float shadow = 0.0; + + vec2 tap = vec2(0.0); + for ( int t = startTap; t < endTap; t++ ) + { + tap.x = ( sNonUniformTaps[t].x * sinCos.y - sNonUniformTaps[t].y * sinCos.x ) * filterRadius; + tap.y = ( sNonUniformTaps[t].y * sinCos.y + sNonUniformTaps[t].x * sinCos.x ) * filterRadius; + float occluder = texture2DLod( shadowMap, shadowPos + tap, 0.0 ).r; + + float esm = clamp( exp( esmFactor * ( occluder - distToLight ) ), 0.0, 1.0 ); + shadow += esm / float( endTap - startTap ); + } + + return shadow; +} + + +// HACK! HACK! HACK! +// We take the noise texture directly as the second parameter to ensure that it +// is the "last used" sampler, and thus doesn't collide with the prepass buffer +// or shadow map. If we use gTapRotationTex directly here, then it is the first +// used sampler and will collide with the prepass buffer. +float softShadow_filter( sampler2D shadowMap, + sampler2D noiseTexture, + vec2 vpos, + vec2 shadowPos, + float filterRadius, + float distToLight, + float dotNL, + float esmFactor ) +{ + // Lookup the random rotation for this screen pixel. + vec2 sinCos = ( texture2DLod( noiseTexture, vpos * 16.0, 0.0 ).rg - 0.5 ) * 2.0; + + // Do the prediction taps first. + float shadow = softShadow_sampleTaps( shadowMap, + sinCos, + shadowPos, + filterRadius, + distToLight, + esmFactor, + 0, + NUM_PRE_TAPS ); + + // Only do the expensive filtering if we're really + // in a partially shadowed area. + if ( shadow * ( 1.0 - shadow ) * max( dotNL, 0.0 ) > 0.06 ) + { + shadow += softShadow_sampleTaps( shadowMap, + sinCos, + shadowPos, + filterRadius, + distToLight, + esmFactor, + NUM_PRE_TAPS, + NUM_TAPS ); + + // This averages the taps above with the results + // of the prediction samples. + shadow *= 0.5; + } + + return shadow; +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/spotLightP.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/spotLightP.glsl new file mode 100644 index 000000000..1f7e949d9 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/spotLightP.glsl @@ -0,0 +1,168 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "farFrustumQuad.glsl" +#include "lightingUtils.glsl" +#include "../../shadowMap/shadowMapIO_GLSL.h" +#include "shadergen:/autogenConditioners.h" + + +#if TORQUE_SM >= 30 + + // Enables high quality soft shadow + // filtering for SM3.0 and above. + #define SOFTSHADOW_SM3 + + #include "softShadow.glsl" + +#else + + +#endif + + +varying vec4 ssPos; +varying vec4 wsEyeDir; + + +uniform sampler2D prePassBuffer; +uniform sampler2D shadowMap; +#ifdef ACCUMULATE_LUV + uniform sampler2D scratchTarget; +#endif + +uniform vec4 renderTargetParams; + +uniform vec3 lightPosition; +uniform vec4 lightColor; +uniform float lightBrightness; +uniform float lightRange; +uniform vec2 lightAttenuation; +uniform vec3 lightDirection; +uniform vec4 lightSpotParams; +uniform vec4 lightMapParams; + +uniform vec3 eyePosWorld; +uniform vec4 farPlane; +uniform float negFarPlaneDotEye; +uniform mat4x4 worldToLightProj; + +uniform vec4 lightParams; +uniform float shadowSoftness; +uniform float constantSpecularPower; + + +void main() +{ + // Compute scene UV + vec3 ssPosP = ssPos.xyz / ssPos.w; + vec2 uvScene = getUVFromSSPos( ssPosP, renderTargetParams ); + + // Sample/unpack the normal/z data + vec4 prepassSample = prepassUncondition( prePassBuffer, uvScene ); + vec3 normal = prepassSample.rgb; + float depth = prepassSample.a; + + // Eye ray - Eye -> Pixel + vec3 eyeRay = getDistanceVectorToPlane( negFarPlaneDotEye, wsEyeDir.xyz / wsEyeDir.w , farPlane ); + + // Get world space pixel position + vec3 worldPos = eyePosWorld + eyeRay * depth; + + // Build light vec, get length, clip pixel if needed + vec3 lightToPxlVec = worldPos - lightPosition; + float lenLightV = length( lightToPxlVec ); + lightToPxlVec /= lenLightV; + + //lightDirection = float3( -lightDirection.xy, lightDirection.z ); //float3( 0, 0, -1 ); + float cosAlpha = dot( lightDirection, lightToPxlVec ); + if ( cosAlpha - lightSpotParams.x < 0.0 ) discard; + if ( lightRange - lenLightV < 0.0 ) discard; + + float atten = attenuate( lightColor, lightAttenuation, lenLightV ); + atten *= ( cosAlpha - lightSpotParams.x ) / lightSpotParams.y; + if ( atten - 1e-6 < 0.0 ) discard; + + float nDotL = dot( normal, -lightToPxlVec ); + + #ifdef NO_SHADOW + + float shadowed = 1.0; + + #else + + // Find Shadow coordinate + vec4 pxlPosLightProj = vec4( worldToLightProj * vec4( worldPos, 1.0 ) ); + vec2 shadowCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + vec2( 0.5, 0.5 ); + + // Get a linear depth from the light source. + float distToLight = pxlPosLightProj.z / lightRange; + + #ifdef SOFTSHADOW_SM3 + + float shadowed = softShadow_filter( shadowMap, + gTapRotationTex, + ssPosP.xy, + shadowCoord, + shadowSoftness, + distToLight, + nDotL, + lightParams.y ); + + #else // !SOFTSHADOW_SM3 + + // Simple exponential shadow map. + float occluder = decodeShadowMap( texture2DLod( shadowMap, shadowCoord, 0.0 ) ); + float esmFactor = lightParams.y; + float shadowed = clamp( exp( esmFactor * ( occluder - distToLight ) ), 0.0, 1.0 ); + + #endif + + #endif // !NO_SHADOW + + // NOTE: Do not clip on fully shadowed pixels as it would + // cause the hardware occlusion query to disable the shadow. + + // Specular term + float specular = calcSpecular( -lightToPxlVec, + normal, + normalize( -eyeRay ), + constantSpecularPower, + lightColor.a * lightBrightness ); + + // N.L * Attenuation + float Sat_NL_Att = clamp( nDotL * atten * shadowed, 0.0, 1.0 ); + + // In LUV color mode we need to blend in the + // output from the previous target. + vec4 previousPix = vec4(0.0); + #ifdef ACCUMULATE_LUV + previousPix = texture2DLod( scratchTarget, uvScene, 0.0 ); + #endif + + // Output + gl_FragColor = lightinfoCondition( lightColor.rgb * lightBrightness, + Sat_NL_Att, + specular, + previousPix ) * lightMapParams; +} diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/vectorLightP.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/vectorLightP.glsl new file mode 100644 index 000000000..579f04ad4 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/vectorLightP.glsl @@ -0,0 +1,230 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" +#include "lightingUtils.glsl" +#include "../../shadowMap/shadowMapIO_GLSL.h" + +varying vec2 uv0; +varying vec3 wsEyeRay; + +uniform sampler2D prePassBuffer; +uniform sampler2D ShadowMap; + +#if TORQUE_SM >= 30 + + // Enables high quality soft shadow + // filtering for SM3.0 and above. + #define SOFTSHADOW_SM3 + + #include "softShadow.glsl" + +#else + + + +#endif + +uniform vec3 lightDirection; +uniform vec4 lightColor; +uniform float lightBrightness; +uniform vec4 lightAmbient; +uniform vec4 lightTrilight; + +uniform vec3 eyePosWorld; + +uniform mat4 worldToLightProj; +uniform vec4 splitDistStart; +uniform vec4 splitDistEnd; +uniform vec4 scaleX; +uniform vec4 scaleY; +uniform vec4 offsetX; +uniform vec4 offsetY; +uniform vec4 atlasXOffset; +uniform vec4 atlasYOffset; +uniform vec2 atlasScale; +uniform vec4 zNearFarInvNearFar; +uniform vec4 lightMapParams; + +uniform float constantSpecularPower; +uniform vec2 fadeStartLength; +uniform vec4 farPlaneScalePSSM; +uniform vec4 splitFade; +uniform vec4 overDarkPSSM; +uniform float shadowSoftness; + + +void main() +{ + // Sample/unpack the normal/z data + vec4 prepassSample = prepassUncondition( prePassBuffer, uv0 ); + vec3 normal = prepassSample.rgb; + float depth = prepassSample.a; + + // Use eye ray to get ws pos + vec4 worldPos = vec4(eyePosWorld + wsEyeRay * depth, 1.0f); + + // Get the light attenuation. + float dotNL = dot(-lightDirection, normal); + + #ifdef NO_SHADOW + + // Fully unshadowed. + float shadowed = 1.0; + + #else + + // Compute shadow map coordinate + vec4 pxlPosLightProj = worldToLightProj * worldPos; + vec2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w; + + float distOffset = 0.0; + float shadowed = 0.0; + float fadeAmt = 0.0; + vec4 zDist = vec4(zNearFarInvNearFar.x + zNearFarInvNearFar.y * depth); + + // Calculate things dependant on the shadowmap split + for ( int i = 0; i < 2; i++ ) + { + float zDistSplit = zDist.x + distOffset; + vec4 mask0; + mask0.x = float(zDistSplit >= splitDistStart.x); + mask0.y = float(zDistSplit >= splitDistStart.y); + mask0.z = float(zDistSplit >= splitDistStart.z); + mask0.w = float(zDistSplit >= splitDistStart.w); + + vec4 mask1; + mask1.x = float(zDistSplit < splitDistEnd.x); + mask1.y = float(zDistSplit < splitDistEnd.y); + mask1.z = float(zDistSplit < splitDistEnd.z); + mask1.w = float(zDistSplit < splitDistEnd.w); + + vec4 finalMask = mask0 * mask1; + + float splitFadeDist = dot( finalMask, splitFade ); + + vec2 finalScale; + finalScale.x = dot(finalMask, scaleX); + finalScale.y = dot(finalMask, scaleY); + + vec2 finalOffset; + finalOffset.x = dot(finalMask, offsetX); + finalOffset.y = dot(finalMask, offsetY); + + vec2 shadowCoord; + shadowCoord = baseShadowCoord * finalScale; + shadowCoord += finalOffset; + + // Convert to texcoord space + shadowCoord = 0.5 * shadowCoord + vec2(0.5, 0.5); + //shadowCoord.y = 1.0f - shadowCoord.y; + + // Move around inside of atlas + vec2 aOffset; + aOffset.x = dot(finalMask, atlasXOffset); + aOffset.y = dot(finalMask, atlasYOffset); + + shadowCoord *= atlasScale; + shadowCoord += aOffset; + + // Distance to light, in shadowmap space + float distToLight = pxlPosLightProj.z / pxlPosLightProj.w; + + // Each split has a different far plane, take this into account. + float farPlaneScale = dot( farPlaneScalePSSM, finalMask ); + distToLight *= farPlaneScale; + + #ifdef SOFTSHADOW_SM3 + + float esmShadow = softShadow_filter( ShadowMap, + gTapRotationTex, + uv0.xy, + shadowCoord, + farPlaneScale * shadowSoftness, + distToLight, + dotNL, + dot( finalMask, overDarkPSSM ) ); + + #else // !SOFTSHADOW_SM3 + + float occluder = decodeShadowMap( texture2DLod( ShadowMap, shadowCoord, 0.0 ) ); + float overDark = dot( finalMask, overDarkPSSM ); + float esmShadow = saturate( exp( esmFactor * ( occluder - distToLight ) ) ); + + #endif + + if ( i == 0 ) + { + float endDist = dot(splitDistEnd, finalMask); + fadeAmt = smoothstep(endDist - splitFadeDist, endDist, zDist).x; + shadowed = esmShadow * ( 1.0 - fadeAmt ); + } + else + shadowed += esmShadow * fadeAmt; + + distOffset += splitFadeDist; + } + + // Fade out the shadow at the end of the range. + float fadeOutAmt = ( zDist.x - fadeStartLength.x ) * fadeStartLength.y; + shadowed = mix( shadowed, 1.0, clamp( fadeOutAmt, 0.0, 1.0 ) ); + + #endif // !NO_SHADOW + + // Calc lighting coefficents + float specular = calcSpecular( -lightDirection, + normal, + normalize(-wsEyeRay), + constantSpecularPower, + lightColor.a * lightBrightness ); + + float Sat_NL_Att = clamp(dotNL, 0.0, 1.0) * shadowed; + + // Trilight, described by Tom Forsyth + // http://home.comcast.net/~tom_forsyth/papers/trilight/trilight.html +#ifdef ACCUMULATE_LUV + + // In LUV multiply in the brightness of the light color (normaly done in the attenuate function) + Sat_NL_Att *= lightColor.a; + + vec4 ambientBlend = lightAmbient; + ambientBlend.b *= clamp(-dotNL, 0.0, 1.0); + + vec3 trilight = lightTrilight.rgb; + trilight.b *= clamp(1.0 - abs(dotNL), 0.0, 1.0); + + ambientBlend.rg = mix(ambientBlend.rg, trilight.rg, clamp(0.5 * trilight.b / lightAmbient.b, 0.0, 1.0)); + ambientBlend.b += trilight.b; + +#else + + // RGB + // TODO: Trilight seems broken... it does lighting in shadows! + //vec4 ambientBlend = vec4(lightTrilight.rgb * clamp(1.0 - abs(dotNL), 0.0, 1.0) + lightAmbient.rgb * clamp(-dotNL, 0.0, 1.0), 0.0); + vec4 ambientBlend = vec4(lightAmbient.rgb, 0.0); + +#endif + + // Output + gl_FragColor = lightinfoCondition( lightColor.rgb * lightBrightness, Sat_NL_Att, specular, ambientBlend) * lightMapParams; +} diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/lightingUtils.hlsl b/Templates/Empty/game/shaders/common/lighting/advanced/lightingUtils.hlsl new file mode 100644 index 000000000..2bff18999 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/lightingUtils.hlsl @@ -0,0 +1,51 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +float attenuate( float4 lightColor, float2 attParams, float dist ) +{ + // We're summing the results of a scaled constant, + // linear, and quadratic attenuation. + + #ifdef ACCUMULATE_LUV + return lightColor.w * ( 1.0 - dot( attParams, float2( dist, dist * dist ) ) ); + #else + return 1.0 - dot( attParams, float2( dist, dist * dist ) ); + #endif +} + +float3 getDistanceVectorToPlane( float3 origin, float3 direction, float4 plane ) +{ + float denum = dot( plane.xyz, direction.xyz ); + float num = dot( plane, float4( origin, 1.0 ) ); + float t = -num / denum; + + return direction.xyz * t; +} + +float3 getDistanceVectorToPlane( float negFarPlaneDotEye, float3 direction, float4 plane ) +{ + float denum = dot( plane.xyz, direction.xyz ); + float t = negFarPlaneDotEye / denum; + + return direction.xyz * t; +} diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/particlePointLightP.hlsl b/Templates/Empty/game/shaders/common/lighting/advanced/particlePointLightP.hlsl new file mode 100644 index 000000000..bc4784980 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/particlePointLightP.hlsl @@ -0,0 +1,75 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" + +#include "farFrustumQuad.hlsl" +#include "lightingUtils.hlsl" +#include "../../lighting.hlsl" + + +struct ConvexConnectP +{ + float4 ssPos : TEXCOORD0; + float3 vsEyeDir : TEXCOORD1; +}; + +float4 main( ConvexConnectP IN, + uniform sampler2D prePassBuffer : register(S0), + + uniform float4 lightPosition, + uniform float4 lightColor, + uniform float lightRange, + + uniform float4 vsFarPlane, + uniform float4 rtParams0 ) : COLOR0 +{ + // Compute scene UV + float3 ssPos = IN.ssPos.xyz / IN.ssPos.w; + float2 uvScene = getUVFromSSPos(ssPos, rtParams0); + + // Sample/unpack the normal/z data + float4 prepassSample = prepassUncondition(prePassBuffer, uvScene); + float3 normal = prepassSample.rgb; + float depth = prepassSample.a; + + // Eye ray - Eye -> Pixel + float3 eyeRay = getDistanceVectorToPlane(-vsFarPlane.w, IN.vsEyeDir, vsFarPlane); + float3 viewSpacePos = eyeRay * depth; + + // Build light vec, get length, clip pixel if needed + float3 lightVec = lightPosition.xyz - viewSpacePos; + float lenLightV = length(lightVec); + clip(lightRange - lenLightV); + + // Do a very simple falloff instead of real attenuation + float atten = 1.0 - saturate(lenLightV / lightRange); + + // Normalize lightVec + lightVec /= lenLightV; + + // N.L * Attenuation + float Sat_NL_Att = saturate(dot(lightVec, normal)) * atten; + + // Output, no specular + return lightinfoCondition(lightColor.rgb, Sat_NL_Att, 0.0, 0.0); +} diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/particlePointLightV.hlsl b/Templates/Empty/game/shaders/common/lighting/advanced/particlePointLightV.hlsl new file mode 100644 index 000000000..f5dc9e444 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/particlePointLightV.hlsl @@ -0,0 +1,46 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "../../hlslStructs.h" + +struct ConvexConnectV +{ + float4 hpos : POSITION; + float4 ssPos : TEXCOORD0; + float3 vsEyeDir : TEXCOORD1; +}; + +ConvexConnectV main( VertexIn_P IN, + uniform float4x4 viewProj, + uniform float4x4 view, + uniform float3 particlePosWorld, + uniform float lightRange ) +{ + ConvexConnectV OUT; + + float4 vPosWorld = IN.pos + float4(particlePosWorld, 0.0) + float4(IN.pos.xyz, 0.0) * lightRange; + OUT.hpos = mul(viewProj, vPosWorld); + OUT.vsEyeDir = mul(view, vPosWorld); + OUT.ssPos = OUT.hpos; + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/pointLightP.hlsl b/Templates/Empty/game/shaders/common/lighting/advanced/pointLightP.hlsl new file mode 100644 index 000000000..96d00b78d --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/pointLightP.hlsl @@ -0,0 +1,239 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" + +#include "farFrustumQuad.hlsl" +#include "lightingUtils.hlsl" +#include "../../lighting.hlsl" +#include "../shadowMap/shadowMapIO_HLSL.h" +#include "softShadow.hlsl" + + +struct ConvexConnectP +{ + float4 wsEyeDir : TEXCOORD0; + float4 ssPos : TEXCOORD1; + float4 vsEyeDir : TEXCOORD2; +}; + + +#ifdef USE_COOKIE_TEX + +/// The texture for cookie rendering. +uniform samplerCUBE cookieMap : register(S2); + +#endif + + +#ifdef SHADOW_CUBE + + float3 decodeShadowCoord( float3 shadowCoord ) + { + return shadowCoord; + } + + float4 shadowSample( samplerCUBE shadowMap, float3 shadowCoord ) + { + return texCUBE( shadowMap, shadowCoord ); + } + +#else + + float3 decodeShadowCoord( float3 paraVec ) + { + // Flip y and z + paraVec = paraVec.xzy; + + #ifndef SHADOW_PARABOLOID + + bool calcBack = (paraVec.z < 0.0); + if ( calcBack ) + { + paraVec.z = paraVec.z * -1.0; + + #ifdef SHADOW_DUALPARABOLOID + paraVec.x = -paraVec.x; + #endif + } + + #endif + + float3 shadowCoord; + shadowCoord.x = (paraVec.x / (2*(1 + paraVec.z))) + 0.5; + shadowCoord.y = 1-((paraVec.y / (2*(1 + paraVec.z))) + 0.5); + shadowCoord.z = 0; + + // adjust the co-ordinate slightly if it is near the extent of the paraboloid + // this value was found via experementation + // NOTE: this is wrong, it only biases in one direction, not towards the uv + // center ( 0.5 0.5 ). + //shadowCoord.xy *= 0.997; + + #ifndef SHADOW_PARABOLOID + + // If this is the back, offset in the atlas + if ( calcBack ) + shadowCoord.x += 1.0; + + // Atlasing front and back maps, so scale + shadowCoord.x *= 0.5; + + #endif + + return shadowCoord; + } + +#endif + + +float4 main( ConvexConnectP IN, + + uniform sampler2D prePassBuffer : register(S0), + + #ifdef SHADOW_CUBE + uniform samplerCUBE shadowMap : register(S1), + #else + uniform sampler2D shadowMap : register(S1), + #endif + + uniform float4 rtParams0, + + uniform float3 lightPosition, + uniform float4 lightColor, + uniform float lightBrightness, + uniform float lightRange, + uniform float2 lightAttenuation, + uniform float4 lightMapParams, + + uniform float4 vsFarPlane, + uniform float3x3 viewToLightProj, + + uniform float4 lightParams, + uniform float shadowSoftness ) : COLOR0 +{ + // Compute scene UV + float3 ssPos = IN.ssPos.xyz / IN.ssPos.w; + float2 uvScene = getUVFromSSPos( ssPos, rtParams0 ); + + // Sample/unpack the normal/z data + float4 prepassSample = prepassUncondition( prePassBuffer, uvScene ); + float3 normal = prepassSample.rgb; + float depth = prepassSample.a; + + // Eye ray - Eye -> Pixel + float3 eyeRay = getDistanceVectorToPlane( -vsFarPlane.w, IN.vsEyeDir.xyz, vsFarPlane ); + float3 viewSpacePos = eyeRay * depth; + + // Build light vec, get length, clip pixel if needed + float3 lightVec = lightPosition - viewSpacePos; + float lenLightV = length( lightVec ); + clip( lightRange - lenLightV ); + + // Get the attenuated falloff. + float atten = attenuate( lightColor, lightAttenuation, lenLightV ); + clip( atten - 1e-6 ); + + // Normalize lightVec + lightVec /= lenLightV; + + // If we can do dynamic branching then avoid wasting + // fillrate on pixels that are backfacing to the light. + float nDotL = dot( lightVec, normal ); + //DB_CLIP( nDotL < 0 ); + + #ifdef NO_SHADOW + + float shadowed = 1.0; + + #else + + // Get a linear depth from the light source. + float distToLight = lenLightV / lightRange; + + #ifdef SHADOW_CUBE + + // TODO: We need to fix shadow cube to handle soft shadows! + float occ = texCUBE( shadowMap, mul( viewToLightProj, -lightVec ) ).r; + float shadowed = saturate( exp( lightParams.y * ( occ - distToLight ) ) ); + + #else + + float2 shadowCoord = decodeShadowCoord( mul( viewToLightProj, -lightVec ) ).xy; + + float shadowed = softShadow_filter( shadowMap, + ssPos.xy, + shadowCoord, + shadowSoftness, + distToLight, + nDotL, + lightParams.y ); + + #endif + + #endif // !NO_SHADOW + + #ifdef USE_COOKIE_TEX + + // Lookup the cookie sample. + float4 cookie = texCUBE( cookieMap, mul( viewToLightProj, -lightVec ) ); + + // Multiply the light with the cookie tex. + lightColor.rgb *= cookie.rgb; + + // Use a maximum channel luminance to attenuate + // the lighting else we get specular in the dark + // regions of the cookie texture. + atten *= max( cookie.r, max( cookie.g, cookie.b ) ); + + #endif + + // NOTE: Do not clip on fully shadowed pixels as it would + // cause the hardware occlusion query to disable the shadow. + + // Specular term + float specular = AL_CalcSpecular( lightVec, + normal, + normalize( -eyeRay ) ) * lightColor.a; + + float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness; + float3 lightColorOut = lightMapParams.rgb * lightColor.rgb; + float4 addToResult = 0.0; + + // TODO: This needs to be removed when lightmapping is disabled + // as its extra work per-pixel on dynamic lit scenes. + // + // Special lightmapping pass. + if ( lightMapParams.a < 0.0 ) + { + // This disables shadows on the backsides of objects. + shadowed = nDotL < 0.0f ? 1.0f : shadowed; + + Sat_NL_Att = 1.0f; + shadowed = lerp( 1.0f, shadowed, atten ); + lightColorOut = shadowed; + specular *= lightBrightness; + addToResult = ( 1.0 - shadowed ) * abs(lightMapParams); + } + + return lightinfoCondition( lightColorOut, Sat_NL_Att, specular, addToResult ); +} diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/softShadow.hlsl b/Templates/Empty/game/shaders/common/lighting/advanced/softShadow.hlsl new file mode 100644 index 000000000..0e8ecabaa --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/softShadow.hlsl @@ -0,0 +1,159 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +#if defined( SOFTSHADOW ) && defined( SOFTSHADOW_HIGH_QUALITY ) + +#define NUM_PRE_TAPS 4 +#define NUM_TAPS 12 + +/// The non-uniform poisson disk used in the +/// high quality shadow filtering. +static float2 sNonUniformTaps[NUM_TAPS] = +{ + // These first 4 taps are located around the edges + // of the disk and are used to predict fully shadowed + // or unshadowed areas. + { 0.992833, 0.979309 }, + { -0.998585, 0.985853 }, + { 0.949299, -0.882562 }, + { -0.941358, -0.893924 }, + + // The rest of the samples. + { 0.545055, -0.589072 }, + { 0.346526, 0.385821 }, + { -0.260183, 0.334412 }, + { 0.248676, -0.679605 }, + { -0.569502, -0.390637 }, + { -0.614096, 0.212577 }, + { -0.259178, 0.876272 }, + { 0.649526, 0.864333 }, +}; + +#else + +#define NUM_PRE_TAPS 5 + +/// The non-uniform poisson disk used in the +/// high quality shadow filtering. +static float2 sNonUniformTaps[NUM_PRE_TAPS] = +{ + { 0.892833, 0.959309 }, + { -0.941358, -0.873924 }, + { -0.260183, 0.334412 }, + { 0.348676, -0.679605 }, + { -0.569502, -0.390637 }, +}; + +#endif + + +/// The texture used to do per-pixel pseudorandom +/// rotations of the filter taps. +uniform sampler2D gTapRotationTex : register(S3); + + +float softShadow_sampleTaps( sampler2D shadowMap, + float2 sinCos, + float2 shadowPos, + float filterRadius, + float distToLight, + float esmFactor, + int startTap, + int endTap ) +{ + float shadow = 0; + + float2 tap = 0; + for ( int t = startTap; t < endTap; t++ ) + { + tap.x = ( sNonUniformTaps[t].x * sinCos.y - sNonUniformTaps[t].y * sinCos.x ) * filterRadius; + tap.y = ( sNonUniformTaps[t].y * sinCos.y + sNonUniformTaps[t].x * sinCos.x ) * filterRadius; + float occluder = tex2Dlod( shadowMap, float4( shadowPos + tap, 0, 0 ) ).r; + + float esm = saturate( exp( esmFactor * ( occluder - distToLight ) ) ); + shadow += esm / float( endTap - startTap ); + } + + return shadow; +} + + +float softShadow_filter( sampler2D shadowMap, + float2 vpos, + float2 shadowPos, + float filterRadius, + float distToLight, + float dotNL, + float esmFactor ) +{ + #ifndef SOFTSHADOW + + // If softshadow is undefined then we skip any complex + // filtering... just do a single sample ESM. + + float occluder = tex2Dlod( shadowMap, float4( shadowPos, 0, 0 ) ).r; + float shadow = saturate( exp( esmFactor * ( occluder - distToLight ) ) ); + + #else + + // Lookup the random rotation for this screen pixel. + float2 sinCos = ( tex2Dlod( gTapRotationTex, float4( vpos * 16, 0, 0 ) ).rg - 0.5 ) * 2; + + // Do the prediction taps first. + float shadow = softShadow_sampleTaps( shadowMap, + sinCos, + shadowPos, + filterRadius, + distToLight, + esmFactor, + 0, + NUM_PRE_TAPS ); + + // We live with only the pretap results if we don't + // have high quality shadow filtering enabled. + #ifdef SOFTSHADOW_HIGH_QUALITY + + // Only do the expensive filtering if we're really + // in a partially shadowed area. + if ( shadow * ( 1.0 - shadow ) * max( dotNL, 0 ) > 0.06 ) + { + shadow += softShadow_sampleTaps( shadowMap, + sinCos, + shadowPos, + filterRadius, + distToLight, + esmFactor, + NUM_PRE_TAPS, + NUM_TAPS ); + + // This averages the taps above with the results + // of the prediction samples. + shadow *= 0.5; + } + + #endif // SOFTSHADOW_HIGH_QUALITY + + #endif // SOFTSHADOW + + return shadow; +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/spotLightP.hlsl b/Templates/Empty/game/shaders/common/lighting/advanced/spotLightP.hlsl new file mode 100644 index 000000000..1cf1f13f5 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/spotLightP.hlsl @@ -0,0 +1,167 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" + +#include "farFrustumQuad.hlsl" +#include "lightingUtils.hlsl" +#include "../../lighting.hlsl" +#include "../shadowMap/shadowMapIO_HLSL.h" +#include "softShadow.hlsl" + + +struct ConvexConnectP +{ + float4 wsEyeDir : TEXCOORD0; + float4 ssPos : TEXCOORD1; + float4 vsEyeDir : TEXCOORD2; +}; + +#ifdef USE_COOKIE_TEX + +/// The texture for cookie rendering. +uniform sampler2D cookieMap : register(S2); + +#endif + + +float4 main( ConvexConnectP IN, + + uniform sampler2D prePassBuffer : register(S0), + uniform sampler2D shadowMap : register(S1), + + uniform float4 rtParams0, + + uniform float3 lightPosition, + uniform float4 lightColor, + uniform float lightBrightness, + uniform float lightRange, + uniform float2 lightAttenuation, + uniform float3 lightDirection, + uniform float4 lightSpotParams, + uniform float4 lightMapParams, + + uniform float4 vsFarPlane, + uniform float4x4 viewToLightProj, + + uniform float4 lightParams, + uniform float shadowSoftness ) : COLOR0 +{ + // Compute scene UV + float3 ssPos = IN.ssPos.xyz / IN.ssPos.w; + float2 uvScene = getUVFromSSPos( ssPos, rtParams0 ); + + // Sample/unpack the normal/z data + float4 prepassSample = prepassUncondition( prePassBuffer, uvScene ); + float3 normal = prepassSample.rgb; + float depth = prepassSample.a; + + // Eye ray - Eye -> Pixel + float3 eyeRay = getDistanceVectorToPlane( -vsFarPlane.w, IN.vsEyeDir.xyz, vsFarPlane ); + float3 viewSpacePos = eyeRay * depth; + + // Build light vec, get length, clip pixel if needed + float3 lightToPxlVec = viewSpacePos - lightPosition; + float lenLightV = length( lightToPxlVec ); + lightToPxlVec /= lenLightV; + + //lightDirection = float3( -lightDirection.xy, lightDirection.z ); //float3( 0, 0, -1 ); + float cosAlpha = dot( lightDirection, lightToPxlVec ); + clip( cosAlpha - lightSpotParams.x ); + clip( lightRange - lenLightV ); + + float atten = attenuate( lightColor, lightAttenuation, lenLightV ); + atten *= ( cosAlpha - lightSpotParams.x ) / lightSpotParams.y; + clip( atten - 1e-6 ); + atten = saturate( atten ); + + float nDotL = dot( normal, -lightToPxlVec ); + + // Get the shadow texture coordinate + float4 pxlPosLightProj = mul( viewToLightProj, float4( viewSpacePos, 1 ) ); + float2 shadowCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + float2( 0.5, 0.5 ); + shadowCoord.y = 1.0f - shadowCoord.y; + + #ifdef NO_SHADOW + + float shadowed = 1.0; + + #else + + // Get a linear depth from the light source. + float distToLight = pxlPosLightProj.z / lightRange; + + float shadowed = softShadow_filter( shadowMap, + ssPos.xy, + shadowCoord, + shadowSoftness, + distToLight, + nDotL, + lightParams.y ); + + #endif // !NO_SHADOW + + #ifdef USE_COOKIE_TEX + + // Lookup the cookie sample. + float4 cookie = tex2D( cookieMap, shadowCoord ); + + // Multiply the light with the cookie tex. + lightColor.rgb *= cookie.rgb; + + // Use a maximum channel luminance to attenuate + // the lighting else we get specular in the dark + // regions of the cookie texture. + atten *= max( cookie.r, max( cookie.g, cookie.b ) ); + + #endif + + // NOTE: Do not clip on fully shadowed pixels as it would + // cause the hardware occlusion query to disable the shadow. + + // Specular term + float specular = AL_CalcSpecular( -lightToPxlVec, + normal, + normalize( -eyeRay ) ) * lightColor.a; + + float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness; + float3 lightColorOut = lightMapParams.rgb * lightColor.rgb; + float4 addToResult = 0.0; + + // TODO: This needs to be removed when lightmapping is disabled + // as its extra work per-pixel on dynamic lit scenes. + // + // Special lightmapping pass. + if ( lightMapParams.a < 0.0 ) + { + // This disables shadows on the backsides of objects. + shadowed = nDotL < 0.0f ? 1.0f : shadowed; + + Sat_NL_Att = 1.0f; + shadowed = lerp( 1.0f, shadowed, atten ); + lightColorOut = shadowed; + specular *= lightBrightness; + addToResult = ( 1.0 - shadowed ) * abs(lightMapParams); + } + + return lightinfoCondition( lightColorOut, Sat_NL_Att, specular, addToResult ); +} diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/vectorLightP.hlsl b/Templates/Empty/game/shaders/common/lighting/advanced/vectorLightP.hlsl new file mode 100644 index 000000000..326802966 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/advanced/vectorLightP.hlsl @@ -0,0 +1,233 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" + +#include "farFrustumQuad.hlsl" +#include "../../torque.hlsl" +#include "../../lighting.hlsl" +#include "lightingUtils.hlsl" +#include "../shadowMap/shadowMapIO_HLSL.h" +#include "softShadow.hlsl" + + +uniform sampler2D ShadowMap : register(S1); + +#ifdef USE_SSAO_MASK +uniform sampler2D ssaoMask : register(S2); +uniform float4 rtParams2; +#endif + + +float4 main( FarFrustumQuadConnectP IN, + + uniform sampler2D prePassBuffer : register(S0), + + uniform float3 lightDirection, + uniform float4 lightColor, + uniform float lightBrightness, + uniform float4 lightAmbient, + + uniform float3 eyePosWorld, + + uniform float4x4 worldToLightProj, + + uniform float4 scaleX, + uniform float4 scaleY, + uniform float4 offsetX, + uniform float4 offsetY, + uniform float4 atlasXOffset, + uniform float4 atlasYOffset, + uniform float2 atlasScale, + uniform float4 zNearFarInvNearFar, + uniform float4 lightMapParams, + + uniform float2 fadeStartLength, + uniform float4 farPlaneScalePSSM, + uniform float4 overDarkPSSM, + uniform float shadowSoftness ) : COLOR0 +{ + // Sample/unpack the normal/z data + float4 prepassSample = prepassUncondition( prePassBuffer, IN.uv0 ); + float3 normal = prepassSample.rgb; + float depth = prepassSample.a; + + // Use eye ray to get ws pos + float4 worldPos = float4(eyePosWorld + IN.wsEyeRay * depth, 1.0f); + + // Get the light attenuation. + float dotNL = dot(-lightDirection, normal); + + #ifdef PSSM_DEBUG_RENDER + float3 debugColor = 0; + #endif + + #ifdef NO_SHADOW + + // Fully unshadowed. + float shadowed = 1.0; + + #ifdef PSSM_DEBUG_RENDER + debugColor = 1.0; + #endif + + #else + + // Compute shadow map coordinate + float4 pxlPosLightProj = mul(worldToLightProj, worldPos); + float2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w; + + // Distance to light, in shadowmap space + float distToLight = pxlPosLightProj.z / pxlPosLightProj.w; + + // Figure out which split to sample from. Basically, we compute the shadowmap sample coord + // for all of the splits and then check if its valid. + float4 shadowCoordX = baseShadowCoord.xxxx; + float4 shadowCoordY = baseShadowCoord.yyyy; + float4 farPlaneDists = distToLight.xxxx; + shadowCoordX *= scaleX; + shadowCoordY *= scaleY; + shadowCoordX += offsetX; + shadowCoordY += offsetY; + farPlaneDists *= farPlaneScalePSSM; + + // If the shadow sample is within -1..1 and the distance + // to the light for this pixel is less than the far plane + // of the split, use it. + float4 finalMask; + if ( shadowCoordX.x > -0.99 && shadowCoordX.x < 0.99 && + shadowCoordY.x > -0.99 && shadowCoordY.x < 0.99 && + farPlaneDists.x < 1.0 ) + finalMask = float4(1, 0, 0, 0); + + else if ( shadowCoordX.y > -0.99 && shadowCoordX.y < 0.99 && + shadowCoordY.y > -0.99 && shadowCoordY.y < 0.99 && + farPlaneDists.y < 1.0 ) + finalMask = float4(0, 1, 0, 0); + + else if ( shadowCoordX.z > -0.99 && shadowCoordX.z < 0.99 && + shadowCoordY.z > -0.99 && shadowCoordY.z < 0.99 && + farPlaneDists.z < 1.0 ) + finalMask = float4(0, 0, 1, 0); + + else + finalMask = float4(0, 0, 0, 1); + + + #ifdef PSSM_DEBUG_RENDER + if ( finalMask.x > 0 ) + debugColor += float3( 1, 0, 0 ); + else if ( finalMask.y > 0 ) + debugColor += float3( 0, 1, 0 ); + else if ( finalMask.z > 0 ) + debugColor += float3( 0, 0, 1 ); + else if ( finalMask.w > 0 ) + debugColor += float3( 1, 1, 0 ); + #endif + + // Here we know what split we're sampling from, so recompute the texcoord location + // Yes, we could just use the result from above, but doing it this way actually saves + // shader instructions. + float2 finalScale; + finalScale.x = dot(finalMask, scaleX); + finalScale.y = dot(finalMask, scaleY); + + float2 finalOffset; + finalOffset.x = dot(finalMask, offsetX); + finalOffset.y = dot(finalMask, offsetY); + + float2 shadowCoord; + shadowCoord = baseShadowCoord * finalScale; + shadowCoord += finalOffset; + + // Convert to texcoord space + shadowCoord = 0.5 * shadowCoord + float2(0.5, 0.5); + shadowCoord.y = 1.0f - shadowCoord.y; + + // Move around inside of atlas + float2 aOffset; + aOffset.x = dot(finalMask, atlasXOffset); + aOffset.y = dot(finalMask, atlasYOffset); + + shadowCoord *= atlasScale; + shadowCoord += aOffset; + + // Each split has a different far plane, take this into account. + float farPlaneScale = dot( farPlaneScalePSSM, finalMask ); + distToLight *= farPlaneScale; + + float shadowed = softShadow_filter( ShadowMap, + IN.uv0.xy, + shadowCoord, + farPlaneScale * shadowSoftness, + distToLight, + dotNL, + dot( finalMask, overDarkPSSM ) ); + + // Fade out the shadow at the end of the range. + float4 zDist = (zNearFarInvNearFar.x + zNearFarInvNearFar.y * depth); + float fadeOutAmt = ( zDist.x - fadeStartLength.x ) * fadeStartLength.y; + shadowed = lerp( shadowed, 1.0, saturate( fadeOutAmt ) ); + + #ifdef PSSM_DEBUG_RENDER + if ( fadeOutAmt > 1.0 ) + debugColor = 1.0; + #endif + + #endif // !NO_SHADOW + + // Specular term + float specular = AL_CalcSpecular( -lightDirection, + normal, + normalize(-IN.vsEyeRay) ) * lightColor.a; + + float Sat_NL_Att = saturate( dotNL * shadowed ) * lightBrightness; + float3 lightColorOut = lightMapParams.rgb * lightColor.rgb; + float4 addToResult = lightAmbient; + + // TODO: This needs to be removed when lightmapping is disabled + // as its extra work per-pixel on dynamic lit scenes. + // + // Special lightmapping pass. + if ( lightMapParams.a < 0.0 ) + { + // This disables shadows on the backsides of objects. + shadowed = dotNL < 0.0f ? 1.0f : shadowed; + + Sat_NL_Att = 1.0f; + lightColorOut = shadowed; + specular *= lightBrightness; + addToResult = ( 1.0 - shadowed ) * abs(lightMapParams); + } + + // Sample the AO texture. + #ifdef USE_SSAO_MASK + float ao = 1.0 - tex2D( ssaoMask, viewportCoordToRenderTarget( IN.uv0.xy, rtParams2 ) ).r; + addToResult *= ao; + #endif + + #ifdef PSSM_DEBUG_RENDER + lightColorOut = debugColor; + #endif + + return lightinfoCondition( lightColorOut, Sat_NL_Att, specular, addToResult ); +} diff --git a/Templates/Empty/game/shaders/common/lighting/basic/gl/shadowFilterP.glsl b/Templates/Empty/game/shaders/common/lighting/basic/gl/shadowFilterP.glsl new file mode 100644 index 000000000..238721e5e --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/basic/gl/shadowFilterP.glsl @@ -0,0 +1,54 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +uniform sampler2D diffuseMap; + +varying vec2 uv; + +uniform vec2 oneOverTargetSize; + +void main() +{ + vec2 sNonUniformTaps[8]; + + sNonUniformTaps[0] = vec2(0.992833, 0.979309); + sNonUniformTaps[1] = vec2(-0.998585, 0.985853); + sNonUniformTaps[2] = vec2(0.949299, -0.882562); + sNonUniformTaps[3] = vec2(-0.941358, -0.893924); + sNonUniformTaps[4] = vec2(0.545055, -0.589072); + sNonUniformTaps[5] = vec2(0.346526, 0.385821); + sNonUniformTaps[6] = vec2(-0.260183, 0.334412); + sNonUniformTaps[7] = vec2(0.248676, -0.679605); + + gl_FragColor = vec4(0.0); + + vec2 texScale = vec2(1.0); + + for ( int i=0; i < 4; i++ ) + { + vec2 offset = (oneOverTargetSize * texScale) * sNonUniformTaps[i]; + gl_FragColor += texture2D( diffuseMap, uv + offset ); + } + + gl_FragColor /= vec4(4.0); + gl_FragColor.rgb = vec3(0.0); +} diff --git a/Templates/Empty/game/shaders/common/lighting/basic/gl/shadowFilterV.glsl b/Templates/Empty/game/shaders/common/lighting/basic/gl/shadowFilterV.glsl new file mode 100644 index 000000000..cbf3696be --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/basic/gl/shadowFilterV.glsl @@ -0,0 +1,34 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "../../../../../../shaders/common/gl/torque.glsl" + +uniform vec2 oneOverTargetSize; +uniform vec4 rtParams0; + +varying vec2 uv; + +void main() +{ + gl_Position = gl_Vertex; + uv = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams0 ); +} diff --git a/Templates/Empty/game/shaders/common/lighting/basic/shadowFilterP.hlsl b/Templates/Empty/game/shaders/common/lighting/basic/shadowFilterP.hlsl new file mode 100644 index 000000000..f161fb5d3 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/basic/shadowFilterP.hlsl @@ -0,0 +1,50 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shaders/common/postFx/postFx.hlsl" + +uniform sampler2D diffuseMap : register(S0); + +struct VertToPix +{ + float4 hpos : POSITION; + float2 uv : TEXCOORD0; +}; + +static float offset[3] = { 0.0, 1.3846153846, 3.2307692308 }; +static float weight[3] = { 0.2270270270, 0.3162162162, 0.0702702703 }; + +uniform float2 oneOverTargetSize; + +float4 main( VertToPix IN ) : COLOR +{ + float4 OUT = tex2D( diffuseMap, IN.uv ) * weight[0]; + + for ( int i=1; i < 3; i++ ) + { + float2 sample = (BLUR_DIR * offset[i]) * oneOverTargetSize; + OUT += tex2D( diffuseMap, IN.uv + sample ) * weight[i]; + OUT += tex2D( diffuseMap, IN.uv - sample ) * weight[i]; + } + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/lighting/basic/shadowFilterV.hlsl b/Templates/Empty/game/shaders/common/lighting/basic/shadowFilterV.hlsl new file mode 100644 index 000000000..bf6a36249 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/basic/shadowFilterV.hlsl @@ -0,0 +1,42 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "../../../../../../shaders/common/postFx/postFx.hlsl" +#include "../../../../../../shaders/common/torque.hlsl" + +float4 rtParams0; + +struct VertToPix +{ + float4 hpos : POSITION; + float2 uv : TEXCOORD0; +}; + +VertToPix main( PFXVert IN ) +{ + VertToPix OUT; + + OUT.hpos = IN.pos; + OUT.uv = viewportCoordToRenderTarget( IN.uv, rtParams0 ); + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/lighting/shadowMap/boxFilterP.hlsl b/Templates/Empty/game/shaders/common/lighting/shadowMap/boxFilterP.hlsl new file mode 100644 index 000000000..dd691de23 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/shadowMap/boxFilterP.hlsl @@ -0,0 +1,80 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//***************************************************************************** +// Box Filter +//***************************************************************************** + +struct ConnectData +{ + float2 tex0 : TEXCOORD0; +}; + +// If not defined from ShaderData then define +// the default blur kernel size here. +//#ifndef blurSamples +// #define blurSamples 4 +//#endif + +float log_conv ( float x0, float X, float y0, float Y ) +{ + return (X + log(x0 + (y0 * exp(Y - X)))); +} + +float4 main( ConnectData IN, + uniform sampler2D diffuseMap0 : register(S0), + uniform float texSize : register(C0), + uniform float2 blurDimension : register(C2), + uniform float2 blurBoundaries : register(C3) + ) : COLOR0 +{ + // 5x5 + if (IN.tex0.x <= blurBoundaries.x) + { + float texelSize = 1.2f / texSize; + float2 sampleOffset = texelSize * blurDimension; + //float2 offset = 0.5 * float( blurSamples ) * sampleOffset; + + float2 texCoord = IN.tex0; + + float accum = log_conv(0.3125, tex2D(diffuseMap0, texCoord - sampleOffset), 0.375, tex2D(diffuseMap0, texCoord)); + accum = log_conv(1, accum, 0.3125, tex2D(diffuseMap0, texCoord + sampleOffset)); + + return accum; + } else { + // 3x3 + if (IN.tex0.x <= blurBoundaries.y) + { + float texelSize = 1.3f / texSize; + float2 sampleOffset = texelSize * blurDimension; + //float2 offset = 0.5 * float( blurSamples ) * sampleOffset; + + float2 texCoord = IN.tex0; + float accum = log_conv(0.5, tex2D(diffuseMap0, texCoord - sampleOffset), 0.5, tex2D(diffuseMap0, texCoord + sampleOffset)); + + return accum; + } else { + return tex2D(diffuseMap0, IN.tex0); + } + } +} + diff --git a/Templates/Empty/game/shaders/common/lighting/shadowMap/boxFilterV.hlsl b/Templates/Empty/game/shaders/common/lighting/shadowMap/boxFilterV.hlsl new file mode 100644 index 000000000..75d9af000 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/shadowMap/boxFilterV.hlsl @@ -0,0 +1,54 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//***************************************************************************** +// Box Filter +//***************************************************************************** +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +struct VertData +{ + float2 texCoord : TEXCOORD0; + float4 position : POSITION; +}; + +struct ConnectData +{ + float4 hpos : POSITION; + float2 tex0 : TEXCOORD0; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( VertData IN, + uniform float4x4 modelview : register(C0)) +{ + ConnectData OUT; + + OUT.hpos = mul(modelview, IN.position); + OUT.tex0 = IN.texCoord; + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/lighting/shadowMap/gl/boxFilterP.glsl b/Templates/Empty/game/shaders/common/lighting/shadowMap/gl/boxFilterP.glsl new file mode 100644 index 000000000..2800a3f17 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/shadowMap/gl/boxFilterP.glsl @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#define blurSamples 4.0 + +uniform sampler2D diffuseMap0; +uniform float texSize; +uniform vec2 blurDimension; + +varying vec2 tex0; + +void main() +{ + // Preshader + float TexelSize = 1.0 / texSize; + vec2 SampleOffset = TexelSize * blurDimension; + vec2 Offset = 0.5 * float(blurSamples - 1.0) * SampleOffset; + + vec2 BaseTexCoord = tex0 - Offset; + + vec4 accum = vec4(0.0, 0.0, 0.0, 0.0); + for(int i = 0; i < int(blurSamples); i++) + { + accum += texture2D(diffuseMap0, BaseTexCoord + float(i) * SampleOffset); + } + accum /= blurSamples; + gl_FragColor = accum; +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/lighting/shadowMap/gl/boxFilterV.glsl b/Templates/Empty/game/shaders/common/lighting/shadowMap/gl/boxFilterV.glsl new file mode 100644 index 000000000..3850f83c7 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/shadowMap/gl/boxFilterV.glsl @@ -0,0 +1,31 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +uniform mat4 modelview; + +varying vec2 tex0; + +void main() +{ + gl_Position = modelview * gl_Vertex; + tex0 = gl_MultiTexCoord0.st; +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/lighting/shadowMap/shadowMapIO_GLSL.h b/Templates/Empty/game/shaders/common/lighting/shadowMap/shadowMapIO_GLSL.h new file mode 100644 index 000000000..10d69b834 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/shadowMap/shadowMapIO_GLSL.h @@ -0,0 +1,50 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//#define SM_Fmt_R8G8B8A8 + +#define pkDepthBitShft 65536.0 +#define pkDepthChanMax 256.0 +#define bias -0.5/255.0 +#define coeff 0.9999991 +//#define coeff 1.0 + +vec4 encodeShadowMap( float depth ) +{ +#if defined(SM_Fmt_R8G8B8A8) + return frac( vec4(1.0, 255.0, 65025.0, 160581375.0) * depth ) + vec4(bias); + + //float4 packedValue = frac((depth / coeff) * float4(16777216.0, 65536.0, 256.0, 1.0)); + //return (packedValue - packedValue.xxyz * float4(0, 1.0 / 256, 1.0 / 256, 1.0 / 256)); +#else + return vec4(depth); +#endif +} + +float decodeShadowMap( vec4 smSample ) +{ +#if defined(SM_Fmt_R8G8B8A8) + return dot( smSample, vec4(1.0, 1/255.0, 1/65025.0, 1/160581375.0) ); +#else + return smSample.x; +#endif +} diff --git a/Templates/Empty/game/shaders/common/lighting/shadowMap/shadowMapIO_HLSL.h b/Templates/Empty/game/shaders/common/lighting/shadowMap/shadowMapIO_HLSL.h new file mode 100644 index 000000000..84ef6b6a8 --- /dev/null +++ b/Templates/Empty/game/shaders/common/lighting/shadowMap/shadowMapIO_HLSL.h @@ -0,0 +1,50 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//#define SM_Fmt_R8G8B8A8 + +#define pkDepthBitShft 65536.0 +#define pkDepthChanMax 256.0 +#define bias -0.5/255.0 +#define coeff 0.9999991 +//#define coeff 1.0 + +float4 encodeShadowMap( float depth ) +{ +#if defined(SM_Fmt_R8G8B8A8) + return frac( float4(1.0, 255.0, 65025.0, 160581375.0) * depth ) + bias; + + //float4 packedValue = frac((depth / coeff) * float4(16777216.0, 65536.0, 256.0, 1.0)); + //return (packedValue - packedValue.xxyz * float4(0, 1.0 / 256, 1.0 / 256, 1.0 / 256)); +#else + return depth; +#endif +} + +float decodeShadowMap( float4 smSample ) +{ +#if defined(SM_Fmt_R8G8B8A8) + return dot( smSample, float4(1.0, 1/255.0, 1/65025.0, 1/160581375.0) ); +#else + return smSample.x; +#endif +} diff --git a/Templates/Empty/game/shaders/common/particleCompositeP.hlsl b/Templates/Empty/game/shaders/common/particleCompositeP.hlsl new file mode 100644 index 000000000..35c2cb4c5 --- /dev/null +++ b/Templates/Empty/game/shaders/common/particleCompositeP.hlsl @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- +#include "torque.hlsl" + +uniform sampler2D colorSource : register(S0); +uniform float4 offscreenTargetParams; + +#ifdef TORQUE_LINEAR_DEPTH +#define REJECT_EDGES +uniform sampler2D edgeSource : register(S1); +uniform float4 edgeTargetParams; +#endif + + +float4 main( float4 offscreenPos : TEXCOORD0, float4 backbufferPos : TEXCOORD1 ) : COLOR +{ + // Off-screen particle source screenspace position in XY + // Back-buffer screenspace position in ZW + float4 ssPos = float4(offscreenPos.xy / offscreenPos.w, backbufferPos.xy / backbufferPos.w); + + float4 uvScene = ( ssPos + 1.0 ) / 2.0; + uvScene.yw = 1.0 - uvScene.yw; + uvScene.xy = viewportCoordToRenderTarget(uvScene.xy, offscreenTargetParams); + +#ifdef REJECT_EDGES + // Cut out particles along the edges, this will create the stencil mask + uvScene.zw = viewportCoordToRenderTarget(uvScene.zw, edgeTargetParams); + float edge = tex2D( edgeSource, uvScene.zw ).r; + clip( -edge ); +#endif + + // Sample offscreen target and return + return tex2D( colorSource, uvScene.xy ); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/particleCompositeV.hlsl b/Templates/Empty/game/shaders/common/particleCompositeV.hlsl new file mode 100644 index 000000000..87fac0d94 --- /dev/null +++ b/Templates/Empty/game/shaders/common/particleCompositeV.hlsl @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "hlslStructs.h" + +struct VertOut +{ + float4 hpos : POSITION; + float4 offscreenPos : TEXCOORD0; + float4 backbufferPos : TEXCOORD1; +}; + +uniform float4 screenRect; // point, extent + +VertOut main( float4 uvCoord : COLOR ) +{ + VertOut OUT; + + OUT.hpos = float4(uvCoord.xy, 1.0, 1.0); + OUT.hpos.xy *= screenRect.zw; + OUT.hpos.xy += screenRect.xy; + + OUT.backbufferPos = OUT.hpos; + OUT.offscreenPos = OUT.hpos; + + return OUT; +} + diff --git a/Templates/Empty/game/shaders/common/particlesP.hlsl b/Templates/Empty/game/shaders/common/particlesP.hlsl new file mode 100644 index 000000000..80e3c7105 --- /dev/null +++ b/Templates/Empty/game/shaders/common/particlesP.hlsl @@ -0,0 +1,109 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "torque.hlsl" + +// With advanced lighting we get soft particles. +#ifdef TORQUE_LINEAR_DEPTH + #define SOFTPARTICLES +#endif + +#ifdef SOFTPARTICLES + + #include "shadergen:/autogenConditioners.h" + + uniform float oneOverSoftness; + uniform float oneOverFar; + uniform sampler2D prepassTex : register(S1); + //uniform float3 vEye; + uniform float4 prePassTargetParams; +#endif + +#define CLIP_Z // TODO: Make this a proper macro + +struct Conn +{ + float4 color : TEXCOORD0; + float2 uv0 : TEXCOORD1; + float4 pos : TEXCOORD2; +}; + +uniform sampler2D diffuseMap : register(S0); + +uniform sampler2D paraboloidLightMap : register(S2); + +float4 lmSample( float3 nrm ) +{ + bool calcBack = (nrm.z < 0.0); + if ( calcBack ) + nrm.z = nrm.z * -1.0; + + float2 lmCoord; + lmCoord.x = (nrm.x / (2*(1 + nrm.z))) + 0.5; + lmCoord.y = 1-((nrm.y / (2*(1 + nrm.z))) + 0.5); + + + // If this is the back, offset in the atlas + if ( calcBack ) + lmCoord.x += 1.0; + + // Atlasing front and back maps, so scale + lmCoord.x *= 0.5; + + return tex2D(paraboloidLightMap, lmCoord); +} + + +uniform float alphaFactor; +uniform float alphaScale; + +float4 main( Conn IN ) : COLOR +{ + float softBlend = 1; + + #ifdef SOFTPARTICLES + float2 tc = IN.pos.xy * float2(1.0, -1.0) / IN.pos.w; + tc = viewportCoordToRenderTarget(saturate( ( tc + 1.0 ) * 0.5 ), prePassTargetParams); + + float sceneDepth = prepassUncondition( prepassTex, tc ).w; + float depth = IN.pos.w * oneOverFar; + float diff = sceneDepth - depth; + #ifdef CLIP_Z + // If drawing offscreen, this acts as the depth test, since we don't line up with the z-buffer + // When drawing high-res, though, we want to be able to take advantage of hi-z + // so this is #ifdef'd out + //clip(diff); + #endif + softBlend = saturate( diff * oneOverSoftness ); + #endif + + float4 diffuse = tex2D( diffuseMap, IN.uv0 ); + + //return float4( lmSample(float3(0, 0, -1)).rgb, IN.color.a * diffuse.a * softBlend * alphaScale); + + // Scale output color by the alpha factor (turn LerpAlpha into pre-multiplied alpha) + float3 colorScale = ( alphaFactor < 0.0 ? IN.color.rgb * diffuse.rgb : ( alphaFactor > 0.0 ? IN.color.a * diffuse.a * alphaFactor * softBlend : softBlend ) ); + + return hdrEncode( float4( IN.color.rgb * diffuse.rgb * colorScale, + IN.color.a * diffuse.a * softBlend * alphaScale ) ); +} + diff --git a/Templates/Empty/game/shaders/common/particlesV.hlsl b/Templates/Empty/game/shaders/common/particlesV.hlsl new file mode 100644 index 000000000..f09604237 --- /dev/null +++ b/Templates/Empty/game/shaders/common/particlesV.hlsl @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +struct Vertex +{ + float4 pos : POSITION; + float4 color : COLOR0; + float2 uv0 : TEXCOORD0; +}; + +struct Conn +{ + float4 hpos : POSITION; + float4 color : TEXCOORD0; + float2 uv0 : TEXCOORD1; + float4 pos : TEXCOORD2; +}; + + +uniform float4x4 modelViewProj; +uniform float4x4 fsModelViewProj; + +Conn main( Vertex In ) +{ + Conn Out; + + Out.hpos = mul( modelViewProj, In.pos ); + Out.pos = mul( fsModelViewProj, In.pos ); + Out.color = In.color; + Out.uv0 = In.uv0; + + return Out; +} + diff --git a/Templates/Empty/game/shaders/common/planarReflectBumpP.hlsl b/Templates/Empty/game/shaders/common/planarReflectBumpP.hlsl new file mode 100644 index 000000000..a5057db50 --- /dev/null +++ b/Templates/Empty/game/shaders/common/planarReflectBumpP.hlsl @@ -0,0 +1,83 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +struct ConnectData +{ + float4 texCoord : TEXCOORD0; + float2 tex2 : TEXCOORD1; +}; + + +struct Fragout +{ + float4 col : COLOR0; +}; + + +//----------------------------------------------------------------------------- +// Fade edges of axis for texcoord passed in +//----------------------------------------------------------------------------- +float fadeAxis( float val ) +{ + // Fades from 1.0 to 0.0 when less than 0.1 + float fadeLow = saturate( val * 10.0 ); + + // Fades from 1.0 to 0.0 when greater than 0.9 + float fadeHigh = 1.0 - saturate( (val - 0.9) * 10.0 ); + + return fadeLow * fadeHigh; +} + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Fragout main( ConnectData IN, + uniform sampler2D refractMap : register(S1), + uniform sampler2D texMap : register(S0), + uniform sampler2D bumpMap : register(S2) +) +{ + Fragout OUT; + + float3 bumpNorm = tex2D( bumpMap, IN.tex2 ) * 2.0 - 1.0; + float2 offset = float2( bumpNorm.x, bumpNorm.y ); + float4 texIndex = IN.texCoord; + + // The fadeVal is used to "fade" the distortion at the edges of the screen. + // This is done so it won't sample the reflection texture out-of-bounds and create artifacts + // Note - this can be done more efficiently with a texture lookup + float fadeVal = fadeAxis( texIndex.x / texIndex.w ) * fadeAxis( texIndex.y / texIndex.w ); + + const float distortion = 0.2; + texIndex.xy += offset * distortion * fadeVal; + + float4 reflectColor = tex2Dproj( refractMap, texIndex ); + float4 diffuseColor = tex2D( texMap, IN.tex2 ); + + OUT.col = diffuseColor + reflectColor * diffuseColor.a; + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/planarReflectBumpV.hlsl b/Templates/Empty/game/shaders/common/planarReflectBumpV.hlsl new file mode 100644 index 000000000..108f918ce --- /dev/null +++ b/Templates/Empty/game/shaders/common/planarReflectBumpV.hlsl @@ -0,0 +1,66 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#define IN_HLSL +#include "shdrConsts.h" + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +struct VertData +{ + float2 texCoord : TEXCOORD0; + float2 lmCoord : TEXCOORD1; + float3 T : TEXCOORD2; + float3 B : TEXCOORD3; + float3 normal : NORMAL; + float4 position : POSITION; +}; + + +struct ConnectData +{ + float4 hpos : POSITION; + float4 texCoord : TEXCOORD0; + float2 tex2 : TEXCOORD1; +}; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( VertData IN, + uniform float4x4 modelview ) +{ + ConnectData OUT; + OUT.hpos = mul(modelview, IN.position); + + float4x4 texGenTest = { 0.5, 0.0, 0.0, 0.5, + 0.0, -0.5, 0.0, 0.5, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 }; + + OUT.texCoord = mul( texGenTest, OUT.hpos ); + + OUT.tex2 = IN.texCoord; + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/planarReflectP.hlsl b/Templates/Empty/game/shaders/common/planarReflectP.hlsl new file mode 100644 index 000000000..981cc316d --- /dev/null +++ b/Templates/Empty/game/shaders/common/planarReflectP.hlsl @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +struct ConnectData +{ + float2 texCoord : TEXCOORD0; + float4 tex2 : TEXCOORD1; +}; + + +struct Fragout +{ + float4 col : COLOR0; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Fragout main( ConnectData IN, + uniform sampler2D texMap : register(S0), + uniform sampler2D refractMap : register(S1) +) +{ + Fragout OUT; + + float4 diffuseColor = tex2D( texMap, IN.texCoord ); + float4 reflectColor = tex2Dproj( refractMap, IN.tex2 ); + + OUT.col = diffuseColor + reflectColor * diffuseColor.a; + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/planarReflectV.hlsl b/Templates/Empty/game/shaders/common/planarReflectV.hlsl new file mode 100644 index 000000000..cd8cb2d96 --- /dev/null +++ b/Templates/Empty/game/shaders/common/planarReflectV.hlsl @@ -0,0 +1,56 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#define IN_HLSL +#include "hlslStructs.h" + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- + +struct ConnectData +{ + float4 hpos : POSITION; + float2 texCoord : TEXCOORD0; + float4 tex2 : TEXCOORD1; +}; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( VertexIn_PNTTTB IN, + uniform float4x4 modelview : register(C0) +) +{ + ConnectData OUT; + OUT.hpos = mul(modelview, IN.pos); + + float4x4 texGenTest = { 0.5, 0.0, 0.0, 0.5, + 0.0, -0.5, 0.0, 0.5, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 }; + + OUT.texCoord = IN.uv0; + OUT.tex2 = mul( texGenTest, OUT.hpos ); + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/postFx/chromaticLens.hlsl b/Templates/Empty/game/shaders/common/postFx/chromaticLens.hlsl new file mode 100644 index 000000000..5916e985a --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/chromaticLens.hlsl @@ -0,0 +1,61 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Based on 'Cubic Lens Distortion HLSL Shader' by François Tarlier +// www.francois-tarlier.com/blog/index.php/2009/11/cubic-lens-distortion-shader + +#include "./postFx.hlsl" +#include "./../torque.hlsl" + + +uniform sampler2D backBuffer : register( s0 ); +uniform float distCoeff; +uniform float cubeDistort; +uniform float3 colorDistort; + + +float4 main( PFXVertToPix IN ) : COLOR0 +{ + float2 tex = IN.uv0; + + float f = 0; + float r2 = (tex.x - 0.5) * (tex.x - 0.5) + (tex.y - 0.5) * (tex.y - 0.5); + + // Only compute the cubic distortion if necessary. + if ( cubeDistort == 0.0 ) + f = 1 + r2 * distCoeff; + else + f = 1 + r2 * (distCoeff + cubeDistort * sqrt(r2)); + + // Distort each color channel seperately to get a chromatic distortion effect. + float3 outColor; + float3 distort = f.xxx + colorDistort; + + for ( int i=0; i < 3; i++ ) + { + float x = distort[i] * ( tex.x - 0.5 ) + 0.5; + float y = distort[i] * ( tex.y - 0.5 ) + 0.5; + outColor[i] = tex2Dlod( backBuffer, float4(x,y,0,0) )[i]; + } + + return float4( outColor.rgb, 1 ); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/postFx/dof/DOF_CalcCoC_P.hlsl b/Templates/Empty/game/shaders/common/postFx/dof/DOF_CalcCoC_P.hlsl new file mode 100644 index 000000000..bc17a2c04 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/dof/DOF_CalcCoC_P.hlsl @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "./../postFx.hlsl" + +// These are set by the game engine. +uniform sampler2D shrunkSampler : register(S0); // Output of DofDownsample() +uniform sampler2D blurredSampler : register(S1); // Blurred version of the shrunk sampler + +// This is the pixel shader function that calculates the actual +// value used for the near circle of confusion. +// "texCoords" are 0 at the bottom left pixel and 1 at the top right. +float4 main( PFXVertToPix IN ) : COLOR +{ + float3 color; + float coc; + half4 blurred; + half4 shrunk; + + shrunk = tex2D( shrunkSampler, IN.uv0 ); + blurred = tex2D( blurredSampler, IN.uv1 ); + color = shrunk.rgb; + //coc = shrunk.a; + //coc = blurred.a; + //coc = max( blurred.a, shrunk.a ); + coc = 2 * max( blurred.a, shrunk.a ) - shrunk.a; + + + //return float4( coc.rrr, 1.0 ); + //return float4( color, 1.0 ); + return float4( color, coc ); + //return float4( 1.0, 0.0, 1.0, 1.0 ); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/postFx/dof/DOF_CalcCoC_V.hlsl b/Templates/Empty/game/shaders/common/postFx/dof/DOF_CalcCoC_V.hlsl new file mode 100644 index 000000000..40cec49de --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/dof/DOF_CalcCoC_V.hlsl @@ -0,0 +1,70 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "./../postFx.hlsl" +#include "./../../torque.hlsl" + +uniform float4 rtParams0; +uniform float4 rtParams1; +uniform float4 rtParams2; +uniform float4 rtParams3; + +PFXVertToPix main( PFXVert IN ) +{ + PFXVertToPix OUT; + + /* + OUT.hpos = IN.pos; + OUT.uv0 = IN.uv; + OUT.uv1 = IN.uv; + OUT.uv2 = IN.uv; + OUT.uv3 = IN.uv; + */ + + /* + OUT.hpos = IN.pos; + OUT.uv0 = IN.uv + rtParams0.xy; + OUT.uv1 = IN.uv + rtParams1.xy; + OUT.uv2 = IN.uv + rtParams2.xy; + OUT.uv3 = IN.uv + rtParams3.xy; + */ + + /* + OUT.hpos = IN.pos; + OUT.uv0 = IN.uv * rtParams0.zw; + OUT.uv1 = IN.uv * rtParams1.zw; + OUT.uv2 = IN.uv * rtParams2.zw; + OUT.uv3 = IN.uv * rtParams3.zw; + */ + + + OUT.hpos = IN.pos; + OUT.uv0 = viewportCoordToRenderTarget( IN.uv, rtParams0 ); + OUT.uv1 = viewportCoordToRenderTarget( IN.uv, rtParams1 ); + OUT.uv2 = viewportCoordToRenderTarget( IN.uv, rtParams2 ); + OUT.uv3 = viewportCoordToRenderTarget( IN.uv, rtParams3 ); + + + OUT.wsEyeRay = IN.wsEyeRay; + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/postFx/dof/DOF_DownSample_P.hlsl b/Templates/Empty/game/shaders/common/postFx/dof/DOF_DownSample_P.hlsl new file mode 100644 index 000000000..37e591f25 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/dof/DOF_DownSample_P.hlsl @@ -0,0 +1,135 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" + +// These are set by the game engine. +// The render target size is one-quarter the scene rendering size. +uniform sampler2D colorSampler : register(S0); +uniform sampler2D depthSampler : register(S1); +uniform float2 dofEqWorld; +uniform float depthOffset; +uniform float2 targetSize; +uniform float maxWorldCoC; +//uniform float2 dofEqWeapon; +//uniform float2 dofRowDelta; // float2( 0, 0.25 / renderTargetHeight ) + +struct Pixel +{ + float4 position : POSITION; + float2 tcColor0 : TEXCOORD0; + float2 tcColor1 : TEXCOORD1; + float2 tcDepth0 : TEXCOORD2; + float2 tcDepth1 : TEXCOORD3; + float2 tcDepth2 : TEXCOORD4; + float2 tcDepth3 : TEXCOORD5; +}; + +half4 main( Pixel IN ) : COLOR +{ + //return float4( 1.0, 0.0, 1.0, 1.0 ); + + float2 dofRowDelta = float2( 0, 0.25 / targetSize.y ); + + //float2 dofEqWorld = float2( -60, 1.0 ); + + half3 color; + half maxCoc; + float4 depth; + half4 viewCoc; + half4 sceneCoc; + half4 curCoc; + half4 coc; + float2 rowOfs[4]; + + // "rowOfs" reduces how many moves PS2.0 uses to emulate swizzling. + rowOfs[0] = 0; + rowOfs[1] = dofRowDelta.xy; + rowOfs[2] = dofRowDelta.xy * 2; + rowOfs[3] = dofRowDelta.xy * 3; + + // Use bilinear filtering to average 4 color samples for free. + color = 0; + color += tex2D( colorSampler, IN.tcColor0.xy + rowOfs[0] ).rgb; + color += tex2D( colorSampler, IN.tcColor1.xy + rowOfs[0] ).rgb; + color += tex2D( colorSampler, IN.tcColor0.xy + rowOfs[2] ).rgb; + color += tex2D( colorSampler, IN.tcColor1.xy + rowOfs[2] ).rgb; + color /= 4; + + // Process 4 samples at a time to use vector hardware efficiently. + // The CoC will be 1 if the depth is negative, so use "min" to pick + // between "sceneCoc" and "viewCoc". + + for ( int i = 0; i < 4; i++ ) + { + depth[0] = prepassUncondition( depthSampler, float4( IN.tcDepth0.xy + rowOfs[i], 0, 0 ) ).w; + depth[1] = prepassUncondition( depthSampler, float4( IN.tcDepth1.xy + rowOfs[i], 0, 0 ) ).w; + depth[2] = prepassUncondition( depthSampler, float4( IN.tcDepth2.xy + rowOfs[i], 0, 0 ) ).w; + depth[3] = prepassUncondition( depthSampler, float4( IN.tcDepth3.xy + rowOfs[i], 0, 0 ) ).w; + coc[i] = clamp( dofEqWorld.x * depth + dofEqWorld.y, 0.0, maxWorldCoC ); + } + + /* + depth[0] = tex2D( depthSampler, pixel.tcDepth0.xy + rowOfs[0] ).r; + depth[1] = tex2D( depthSampler, pixel.tcDepth1.xy + rowOfs[0] ).r; + depth[2] = tex2D( depthSampler, pixel.tcDepth2.xy + rowOfs[0] ).r; + depth[3] = tex2D( depthSampler, pixel.tcDepth3.xy + rowOfs[0] ).r; + viewCoc = saturate( dofEqWeapon.x * -depth + dofEqWeapon.y ); + sceneCoc = saturate( dofEqWorld.x * depth + dofEqWorld.y ); + curCoc = min( viewCoc, sceneCoc ); + coc = curCoc; + + depth[0] = tex2D( depthSampler, pixel.tcDepth0.xy + rowOfs[1] ).r; + depth[1] = tex2D( depthSampler, pixel.tcDepth1.xy + rowOfs[1] ).r; + depth[2] = tex2D( depthSampler, pixel.tcDepth2.xy + rowOfs[1] ).r; + depth[3] = tex2D( depthSampler, pixel.tcDepth3.xy + rowOfs[1] ).r; + viewCoc = saturate( dofEqWeapon.x * -depth + dofEqWeapon.y ); + sceneCoc = saturate( dofEqWorld.x * depth + dofEqWorld.y ); + curCoc = min( viewCoc, sceneCoc ); + coc = max( coc, curCoc ); + + depth[0] = tex2D( depthSampler, pixel.tcDepth0.xy + rowOfs[2] ).r; + depth[1] = tex2D( depthSampler, pixel.tcDepth1.xy + rowOfs[2] ).r; + depth[2] = tex2D( depthSampler, pixel.tcDepth2.xy + rowOfs[2] ).r; + depth[3] = tex2D( depthSampler, pixel.tcDepth3.xy + rowOfs[2] ).r; + viewCoc = saturate( dofEqWeapon.x * -depth + dofEqWeapon.y ); + sceneCoc = saturate( dofEqWorld.x * depth + dofEqWorld.y ); + curCoc = min( viewCoc, sceneCoc ); + coc = max( coc, curCoc ); + + depth[0] = tex2D( depthSampler, pixel.tcDepth0.xy + rowOfs[3] ).r; + depth[1] = tex2D( depthSampler, pixel.tcDepth1.xy + rowOfs[3] ).r; + depth[2] = tex2D( depthSampler, pixel.tcDepth2.xy + rowOfs[3] ).r; + depth[3] = tex2D( depthSampler, pixel.tcDepth3.xy + rowOfs[3] ).r; + viewCoc = saturate( dofEqWeapon.x * -depth + dofEqWeapon.y ); + sceneCoc = saturate( dofEqWorld.x * depth + dofEqWorld.y ); + curCoc = min( viewCoc, sceneCoc ); + coc = max( coc, curCoc ); + */ + + maxCoc = max( max( coc[0], coc[1] ), max( coc[2], coc[3] ) ); + + //return half4( 1.0, 0.0, 1.0, 1.0 ); + return half4( color, maxCoc ); + //return half4( color, 1.0f ); + //return half4( maxCoc.rrr, 1.0 ); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/postFx/dof/DOF_DownSample_V.hlsl b/Templates/Empty/game/shaders/common/postFx/dof/DOF_DownSample_V.hlsl new file mode 100644 index 000000000..da2a79fb4 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/dof/DOF_DownSample_V.hlsl @@ -0,0 +1,61 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "./../postFx.hlsl" +#include "./../../torque.hlsl" + +struct Vert +{ + float4 pos : POSITION; + float2 tc : TEXCOORD0; + float3 wsEyeRay : TEXCOORD1; +}; + +struct Pixel +{ + float4 position : POSITION; + float2 tcColor0 : TEXCOORD0; + float2 tcColor1 : TEXCOORD1; + float2 tcDepth0 : TEXCOORD2; + float2 tcDepth1 : TEXCOORD3; + float2 tcDepth2 : TEXCOORD4; + float2 tcDepth3 : TEXCOORD5; +}; + +uniform float4 rtParams0; +uniform float2 oneOverTargetSize; + +Pixel main( Vert IN ) +{ + Pixel OUT; + OUT.position = IN.pos; + + float2 uv = viewportCoordToRenderTarget( IN.tc, rtParams0 ); + //OUT.position = mul( IN.pos, modelView ); + OUT.tcColor1 = uv + float2( +1.0, -0.0 ) * oneOverTargetSize; + OUT.tcColor0 = uv + float2( -1.0, -0.0 ) * oneOverTargetSize; + OUT.tcDepth0 = uv + float2( -0.5, -0.0 ) * oneOverTargetSize; + OUT.tcDepth1 = uv + float2( -1.5, -0.0 ) * oneOverTargetSize; + OUT.tcDepth2 = uv + float2( +1.5, -0.0 ) * oneOverTargetSize; + OUT.tcDepth3 = uv + float2( +2.5, -0.0 ) * oneOverTargetSize; + return OUT; +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/postFx/dof/DOF_Final_P.hlsl b/Templates/Empty/game/shaders/common/postFx/dof/DOF_Final_P.hlsl new file mode 100644 index 000000000..36622495c --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/dof/DOF_Final_P.hlsl @@ -0,0 +1,144 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" +#include "./../postFx.hlsl" + +uniform sampler2D colorSampler : register(S0); // Original source image +uniform sampler2D smallBlurSampler : register(S1); // Output of SmallBlurPS() +uniform sampler2D largeBlurSampler : register(S2); // Blurred output of DofDownsample() +uniform sampler2D depthSampler : register(S3); // +uniform float2 oneOverTargetSize; +uniform float4 dofLerpScale; +uniform float4 dofLerpBias; +uniform float3 dofEqFar; +uniform float maxFarCoC; + +//static float d0 = 0.1; +//static float d1 = 0.1; +//static float d2 = 0.8; +//static float4 dofLerpScale = float4( -1.0 / d0, -1.0 / d1, -1.0 / d2, 1.0 / d2 ); +//static float4 dofLerpBias = float4( 1.0, (1.0 - d2) / d1, 1.0 / d2, (d2 - 1.0) / d2 ); +//static float3 dofEqFar = float3( 2.0, 0.0, 1.0 ); + +float4 tex2Doffset( sampler2D s, float2 tc, float2 offset ) +{ + return tex2D( s, tc + offset * oneOverTargetSize ); +} + +half3 GetSmallBlurSample( float2 tc ) +{ + half3 sum; + const half weight = 4.0 / 17; + sum = 0; // Unblurred sample done by alpha blending + //sum += weight * tex2Doffset( colorSampler, tc, float2( 0, 0 ) ).rgb; + sum += weight * tex2Doffset( colorSampler, tc, float2( +0.5, -1.5 ) ).rgb; + sum += weight * tex2Doffset( colorSampler, tc, float2( -1.5, -0.5 ) ).rgb; + sum += weight * tex2Doffset( colorSampler, tc, float2( -0.5, +1.5 ) ).rgb; + sum += weight * tex2Doffset( colorSampler, tc, float2( +1.5, +0.5 ) ).rgb; + return sum; +} + +half4 InterpolateDof( half3 small, half3 med, half3 large, half t ) +{ + //t = 2; + half4 weights; + half3 color; + half alpha; + + // Efficiently calculate the cross-blend weights for each sample. + // Let the unblurred sample to small blur fade happen over distance + // d0, the small to medium blur over distance d1, and the medium to + // large blur over distance d2, where d0 + d1 + d2 = 1. + //float4 dofLerpScale = float4( -1 / d0, -1 / d1, -1 / d2, 1 / d2 ); + //float4 dofLerpBias = float4( 1, (1 – d2) / d1, 1 / d2, (d2 – 1) / d2 ); + + weights = saturate( t * dofLerpScale + dofLerpBias ); + weights.yz = min( weights.yz, 1 - weights.xy ); + + // Unblurred sample with weight "weights.x" done by alpha blending + color = weights.y * small + weights.z * med + weights.w * large; + //color = med; + alpha = dot( weights.yzw, half3( 16.0 / 17, 1.0, 1.0 ) ); + //alpha = 0.0; + + return half4( color, alpha ); +} + +half4 main( PFXVertToPix IN ) : COLOR +{ + //return half4( 1,0,1,1 ); + //return half4( tex2D( colorSampler, IN.uv0 ).rgb, 1.0 ); + //return half4( tex2D( colorSampler, texCoords ).rgb, 0 ); + half3 small; + half4 med; + half3 large; + half depth; + half nearCoc; + half farCoc; + half coc; + + small = GetSmallBlurSample( IN.uv0 ); + //small = half3( 1,0,0 ); + //return half4( small, 1.0 ); + med = tex2D( smallBlurSampler, IN.uv1 ); + //med.rgb = half3( 0,1,0 ); + //return half4(med.rgb, 0.0); + large = tex2D( largeBlurSampler, IN.uv2 ).rgb; + //large = half3( 0,0,1 ); + //return large; + //return half4(large.rgb,1.0); + nearCoc = med.a; + + // Since the med blur texture is screwed up currently + // replace it with the large, but this needs to be fixed. + //med.rgb = large; + + //nearCoc = 0; + depth = prepassUncondition( depthSampler, float4( IN.uv3, 0, 0 ) ).w; + //return half4(depth.rrr,1); + //return half4(nearCoc.rrr,1.0); + + if (depth > 0.999 ) + { + coc = nearCoc; // We don't want to blur the sky. + //coc = 0; + } + else + { + // dofEqFar.x and dofEqFar.y specify the linear ramp to convert + // to depth for the distant out-of-focus region. + // dofEqFar.z is the ratio of the far to the near blur radius. + farCoc = clamp( dofEqFar.x * depth + dofEqFar.y, 0.0, maxFarCoC ); + coc = max( nearCoc, farCoc * dofEqFar.z ); + //coc = nearCoc; + } + + //coc = nearCoc; + //coc = farCoc; + //return half4(coc.rrr,0.5); + //return half4(farCoc.rrr,1); + //return half4(nearCoc.rrr,1); + + //return half4( 1,0,1,0 ); + return InterpolateDof( small, med.rgb, large, coc ); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/postFx/dof/DOF_Final_V.hlsl b/Templates/Empty/game/shaders/common/postFx/dof/DOF_Final_V.hlsl new file mode 100644 index 000000000..91dfba0a2 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/dof/DOF_Final_V.hlsl @@ -0,0 +1,72 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "./../postFx.hlsl" +#include "./../../torque.hlsl" + +uniform float4 rtParams0; +uniform float4 rtParams1; +uniform float4 rtParams2; +uniform float4 rtParams3; +uniform float2 oneOverTargetSize; + +PFXVertToPix main( PFXVert IN ) +{ + PFXVertToPix OUT; + + /* + OUT.hpos = IN.pos; + OUT.uv0 = IN.uv; + OUT.uv1 = IN.uv; + OUT.uv2 = IN.uv; + OUT.uv3 = IN.uv; + */ + + /* + OUT.hpos = IN.pos; + OUT.uv0 = IN.uv + rtParams0.xy; + OUT.uv1 = IN.uv + rtParams1.xy; + OUT.uv2 = IN.uv + rtParams2.xy; + OUT.uv3 = IN.uv + rtParams3.xy; + */ + + + /* + OUT.hpos = IN.pos; + OUT.uv0 = IN.uv * rtParams0.zw; + OUT.uv1 = IN.uv * rtParams1.zw; + OUT.uv2 = IN.uv * rtParams2.zw; + OUT.uv3 = IN.uv * rtParams3.zw; + */ + + + OUT.hpos = IN.pos; + OUT.uv0 = viewportCoordToRenderTarget( IN.uv, rtParams0 ); + OUT.uv1 = viewportCoordToRenderTarget( IN.uv, rtParams1 ); // + float2( -5, 1 ) * oneOverTargetSize; + OUT.uv2 = viewportCoordToRenderTarget( IN.uv, rtParams2 ); + OUT.uv3 = viewportCoordToRenderTarget( IN.uv, rtParams3 ); + + + OUT.wsEyeRay = IN.wsEyeRay; + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/postFx/dof/DOF_Gausian_P.hlsl b/Templates/Empty/game/shaders/common/postFx/dof/DOF_Gausian_P.hlsl new file mode 100644 index 000000000..084a2c014 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/dof/DOF_Gausian_P.hlsl @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "./../postFx.hlsl" + +uniform sampler2D diffuseMap : register(S0); + +struct VertToPix +{ + float4 hpos : POSITION; + + float2 uv0 : TEXCOORD0; + float2 uv1 : TEXCOORD1; + float2 uv2 : TEXCOORD2; + float2 uv3 : TEXCOORD3; + + float2 uv4 : TEXCOORD4; + float2 uv5 : TEXCOORD5; + float2 uv6 : TEXCOORD6; + float2 uv7 : TEXCOORD7; +}; + +float4 main( VertToPix IN ) : COLOR +{ + float4 kernel = float4( 0.175, 0.275, 0.375, 0.475 ) * 0.5 / 1.3; //25f; + + float4 OUT = 0; + OUT += tex2D( diffuseMap, IN.uv0 ) * kernel.x; + OUT += tex2D( diffuseMap, IN.uv1 ) * kernel.y; + OUT += tex2D( diffuseMap, IN.uv2 ) * kernel.z; + OUT += tex2D( diffuseMap, IN.uv3 ) * kernel.w; + + OUT += tex2D( diffuseMap, IN.uv4 ) * kernel.x; + OUT += tex2D( diffuseMap, IN.uv5 ) * kernel.y; + OUT += tex2D( diffuseMap, IN.uv6 ) * kernel.z; + OUT += tex2D( diffuseMap, IN.uv7 ) * kernel.w; + + // Calculate a lumenance value in the alpha so we + // can use alpha test to save fillrate. + //float3 rgb2lum = float3( 0.30, 0.59, 0.11 ); + //OUT.a = dot( OUT.rgb, rgb2lum ); + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/postFx/dof/DOF_Gausian_V.hlsl b/Templates/Empty/game/shaders/common/postFx/dof/DOF_Gausian_V.hlsl new file mode 100644 index 000000000..e29746e96 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/dof/DOF_Gausian_V.hlsl @@ -0,0 +1,80 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "./../postFx.hlsl" +#include "./../../torque.hlsl" + + +uniform float2 texSize0; +uniform float4 rtParams0; +uniform float2 oneOverTargetSize; + +struct VertToPix +{ + float4 hpos : POSITION; + + float2 uv0 : TEXCOORD0; + float2 uv1 : TEXCOORD1; + float2 uv2 : TEXCOORD2; + float2 uv3 : TEXCOORD3; + + float2 uv4 : TEXCOORD4; + float2 uv5 : TEXCOORD5; + float2 uv6 : TEXCOORD6; + float2 uv7 : TEXCOORD7; +}; + +VertToPix main( PFXVert IN ) +{ + VertToPix OUT; + + OUT.hpos = IN.pos; + + IN.uv = viewportCoordToRenderTarget( IN.uv, rtParams0 ); + + // I don't know why this offset is necessary, but it is. + //IN.uv = IN.uv * oneOverTargetSize; + + OUT.uv0 = IN.uv + ( ( BLUR_DIR * 3.5f ) / texSize0 ); + OUT.uv1 = IN.uv + ( ( BLUR_DIR * 2.5f ) / texSize0 ); + OUT.uv2 = IN.uv + ( ( BLUR_DIR * 1.5f ) / texSize0 ); + OUT.uv3 = IN.uv + ( ( BLUR_DIR * 0.5f ) / texSize0 ); + + OUT.uv4 = IN.uv - ( ( BLUR_DIR * 3.5f ) / texSize0 ); + OUT.uv5 = IN.uv - ( ( BLUR_DIR * 2.5f ) / texSize0 ); + OUT.uv6 = IN.uv - ( ( BLUR_DIR * 1.5f ) / texSize0 ); + OUT.uv7 = IN.uv - ( ( BLUR_DIR * 0.5f ) / texSize0 ); + + /* + OUT.uv0 = viewportCoordToRenderTarget( OUT.uv0, rtParams0 ); + OUT.uv1 = viewportCoordToRenderTarget( OUT.uv1, rtParams0 ); + OUT.uv2 = viewportCoordToRenderTarget( OUT.uv2, rtParams0 ); + OUT.uv3 = viewportCoordToRenderTarget( OUT.uv3, rtParams0 ); + + OUT.uv4 = viewportCoordToRenderTarget( OUT.uv4, rtParams0 ); + OUT.uv5 = viewportCoordToRenderTarget( OUT.uv5, rtParams0 ); + OUT.uv6 = viewportCoordToRenderTarget( OUT.uv6, rtParams0 ); + OUT.uv7 = viewportCoordToRenderTarget( OUT.uv7, rtParams0 ); + */ + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/postFx/dof/DOF_Passthrough_V.hlsl b/Templates/Empty/game/shaders/common/postFx/dof/DOF_Passthrough_V.hlsl new file mode 100644 index 000000000..40cec49de --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/dof/DOF_Passthrough_V.hlsl @@ -0,0 +1,70 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "./../postFx.hlsl" +#include "./../../torque.hlsl" + +uniform float4 rtParams0; +uniform float4 rtParams1; +uniform float4 rtParams2; +uniform float4 rtParams3; + +PFXVertToPix main( PFXVert IN ) +{ + PFXVertToPix OUT; + + /* + OUT.hpos = IN.pos; + OUT.uv0 = IN.uv; + OUT.uv1 = IN.uv; + OUT.uv2 = IN.uv; + OUT.uv3 = IN.uv; + */ + + /* + OUT.hpos = IN.pos; + OUT.uv0 = IN.uv + rtParams0.xy; + OUT.uv1 = IN.uv + rtParams1.xy; + OUT.uv2 = IN.uv + rtParams2.xy; + OUT.uv3 = IN.uv + rtParams3.xy; + */ + + /* + OUT.hpos = IN.pos; + OUT.uv0 = IN.uv * rtParams0.zw; + OUT.uv1 = IN.uv * rtParams1.zw; + OUT.uv2 = IN.uv * rtParams2.zw; + OUT.uv3 = IN.uv * rtParams3.zw; + */ + + + OUT.hpos = IN.pos; + OUT.uv0 = viewportCoordToRenderTarget( IN.uv, rtParams0 ); + OUT.uv1 = viewportCoordToRenderTarget( IN.uv, rtParams1 ); + OUT.uv2 = viewportCoordToRenderTarget( IN.uv, rtParams2 ); + OUT.uv3 = viewportCoordToRenderTarget( IN.uv, rtParams3 ); + + + OUT.wsEyeRay = IN.wsEyeRay; + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/postFx/dof/DOF_SmallBlur_P.hlsl b/Templates/Empty/game/shaders/common/postFx/dof/DOF_SmallBlur_P.hlsl new file mode 100644 index 000000000..6d4144576 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/dof/DOF_SmallBlur_P.hlsl @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// This vertex and pixel shader applies a 3 x 3 blur to the image in +// colorMapSampler, which is the same size as the render target. +// The sample weights are 1/16 in the corners, 2/16 on the edges, +// and 4/16 in the center. + +uniform sampler2D colorSampler; // Output of DofNearCoc() + +struct Pixel +{ + float4 position : POSITION; + float4 texCoords : TEXCOORD0; +}; + +float4 main( Pixel IN ) : COLOR +{ + float4 color; + color = 0.0; + color += tex2D( colorSampler, IN.texCoords.xz ); + color += tex2D( colorSampler, IN.texCoords.yz ); + color += tex2D( colorSampler, IN.texCoords.xw ); + color += tex2D( colorSampler, IN.texCoords.yw ); + return color / 4.0; +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/postFx/dof/DOF_SmallBlur_V.hlsl b/Templates/Empty/game/shaders/common/postFx/dof/DOF_SmallBlur_V.hlsl new file mode 100644 index 000000000..204f4639d --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/dof/DOF_SmallBlur_V.hlsl @@ -0,0 +1,56 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// This vertex and pixel shader applies a 3 x 3 blur to the image in +// colorMapSampler, which is the same size as the render target. +// The sample weights are 1/16 in the corners, 2/16 on the edges, +// and 4/16 in the center. + +#include "./../postFx.hlsl" +#include "./../../torque.hlsl" + +struct Vert +{ + float4 position : POSITION; + float2 texCoords : TEXCOORD0; +}; + +struct Pixel +{ + float4 position : POSITION; + float4 texCoords : TEXCOORD0; +}; + +uniform float2 oneOverTargetSize; +uniform float4 rtParams0; + +Pixel main( Vert IN ) +{ + Pixel OUT; + const float4 halfPixel = { -0.5, 0.5, -0.5, 0.5 }; + OUT.position = IN.position; //Transform_ObjectToClip( IN.position ); + + //float2 uv = IN.texCoords + rtParams0.xy; + float2 uv = viewportCoordToRenderTarget( IN.texCoords, rtParams0 ); + OUT.texCoords = uv.xxyy + halfPixel * oneOverTargetSize.xxyy; + return OUT; +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/postFx/edgeaa/dbgEdgeDisplayP.hlsl b/Templates/Empty/game/shaders/common/postFx/edgeaa/dbgEdgeDisplayP.hlsl new file mode 100644 index 000000000..90cf391dc --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/edgeaa/dbgEdgeDisplayP.hlsl @@ -0,0 +1,30 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "../postFx.hlsl" +#include "shadergen:/autogenConditioners.h" + +float4 main( PFXVertToPix IN, + uniform sampler2D edgeBuffer :register(S0) ) : COLOR0 +{ + return float4( tex2D( edgeBuffer, IN.uv0 ).rrr, 1.0 ); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/postFx/edgeaa/edgeAAP.hlsl b/Templates/Empty/game/shaders/common/postFx/edgeaa/edgeAAP.hlsl new file mode 100644 index 000000000..e45684199 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/edgeaa/edgeAAP.hlsl @@ -0,0 +1,66 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "../postFx.hlsl" +#include "shadergen:/autogenConditioners.h" + +float4 main( PFXVertToPix IN, + uniform sampler2D edgeBuffer : register(S0), + uniform sampler2D backBuffer : register(S1), + uniform float2 targetSize : register(C0) ) : COLOR0 +{ + float2 pixelSize = 1.0 / targetSize; + + // Sample edge buffer, bail if not on an edge + float edgeSample = tex2D(edgeBuffer, IN.uv0).r; + clip(edgeSample - 1e-6); + + // Ok we're on an edge, so multi-tap sample, average, and return + float2 offsets[9] = { + float2( 0.0, 0.0), + float2(-1.0, -1.0), + float2( 0.0, -1.0), + float2( 1.0, -1.0), + float2( 1.0, 0.0), + float2( 1.0, 1.0), + float2( 0.0, 1.0), + float2(-1.0, 1.0), + float2(-1.0, 0.0), + }; + + float4 accumColor = 0; + for(int i = 0; i < 9; i++) + { + // Multiply the intensity of the edge, by the UV, so that things which maybe + // aren't quite full edges get sub-pixel sampling to reduce artifacts + + // Scaling offsets by 0.5 to reduce the range bluriness from extending to + // far outward from the edge. + + float2 offsetUV = IN.uv1 + edgeSample * ( offsets[i] * 0.5 ) * pixelSize;//rtWidthHeightInvWidthNegHeight.zw; + //offsetUV *= 0.999; + accumColor+= tex2D(backBuffer, offsetUV); + } + accumColor /= 9.0; + + return accumColor; +} diff --git a/Templates/Empty/game/shaders/common/postFx/edgeaa/edgeAAV.hlsl b/Templates/Empty/game/shaders/common/postFx/edgeaa/edgeAAV.hlsl new file mode 100644 index 000000000..4718b40f5 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/edgeaa/edgeAAV.hlsl @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "./../postFx.hlsl" +#include "./../../torque.hlsl" + + +uniform float4 rtParams0; +uniform float4 rtParams1; +uniform float4 rtParams2; +uniform float4 rtParams3; + +PFXVertToPix main( PFXVert IN ) +{ + PFXVertToPix OUT; + + OUT.hpos = IN.pos; + OUT.uv0 = viewportCoordToRenderTarget( IN.uv, rtParams0 ); + OUT.uv1 = viewportCoordToRenderTarget( IN.uv, rtParams1 ); + OUT.uv2 = viewportCoordToRenderTarget( IN.uv, rtParams2 ); + OUT.uv3 = viewportCoordToRenderTarget( IN.uv, rtParams3 ); + + OUT.wsEyeRay = IN.wsEyeRay; + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/postFx/edgeaa/edgeDetectP.hlsl b/Templates/Empty/game/shaders/common/postFx/edgeaa/edgeDetectP.hlsl new file mode 100644 index 000000000..bc79516ee --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/edgeaa/edgeDetectP.hlsl @@ -0,0 +1,90 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "../postFx.hlsl" +#include "shadergen:/autogenConditioners.h" + +// GPU Gems 3, pg 443-444 +float GetEdgeWeight(float2 uv0, in sampler2D prepassBuffer, in float2 targetSize) +{ + float2 offsets[9] = { + float2( 0.0, 0.0), + float2(-1.0, -1.0), + float2( 0.0, -1.0), + float2( 1.0, -1.0), + float2( 1.0, 0.0), + float2( 1.0, 1.0), + float2( 0.0, 1.0), + float2(-1.0, 1.0), + float2(-1.0, 0.0), + }; + + + float2 PixelSize = 1.0 / targetSize; + + float Depth[9]; + float3 Normal[9]; + + for(int i = 0; i < 9; i++) + { + float2 uv = uv0 + offsets[i] * PixelSize; + float4 gbSample = prepassUncondition( prepassBuffer, uv ); + Depth[i] = gbSample.a; + Normal[i] = gbSample.rgb; + } + + float4 Deltas1 = float4(Depth[1], Depth[2], Depth[3], Depth[4]); + float4 Deltas2 = float4(Depth[5], Depth[6], Depth[7], Depth[8]); + + Deltas1 = abs(Deltas1 - Depth[0]); + Deltas2 = abs(Depth[0] - Deltas2); + + float4 maxDeltas = max(Deltas1, Deltas2); + float4 minDeltas = max(min(Deltas1, Deltas2), 0.00001); + + float4 depthResults = step(minDeltas * 25.0, maxDeltas); + + Deltas1.x = dot(Normal[1], Normal[0]); + Deltas1.y = dot(Normal[2], Normal[0]); + Deltas1.z = dot(Normal[3], Normal[0]); + Deltas1.w = dot(Normal[4], Normal[0]); + + Deltas2.x = dot(Normal[5], Normal[0]); + Deltas2.y = dot(Normal[6], Normal[0]); + Deltas2.z = dot(Normal[7], Normal[0]); + Deltas2.w = dot(Normal[8], Normal[0]); + + Deltas1 = abs(Deltas1 - Deltas2); + + float4 normalResults = step(0.4, Deltas1); + + normalResults = max(normalResults, depthResults); + + return dot(normalResults, float4(1.0, 1.0, 1.0, 1.0)) * 0.25; +} + +float4 main( PFXVertToPix IN, + uniform sampler2D prepassBuffer :register(S0), + uniform float2 targetSize : register(C0) ) : COLOR0 +{ + return GetEdgeWeight(IN.uv0, prepassBuffer, targetSize );//rtWidthHeightInvWidthNegHeight.zw); +} diff --git a/Templates/Empty/game/shaders/common/postFx/flashP.hlsl b/Templates/Empty/game/shaders/common/postFx/flashP.hlsl new file mode 100644 index 000000000..3d9c6c744 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/flashP.hlsl @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "./postFx.hlsl" +#include "../torque.hlsl" + +uniform float damageFlash; +uniform float whiteOut; +uniform sampler2D backBuffer : register(S0); + +float4 main(PFXVertToPix IN) : COLOR0 +{ + float4 color1 = tex2D(backBuffer, IN.uv0); + float4 color2 = color1 * MUL_COLOR; + float4 damage = lerp(color1,color2,damageFlash); + return lerp(damage,WHITE_COLOR,whiteOut); +} diff --git a/Templates/Empty/game/shaders/common/postFx/fogP.hlsl b/Templates/Empty/game/shaders/common/postFx/fogP.hlsl new file mode 100644 index 000000000..5e69e72ba --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/fogP.hlsl @@ -0,0 +1,50 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" +#include "./postFx.hlsl" +#include "./../torque.hlsl" + +uniform sampler2D prepassTex : register(S0); +uniform float3 eyePosWorld; +uniform float4 fogColor; +uniform float3 fogData; +uniform float4 rtParams0; + +float4 main( PFXVertToPix IN ) : COLOR +{ + //float2 prepassCoord = ( IN.uv0.xy * rtParams0.zw ) + rtParams0.xy; + float depth = prepassUncondition( prepassTex, IN.uv0 ).w; + //return float4( depth, 0, 0, 0.7 ); + + // Skip fogging the extreme far plane so that + // the canvas clear color always appears. + clip( 0.9999 - depth ); + + float factor = computeSceneFog( eyePosWorld, + eyePosWorld + ( IN.wsEyeRay * depth ), + fogData.x, + fogData.y, + fogData.z ); + + return hdrEncode( float4( fogColor.rgb, 1.0 - saturate( factor ) ) ); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/postFx/fxaa/Fxaa3_11.h b/Templates/Empty/game/shaders/common/postFx/fxaa/Fxaa3_11.h new file mode 100644 index 000000000..92a373740 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/fxaa/Fxaa3_11.h @@ -0,0 +1,2047 @@ +/*============================================================================ + + + NVIDIA FXAA 3.11 by TIMOTHY LOTTES + + +------------------------------------------------------------------------------ +COPYRIGHT (C) 2010, 2011 NVIDIA CORPORATION. ALL RIGHTS RESERVED. +------------------------------------------------------------------------------ +TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED +*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA +OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR +CONSEQUENTIAL 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 SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + +------------------------------------------------------------------------------ + INTEGRATION CHECKLIST +------------------------------------------------------------------------------ +(1.) +In the shader source, setup defines for the desired configuration. +When providing multiple shaders (for different presets), +simply setup the defines differently in multiple files. +Example, + + #define FXAA_PC 1 + #define FXAA_HLSL_5 1 + #define FXAA_QUALITY__PRESET 12 + +Or, + + #define FXAA_360 1 + +Or, + + #define FXAA_PS3 1 + +Etc. + +(2.) +Then include this file, + + #include "Fxaa3_11.h" + +(3.) +Then call the FXAA pixel shader from within your desired shader. +Look at the FXAA Quality FxaaPixelShader() for docs on inputs. +As for FXAA 3.11 all inputs for all shaders are the same +to enable easy porting between platforms. + + return FxaaPixelShader(...); + +(4.) +Insure pass prior to FXAA outputs RGBL (see next section). +Or use, + + #define FXAA_GREEN_AS_LUMA 1 + +(5.) +Setup engine to provide the following constants +which are used in the FxaaPixelShader() inputs, + + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir + +Look at the FXAA Quality FxaaPixelShader() for docs on inputs. + +(6.) +Have FXAA vertex shader run as a full screen triangle, +and output "pos" and "fxaaConsolePosPos" +such that inputs in the pixel shader provide, + + // {xy} = center of pixel + FxaaFloat2 pos, + + // {xy__} = upper left of pixel + // {__zw} = lower right of pixel + FxaaFloat4 fxaaConsolePosPos, + +(7.) +Insure the texture sampler(s) used by FXAA are set to bilinear filtering. + + +------------------------------------------------------------------------------ + INTEGRATION - RGBL AND COLORSPACE +------------------------------------------------------------------------------ +FXAA3 requires RGBL as input unless the following is set, + + #define FXAA_GREEN_AS_LUMA 1 + +In which case the engine uses green in place of luma, +and requires RGB input is in a non-linear colorspace. + +RGB should be LDR (low dynamic range). +Specifically do FXAA after tonemapping. + +RGB data as returned by a texture fetch can be non-linear, +or linear when FXAA_GREEN_AS_LUMA is not set. +Note an "sRGB format" texture counts as linear, +because the result of a texture fetch is linear data. +Regular "RGBA8" textures in the sRGB colorspace are non-linear. + +If FXAA_GREEN_AS_LUMA is not set, +luma must be stored in the alpha channel prior to running FXAA. +This luma should be in a perceptual space (could be gamma 2.0). +Example pass before FXAA where output is gamma 2.0 encoded, + + color.rgb = ToneMap(color.rgb); // linear color output + color.rgb = sqrt(color.rgb); // gamma 2.0 color output + return color; + +To use FXAA, + + color.rgb = ToneMap(color.rgb); // linear color output + color.rgb = sqrt(color.rgb); // gamma 2.0 color output + color.a = dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114)); // compute luma + return color; + +Another example where output is linear encoded, +say for instance writing to an sRGB formated render target, +where the render target does the conversion back to sRGB after blending, + + color.rgb = ToneMap(color.rgb); // linear color output + return color; + +To use FXAA, + + color.rgb = ToneMap(color.rgb); // linear color output + color.a = sqrt(dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114))); // compute luma + return color; + +Getting luma correct is required for the algorithm to work correctly. + + +------------------------------------------------------------------------------ + BEING LINEARLY CORRECT? +------------------------------------------------------------------------------ +Applying FXAA to a framebuffer with linear RGB color will look worse. +This is very counter intuitive, but happends to be true in this case. +The reason is because dithering artifacts will be more visiable +in a linear colorspace. + + +------------------------------------------------------------------------------ + COMPLEX INTEGRATION +------------------------------------------------------------------------------ +Q. What if the engine is blending into RGB before wanting to run FXAA? + +A. In the last opaque pass prior to FXAA, + have the pass write out luma into alpha. + Then blend into RGB only. + FXAA should be able to run ok + assuming the blending pass did not any add aliasing. + This should be the common case for particles and common blending passes. + +A. Or use FXAA_GREEN_AS_LUMA. + +============================================================================*/ + +/*============================================================================ + + INTEGRATION KNOBS + +============================================================================*/ +// +// FXAA_PS3 and FXAA_360 choose the console algorithm (FXAA3 CONSOLE). +// FXAA_360_OPT is a prototype for the new optimized 360 version. +// +// 1 = Use API. +// 0 = Don't use API. +// +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_PS3 + #define FXAA_PS3 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_360 + #define FXAA_360 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_360_OPT + #define FXAA_360_OPT 0 +#endif +/*==========================================================================*/ +#ifndef FXAA_PC + // + // FXAA Quality + // The high quality PC algorithm. + // + #define FXAA_PC 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_PC_CONSOLE + // + // The console algorithm for PC is included + // for developers targeting really low spec machines. + // Likely better to just run FXAA_PC, and use a really low preset. + // + #define FXAA_PC_CONSOLE 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GLSL_120 + #define FXAA_GLSL_120 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GLSL_130 + #define FXAA_GLSL_130 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_3 + #define FXAA_HLSL_3 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_4 + #define FXAA_HLSL_4 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_5 + #define FXAA_HLSL_5 0 +#endif +/*==========================================================================*/ +#ifndef FXAA_GREEN_AS_LUMA + // + // For those using non-linear color, + // and either not able to get luma in alpha, or not wanting to, + // this enables FXAA to run using green as a proxy for luma. + // So with this enabled, no need to pack luma in alpha. + // + // This will turn off AA on anything which lacks some amount of green. + // Pure red and blue or combination of only R and B, will get no AA. + // + // Might want to lower the settings for both, + // fxaaConsoleEdgeThresholdMin + // fxaaQualityEdgeThresholdMin + // In order to insure AA does not get turned off on colors + // which contain a minor amount of green. + // + // 1 = On. + // 0 = Off. + // + #define FXAA_GREEN_AS_LUMA 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_EARLY_EXIT + // + // Controls algorithm's early exit path. + // On PS3 turning this ON adds 2 cycles to the shader. + // On 360 turning this OFF adds 10ths of a millisecond to the shader. + // Turning this off on console will result in a more blurry image. + // So this defaults to on. + // + // 1 = On. + // 0 = Off. + // + #define FXAA_EARLY_EXIT 1 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_DISCARD + // + // Only valid for PC OpenGL currently. + // Probably will not work when FXAA_GREEN_AS_LUMA = 1. + // + // 1 = Use discard on pixels which don't need AA. + // For APIs which enable concurrent TEX+ROP from same surface. + // 0 = Return unchanged color on pixels which don't need AA. + // + #define FXAA_DISCARD 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_FAST_PIXEL_OFFSET + // + // Used for GLSL 120 only. + // + // 1 = GL API supports fast pixel offsets + // 0 = do not use fast pixel offsets + // + #ifdef GL_EXT_gpu_shader4 + #define FXAA_FAST_PIXEL_OFFSET 1 + #endif + #ifdef GL_NV_gpu_shader5 + #define FXAA_FAST_PIXEL_OFFSET 1 + #endif + #ifdef GL_ARB_gpu_shader5 + #define FXAA_FAST_PIXEL_OFFSET 1 + #endif + #ifndef FXAA_FAST_PIXEL_OFFSET + #define FXAA_FAST_PIXEL_OFFSET 0 + #endif +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GATHER4_ALPHA + // + // 1 = API supports gather4 on alpha channel. + // 0 = API does not support gather4 on alpha channel. + // + #if (FXAA_HLSL_5 == 1) + #define FXAA_GATHER4_ALPHA 1 + #endif + #ifdef GL_ARB_gpu_shader5 + #define FXAA_GATHER4_ALPHA 1 + #endif + #ifdef GL_NV_gpu_shader5 + #define FXAA_GATHER4_ALPHA 1 + #endif + #ifndef FXAA_GATHER4_ALPHA + #define FXAA_GATHER4_ALPHA 0 + #endif +#endif + +/*============================================================================ + FXAA CONSOLE PS3 - TUNING KNOBS +============================================================================*/ +#ifndef FXAA_CONSOLE__PS3_EDGE_SHARPNESS + // + // Consoles the sharpness of edges on PS3 only. + // Non-PS3 tuning is done with shader input. + // + // Due to the PS3 being ALU bound, + // there are only two safe values here: 4 and 8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // + // 8.0 is sharper + // 4.0 is softer + // 2.0 is really soft (good for vector graphics inputs) + // + #if 1 + #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 8.0 + #endif + #if 0 + #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 4.0 + #endif + #if 0 + #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 2.0 + #endif +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_CONSOLE__PS3_EDGE_THRESHOLD + // + // Only effects PS3. + // Non-PS3 tuning is done with shader input. + // + // The minimum amount of local contrast required to apply algorithm. + // The console setting has a different mapping than the quality setting. + // + // This only applies when FXAA_EARLY_EXIT is 1. + // + // Due to the PS3 being ALU bound, + // there are only two safe values here: 0.25 and 0.125. + // These options use the shaders ability to a free *|/ by 2|4|8. + // + // 0.125 leaves less aliasing, but is softer + // 0.25 leaves more aliasing, and is sharper + // + #if 1 + #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.125 + #else + #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.25 + #endif +#endif + +/*============================================================================ + FXAA QUALITY - TUNING KNOBS +------------------------------------------------------------------------------ +NOTE the other tuning knobs are now in the shader function inputs! +============================================================================*/ +#ifndef FXAA_QUALITY__PRESET + // + // Choose the quality preset. + // This needs to be compiled into the shader as it effects code. + // Best option to include multiple presets is to + // in each shader define the preset, then include this file. + // + // OPTIONS + // ----------------------------------------------------------------------- + // 10 to 15 - default medium dither (10=fastest, 15=highest quality) + // 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality) + // 39 - no dither, very expensive + // + // NOTES + // ----------------------------------------------------------------------- + // 12 = slightly faster then FXAA 3.9 and higher edge quality (default) + // 13 = about same speed as FXAA 3.9 and better than 12 + // 23 = closest to FXAA 3.9 visually and performance wise + // _ = the lowest digit is directly related to performance + // _ = the highest digit is directly related to style + // + #define FXAA_QUALITY__PRESET 12 +#endif + + +/*============================================================================ + + FXAA QUALITY - PRESETS + +============================================================================*/ + +/*============================================================================ + FXAA QUALITY - MEDIUM DITHER PRESETS +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 10) + #define FXAA_QUALITY__PS 3 + #define FXAA_QUALITY__P0 1.5 + #define FXAA_QUALITY__P1 3.0 + #define FXAA_QUALITY__P2 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 11) + #define FXAA_QUALITY__PS 4 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 3.0 + #define FXAA_QUALITY__P3 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 12) + #define FXAA_QUALITY__PS 5 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 4.0 + #define FXAA_QUALITY__P4 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 13) + #define FXAA_QUALITY__PS 6 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 4.0 + #define FXAA_QUALITY__P5 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 14) + #define FXAA_QUALITY__PS 7 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 4.0 + #define FXAA_QUALITY__P6 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 15) + #define FXAA_QUALITY__PS 8 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 4.0 + #define FXAA_QUALITY__P7 12.0 +#endif + +/*============================================================================ + FXAA QUALITY - LOW DITHER PRESETS +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 20) + #define FXAA_QUALITY__PS 3 + #define FXAA_QUALITY__P0 1.5 + #define FXAA_QUALITY__P1 2.0 + #define FXAA_QUALITY__P2 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 21) + #define FXAA_QUALITY__PS 4 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 22) + #define FXAA_QUALITY__PS 5 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 23) + #define FXAA_QUALITY__PS 6 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 24) + #define FXAA_QUALITY__PS 7 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 3.0 + #define FXAA_QUALITY__P6 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 25) + #define FXAA_QUALITY__PS 8 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 4.0 + #define FXAA_QUALITY__P7 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 26) + #define FXAA_QUALITY__PS 9 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 4.0 + #define FXAA_QUALITY__P8 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 27) + #define FXAA_QUALITY__PS 10 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 4.0 + #define FXAA_QUALITY__P9 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 28) + #define FXAA_QUALITY__PS 11 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 2.0 + #define FXAA_QUALITY__P9 4.0 + #define FXAA_QUALITY__P10 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 29) + #define FXAA_QUALITY__PS 12 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 2.0 + #define FXAA_QUALITY__P9 2.0 + #define FXAA_QUALITY__P10 4.0 + #define FXAA_QUALITY__P11 8.0 +#endif + +/*============================================================================ + FXAA QUALITY - EXTREME QUALITY +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 39) + #define FXAA_QUALITY__PS 12 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.0 + #define FXAA_QUALITY__P2 1.0 + #define FXAA_QUALITY__P3 1.0 + #define FXAA_QUALITY__P4 1.0 + #define FXAA_QUALITY__P5 1.5 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 2.0 + #define FXAA_QUALITY__P9 2.0 + #define FXAA_QUALITY__P10 4.0 + #define FXAA_QUALITY__P11 8.0 +#endif + + + +/*============================================================================ + + API PORTING + +============================================================================*/ +#if (FXAA_GLSL_120 == 1) || (FXAA_GLSL_130 == 1) + #define FxaaBool bool + #define FxaaDiscard discard + #define FxaaFloat float + #define FxaaFloat2 vec2 + #define FxaaFloat3 vec3 + #define FxaaFloat4 vec4 + #define FxaaHalf float + #define FxaaHalf2 vec2 + #define FxaaHalf3 vec3 + #define FxaaHalf4 vec4 + #define FxaaInt2 ivec2 + #define FxaaSat(x) clamp(x, 0.0, 1.0) + #define FxaaTex sampler2D +#else + #define FxaaBool bool + #define FxaaDiscard clip(-1) + #define FxaaFloat float + #define FxaaFloat2 float2 + #define FxaaFloat3 float3 + #define FxaaFloat4 float4 + #define FxaaHalf half + #define FxaaHalf2 half2 + #define FxaaHalf3 half3 + #define FxaaHalf4 half4 + #define FxaaSat(x) saturate(x) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_GLSL_120 == 1) + // Requires, + // #version 120 + // And at least, + // #extension GL_EXT_gpu_shader4 : enable + // (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9) + #define FxaaTexTop(t, p) texture2DLod(t, p, 0.0) + #if (FXAA_FAST_PIXEL_OFFSET == 1) + #define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o) + #else + #define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0) + #endif + #if (FXAA_GATHER4_ALPHA == 1) + // use #extension GL_ARB_gpu_shader5 : enable + #define FxaaTexAlpha4(t, p) textureGather(t, p, 3) + #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3) + #define FxaaTexGreen4(t, p) textureGather(t, p, 1) + #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1) + #endif +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_GLSL_130 == 1) + // Requires "#version 130" or better + #define FxaaTexTop(t, p) textureLod(t, p, 0.0) + #define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o) + #if (FXAA_GATHER4_ALPHA == 1) + // use #extension GL_ARB_gpu_shader5 : enable + #define FxaaTexAlpha4(t, p) textureGather(t, p, 3) + #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3) + #define FxaaTexGreen4(t, p) textureGather(t, p, 1) + #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1) + #endif +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_3 == 1) || (FXAA_360 == 1) || (FXAA_PS3 == 1) + #define FxaaInt2 float2 + #define FxaaTex sampler2D + #define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0)) + #define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0)) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_4 == 1) + #define FxaaInt2 int2 + struct FxaaTex { SamplerState smpl; Texture2D tex; }; + #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0) + #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_5 == 1) + #define FxaaInt2 int2 + struct FxaaTex { SamplerState smpl; Texture2D tex; }; + #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0) + #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o) + #define FxaaTexAlpha4(t, p) t.tex.GatherAlpha(t.smpl, p) + #define FxaaTexOffAlpha4(t, p, o) t.tex.GatherAlpha(t.smpl, p, o) + #define FxaaTexGreen4(t, p) t.tex.GatherGreen(t.smpl, p) + #define FxaaTexOffGreen4(t, p, o) t.tex.GatherGreen(t.smpl, p, o) +#endif + + +/*============================================================================ + GREEN AS LUMA OPTION SUPPORT FUNCTION +============================================================================*/ +#if (FXAA_GREEN_AS_LUMA == 0) + FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.w; } +#else + FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; } +#endif + + + + +/*============================================================================ + + FXAA3 QUALITY - PC + +============================================================================*/ +#if (FXAA_PC == 1) +/*--------------------------------------------------------------------------*/ +FxaaFloat4 FxaaPixelShader( + // + // Use noperspective interpolation here (turn off perspective interpolation). + // {xy} = center of pixel + FxaaFloat2 pos, + // + // Used only for FXAA Console, and not used on the 360 version. + // Use noperspective interpolation here (turn off perspective interpolation). + // {xy__} = upper left of pixel + // {__zw} = lower right of pixel + FxaaFloat4 fxaaConsolePosPos, + // + // Input color texture. + // {rgb_} = color in linear or perceptual color space + // if (FXAA_GREEN_AS_LUMA == 0) + // {___a} = luma in perceptual color space (not linear) + FxaaTex tex, + // + // Only used on the optimized 360 version of FXAA Console. + // For everything but 360, just use the same input here as for "tex". + // For 360, same texture, just alias with a 2nd sampler. + // This sampler needs to have an exponent bias of -1. + FxaaTex fxaaConsole360TexExpBiasNegOne, + // + // Only used on the optimized 360 version of FXAA Console. + // For everything but 360, just use the same input here as for "tex". + // For 360, same texture, just alias with a 3nd sampler. + // This sampler needs to have an exponent bias of -2. + FxaaTex fxaaConsole360TexExpBiasNegTwo, + // + // Only used on FXAA Quality. + // This must be from a constant/uniform. + // {x_} = 1.0/screenWidthInPixels + // {_y} = 1.0/screenHeightInPixels + FxaaFloat2 fxaaQualityRcpFrame, + // + // Only used on FXAA Console. + // This must be from a constant/uniform. + // This effects sub-pixel AA quality and inversely sharpness. + // Where N ranges between, + // N = 0.50 (default) + // N = 0.33 (sharper) + // {x___} = -N/screenWidthInPixels + // {_y__} = -N/screenHeightInPixels + // {__z_} = N/screenWidthInPixels + // {___w} = N/screenHeightInPixels + FxaaFloat4 fxaaConsoleRcpFrameOpt, + // + // Only used on FXAA Console. + // Not used on 360, but used on PS3 and PC. + // This must be from a constant/uniform. + // {x___} = -2.0/screenWidthInPixels + // {_y__} = -2.0/screenHeightInPixels + // {__z_} = 2.0/screenWidthInPixels + // {___w} = 2.0/screenHeightInPixels + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + // + // Only used on FXAA Console. + // Only used on 360 in place of fxaaConsoleRcpFrameOpt2. + // This must be from a constant/uniform. + // {x___} = 8.0/screenWidthInPixels + // {_y__} = 8.0/screenHeightInPixels + // {__z_} = -4.0/screenWidthInPixels + // {___w} = -4.0/screenHeightInPixels + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__SUBPIX define. + // It is here now to allow easier tuning. + // Choose the amount of sub-pixel aliasing removal. + // This can effect sharpness. + // 1.00 - upper limit (softer) + // 0.75 - default amount of filtering + // 0.50 - lower limit (sharper, less sub-pixel aliasing removal) + // 0.25 - almost off + // 0.00 - completely off + FxaaFloat fxaaQualitySubpix, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD define. + // It is here now to allow easier tuning. + // The minimum amount of local contrast required to apply algorithm. + // 0.333 - too little (faster) + // 0.250 - low quality + // 0.166 - default + // 0.125 - high quality + // 0.063 - overkill (slower) + FxaaFloat fxaaQualityEdgeThreshold, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD_MIN define. + // It is here now to allow easier tuning. + // Trims the algorithm from processing darks. + // 0.0833 - upper limit (default, the start of visible unfiltered edges) + // 0.0625 - high quality (faster) + // 0.0312 - visible limit (slower) + // Special notes when using FXAA_GREEN_AS_LUMA, + // Likely want to set this to zero. + // As colors that are mostly not-green + // will appear very dark in the green channel! + // Tune by looking at mostly non-green content, + // then start at zero and increase until aliasing is a problem. + FxaaFloat fxaaQualityEdgeThresholdMin, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define. + // It is here now to allow easier tuning. + // This does not effect PS3, as this needs to be compiled in. + // Use FXAA_CONSOLE__PS3_EDGE_SHARPNESS for PS3. + // Due to the PS3 being ALU bound, + // there are only three safe values here: 2 and 4 and 8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // For all other platforms can be a non-power of two. + // 8.0 is sharper (default!!!) + // 4.0 is softer + // 2.0 is really soft (good only for vector graphics inputs) + FxaaFloat fxaaConsoleEdgeSharpness, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD define. + // It is here now to allow easier tuning. + // This does not effect PS3, as this needs to be compiled in. + // Use FXAA_CONSOLE__PS3_EDGE_THRESHOLD for PS3. + // Due to the PS3 being ALU bound, + // there are only two safe values here: 1/4 and 1/8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // The console setting has a different mapping than the quality setting. + // Other platforms can use other values. + // 0.125 leaves less aliasing, but is softer (default!!!) + // 0.25 leaves more aliasing, and is sharper + FxaaFloat fxaaConsoleEdgeThreshold, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD_MIN define. + // It is here now to allow easier tuning. + // Trims the algorithm from processing darks. + // The console setting has a different mapping than the quality setting. + // This only applies when FXAA_EARLY_EXIT is 1. + // This does not apply to PS3, + // PS3 was simplified to avoid more shader instructions. + // 0.06 - faster but more aliasing in darks + // 0.05 - default + // 0.04 - slower and less aliasing in darks + // Special notes when using FXAA_GREEN_AS_LUMA, + // Likely want to set this to zero. + // As colors that are mostly not-green + // will appear very dark in the green channel! + // Tune by looking at mostly non-green content, + // then start at zero and increase until aliasing is a problem. + FxaaFloat fxaaConsoleEdgeThresholdMin, + // + // Extra constants for 360 FXAA Console only. + // Use zeros or anything else for other platforms. + // These must be in physical constant registers and NOT immedates. + // Immedates will result in compiler un-optimizing. + // {xyzw} = float4(1.0, -1.0, 0.25, -0.25) + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ + FxaaFloat2 posM; + posM.x = pos.x; + posM.y = pos.y; + #if (FXAA_GATHER4_ALPHA == 1) + #if (FXAA_DISCARD == 0) + FxaaFloat4 rgbyM = FxaaTexTop(tex, posM); + #if (FXAA_GREEN_AS_LUMA == 0) + #define lumaM rgbyM.w + #else + #define lumaM rgbyM.y + #endif + #endif + #if (FXAA_GREEN_AS_LUMA == 0) + FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM); + FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1)); + #else + FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM); + FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1)); + #endif + #if (FXAA_DISCARD == 1) + #define lumaM luma4A.w + #endif + #define lumaE luma4A.z + #define lumaS luma4A.x + #define lumaSE luma4A.y + #define lumaNW luma4B.w + #define lumaN luma4B.z + #define lumaW luma4B.x + #else + FxaaFloat4 rgbyM = FxaaTexTop(tex, posM); + #if (FXAA_GREEN_AS_LUMA == 0) + #define lumaM rgbyM.w + #else + #define lumaM rgbyM.y + #endif + FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy)); + #endif +/*--------------------------------------------------------------------------*/ + FxaaFloat maxSM = max(lumaS, lumaM); + FxaaFloat minSM = min(lumaS, lumaM); + FxaaFloat maxESM = max(lumaE, maxSM); + FxaaFloat minESM = min(lumaE, minSM); + FxaaFloat maxWN = max(lumaN, lumaW); + FxaaFloat minWN = min(lumaN, lumaW); + FxaaFloat rangeMax = max(maxWN, maxESM); + FxaaFloat rangeMin = min(minWN, minESM); + FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold; + FxaaFloat range = rangeMax - rangeMin; + FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled); + FxaaBool earlyExit = range < rangeMaxClamped; +/*--------------------------------------------------------------------------*/ + if(earlyExit) + #if (FXAA_DISCARD == 1) + FxaaDiscard; + #else + return rgbyM; + #endif +/*--------------------------------------------------------------------------*/ + #if (FXAA_GATHER4_ALPHA == 0) + FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy)); + #else + FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy)); + #endif +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNS = lumaN + lumaS; + FxaaFloat lumaWE = lumaW + lumaE; + FxaaFloat subpixRcpRange = 1.0/range; + FxaaFloat subpixNSWE = lumaNS + lumaWE; + FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS; + FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE; +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNESE = lumaNE + lumaSE; + FxaaFloat lumaNWNE = lumaNW + lumaNE; + FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE; + FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE; +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNWSW = lumaNW + lumaSW; + FxaaFloat lumaSWSE = lumaSW + lumaSE; + FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2); + FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2); + FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW; + FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE; + FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4; + FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4; +/*--------------------------------------------------------------------------*/ + FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE; + FxaaFloat lengthSign = fxaaQualityRcpFrame.x; + FxaaBool horzSpan = edgeHorz >= edgeVert; + FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE; +/*--------------------------------------------------------------------------*/ + if(!horzSpan) lumaN = lumaW; + if(!horzSpan) lumaS = lumaE; + if(horzSpan) lengthSign = fxaaQualityRcpFrame.y; + FxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM; +/*--------------------------------------------------------------------------*/ + FxaaFloat gradientN = lumaN - lumaM; + FxaaFloat gradientS = lumaS - lumaM; + FxaaFloat lumaNN = lumaN + lumaM; + FxaaFloat lumaSS = lumaS + lumaM; + FxaaBool pairN = abs(gradientN) >= abs(gradientS); + FxaaFloat gradient = max(abs(gradientN), abs(gradientS)); + if(pairN) lengthSign = -lengthSign; + FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange); +/*--------------------------------------------------------------------------*/ + FxaaFloat2 posB; + posB.x = posM.x; + posB.y = posM.y; + FxaaFloat2 offNP; + offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x; + offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y; + if(!horzSpan) posB.x += lengthSign * 0.5; + if( horzSpan) posB.y += lengthSign * 0.5; +/*--------------------------------------------------------------------------*/ + FxaaFloat2 posN; + posN.x = posB.x - offNP.x * FXAA_QUALITY__P0; + posN.y = posB.y - offNP.y * FXAA_QUALITY__P0; + FxaaFloat2 posP; + posP.x = posB.x + offNP.x * FXAA_QUALITY__P0; + posP.y = posB.y + offNP.y * FXAA_QUALITY__P0; + FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0; + FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN)); + FxaaFloat subpixE = subpixC * subpixC; + FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP)); +/*--------------------------------------------------------------------------*/ + if(!pairN) lumaNN = lumaSS; + FxaaFloat gradientScaled = gradient * 1.0/4.0; + FxaaFloat lumaMM = lumaM - lumaNN * 0.5; + FxaaFloat subpixF = subpixD * subpixE; + FxaaBool lumaMLTZero = lumaMM < 0.0; +/*--------------------------------------------------------------------------*/ + lumaEndN -= lumaNN * 0.5; + lumaEndP -= lumaNN * 0.5; + FxaaBool doneN = abs(lumaEndN) >= gradientScaled; + FxaaBool doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P1; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P1; + FxaaBool doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P1; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P1; +/*--------------------------------------------------------------------------*/ + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P2; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P2; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P2; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P2; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 3) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P3; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P3; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P3; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P3; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 4) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P4; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P4; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P4; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P4; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 5) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P5; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P5; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P5; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P5; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 6) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P6; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P6; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P6; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P6; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 7) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P7; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P7; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P7; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P7; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 8) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P8; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P8; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P8; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P8; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 9) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P9; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P9; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P9; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P9; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 10) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P10; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P10; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P10; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P10; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 11) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P11; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P11; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P11; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P11; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 12) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P12; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P12; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P12; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P12; +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } +/*--------------------------------------------------------------------------*/ + FxaaFloat dstN = posM.x - posN.x; + FxaaFloat dstP = posP.x - posM.x; + if(!horzSpan) dstN = posM.y - posN.y; + if(!horzSpan) dstP = posP.y - posM.y; +/*--------------------------------------------------------------------------*/ + FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero; + FxaaFloat spanLength = (dstP + dstN); + FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero; + FxaaFloat spanLengthRcp = 1.0/spanLength; +/*--------------------------------------------------------------------------*/ + FxaaBool directionN = dstN < dstP; + FxaaFloat dst = min(dstN, dstP); + FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP; + FxaaFloat subpixG = subpixF * subpixF; + FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5; + FxaaFloat subpixH = subpixG * fxaaQualitySubpix; +/*--------------------------------------------------------------------------*/ + FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0; + FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH); + if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign; + if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign; + #if (FXAA_DISCARD == 1) + return FxaaTexTop(tex, posM); + #else + return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM); + #endif +} +/*==========================================================================*/ +#endif + + + + +/*============================================================================ + + FXAA3 CONSOLE - PC VERSION + +------------------------------------------------------------------------------ +Instead of using this on PC, I'd suggest just using FXAA Quality with + #define FXAA_QUALITY__PRESET 10 +Or + #define FXAA_QUALITY__PRESET 20 +Either are higher qualilty and almost as fast as this on modern PC GPUs. +============================================================================*/ +#if (FXAA_PC_CONSOLE == 1) +/*--------------------------------------------------------------------------*/ +FxaaFloat4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + FxaaFloat2 pos, + FxaaFloat4 fxaaConsolePosPos, + FxaaTex tex, + FxaaTex fxaaConsole360TexExpBiasNegOne, + FxaaTex fxaaConsole360TexExpBiasNegTwo, + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xy)); + FxaaFloat lumaSw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xw)); + FxaaFloat lumaNe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zy)); + FxaaFloat lumaSe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zw)); +/*--------------------------------------------------------------------------*/ + FxaaFloat4 rgbyM = FxaaTexTop(tex, pos.xy); + #if (FXAA_GREEN_AS_LUMA == 0) + FxaaFloat lumaM = rgbyM.w; + #else + FxaaFloat lumaM = rgbyM.y; + #endif +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMaxNwSw = max(lumaNw, lumaSw); + lumaNe += 1.0/384.0; + FxaaFloat lumaMinNwSw = min(lumaNw, lumaSw); +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMaxNeSe = max(lumaNe, lumaSe); + FxaaFloat lumaMinNeSe = min(lumaNe, lumaSe); +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMax = max(lumaMaxNeSe, lumaMaxNwSw); + FxaaFloat lumaMin = min(lumaMinNeSe, lumaMinNwSw); +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMaxScaled = lumaMax * fxaaConsoleEdgeThreshold; +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMinM = min(lumaMin, lumaM); + FxaaFloat lumaMaxScaledClamped = max(fxaaConsoleEdgeThresholdMin, lumaMaxScaled); + FxaaFloat lumaMaxM = max(lumaMax, lumaM); + FxaaFloat dirSwMinusNe = lumaSw - lumaNe; + FxaaFloat lumaMaxSubMinM = lumaMaxM - lumaMinM; + FxaaFloat dirSeMinusNw = lumaSe - lumaNw; + if(lumaMaxSubMinM < lumaMaxScaledClamped) return rgbyM; +/*--------------------------------------------------------------------------*/ + FxaaFloat2 dir; + dir.x = dirSwMinusNe + dirSeMinusNw; + dir.y = dirSwMinusNe - dirSeMinusNw; +/*--------------------------------------------------------------------------*/ + FxaaFloat2 dir1 = normalize(dir.xy); + FxaaFloat4 rgbyN1 = FxaaTexTop(tex, pos.xy - dir1 * fxaaConsoleRcpFrameOpt.zw); + FxaaFloat4 rgbyP1 = FxaaTexTop(tex, pos.xy + dir1 * fxaaConsoleRcpFrameOpt.zw); +/*--------------------------------------------------------------------------*/ + FxaaFloat dirAbsMinTimesC = min(abs(dir1.x), abs(dir1.y)) * fxaaConsoleEdgeSharpness; + FxaaFloat2 dir2 = clamp(dir1.xy / dirAbsMinTimesC, -2.0, 2.0); +/*--------------------------------------------------------------------------*/ + FxaaFloat4 rgbyN2 = FxaaTexTop(tex, pos.xy - dir2 * fxaaConsoleRcpFrameOpt2.zw); + FxaaFloat4 rgbyP2 = FxaaTexTop(tex, pos.xy + dir2 * fxaaConsoleRcpFrameOpt2.zw); +/*--------------------------------------------------------------------------*/ + FxaaFloat4 rgbyA = rgbyN1 + rgbyP1; + FxaaFloat4 rgbyB = ((rgbyN2 + rgbyP2) * 0.25) + (rgbyA * 0.25); +/*--------------------------------------------------------------------------*/ + #if (FXAA_GREEN_AS_LUMA == 0) + FxaaBool twoTap = (rgbyB.w < lumaMin) || (rgbyB.w > lumaMax); + #else + FxaaBool twoTap = (rgbyB.y < lumaMin) || (rgbyB.y > lumaMax); + #endif + if(twoTap) rgbyB.xyz = rgbyA.xyz * 0.5; + return rgbyB; } +/*==========================================================================*/ +#endif + + + +/*============================================================================ + + FXAA3 CONSOLE - 360 PIXEL SHADER + +------------------------------------------------------------------------------ +This optimized version thanks to suggestions from Andy Luedke. +Should be fully tex bound in all cases. +As of the FXAA 3.11 release, I have still not tested this code, +however I fixed a bug which was in both FXAA 3.9 and FXAA 3.10. +And note this is replacing the old unoptimized version. +If it does not work, please let me know so I can fix it. +============================================================================*/ +#if (FXAA_360 == 1) +/*--------------------------------------------------------------------------*/ +[reduceTempRegUsage(4)] +float4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + FxaaFloat2 pos, + FxaaFloat4 fxaaConsolePosPos, + FxaaTex tex, + FxaaTex fxaaConsole360TexExpBiasNegOne, + FxaaTex fxaaConsole360TexExpBiasNegTwo, + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ + float4 lumaNwNeSwSe; + #if (FXAA_GREEN_AS_LUMA == 0) + asm { + tfetch2D lumaNwNeSwSe.w___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe._w__, tex, pos.xy, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe.__w_, tex, pos.xy, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe.___w, tex, pos.xy, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false + }; + #else + asm { + tfetch2D lumaNwNeSwSe.y___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe._y__, tex, pos.xy, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe.__y_, tex, pos.xy, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe.___y, tex, pos.xy, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false + }; + #endif +/*--------------------------------------------------------------------------*/ + lumaNwNeSwSe.y += 1.0/384.0; + float2 lumaMinTemp = min(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw); + float2 lumaMaxTemp = max(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw); + float lumaMin = min(lumaMinTemp.x, lumaMinTemp.y); + float lumaMax = max(lumaMaxTemp.x, lumaMaxTemp.y); +/*--------------------------------------------------------------------------*/ + float4 rgbyM = tex2Dlod(tex, float4(pos.xy, 0.0, 0.0)); + #if (FXAA_GREEN_AS_LUMA == 0) + float lumaMinM = min(lumaMin, rgbyM.w); + float lumaMaxM = max(lumaMax, rgbyM.w); + #else + float lumaMinM = min(lumaMin, rgbyM.y); + float lumaMaxM = max(lumaMax, rgbyM.y); + #endif + if((lumaMaxM - lumaMinM) < max(fxaaConsoleEdgeThresholdMin, lumaMax * fxaaConsoleEdgeThreshold)) return rgbyM; +/*--------------------------------------------------------------------------*/ + float2 dir; + dir.x = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.yyxx); + dir.y = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.xyxy); + dir = normalize(dir); +/*--------------------------------------------------------------------------*/ + float4 dir1 = dir.xyxy * fxaaConsoleRcpFrameOpt.xyzw; +/*--------------------------------------------------------------------------*/ + float4 dir2; + float dirAbsMinTimesC = min(abs(dir.x), abs(dir.y)) * fxaaConsoleEdgeSharpness; + dir2 = saturate(fxaaConsole360ConstDir.zzww * dir.xyxy / dirAbsMinTimesC + 0.5); + dir2 = dir2 * fxaaConsole360RcpFrameOpt2.xyxy + fxaaConsole360RcpFrameOpt2.zwzw; +/*--------------------------------------------------------------------------*/ + float4 rgbyN1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.xy, 0.0, 0.0)); + float4 rgbyP1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.zw, 0.0, 0.0)); + float4 rgbyN2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.xy, 0.0, 0.0)); + float4 rgbyP2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.zw, 0.0, 0.0)); +/*--------------------------------------------------------------------------*/ + float4 rgbyA = rgbyN1 + rgbyP1; + float4 rgbyB = rgbyN2 + rgbyP2 + rgbyA * 0.5; +/*--------------------------------------------------------------------------*/ + float4 rgbyR = ((FxaaLuma(rgbyB) - lumaMax) > 0.0) ? rgbyA : rgbyB; + rgbyR = ((FxaaLuma(rgbyB) - lumaMin) > 0.0) ? rgbyR : rgbyA; + return rgbyR; } +/*==========================================================================*/ +#endif + + + +/*============================================================================ + + FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (NO EARLY EXIT) + +============================================================================== +The code below does not exactly match the assembly. +I have a feeling that 12 cycles is possible, but was not able to get there. +Might have to increase register count to get full performance. +Note this shader does not use perspective interpolation. + +Use the following cgc options, + + --fenable-bx2 --fastmath --fastprecision --nofloatbindings + +------------------------------------------------------------------------------ + NVSHADERPERF OUTPUT +------------------------------------------------------------------------------ +For reference and to aid in debug, output of NVShaderPerf should match this, + +Shader to schedule: + 0: texpkb h0.w(TRUE), v5.zyxx, #0 + 2: addh h2.z(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x + 4: texpkb h0.w(TRUE), v5.xwxx, #0 + 6: addh h0.z(TRUE), -h2, h0.w + 7: texpkb h1.w(TRUE), v5, #0 + 9: addh h0.x(TRUE), h0.z, -h1.w + 10: addh h3.w(TRUE), h0.z, h1 + 11: texpkb h2.w(TRUE), v5.zwzz, #0 + 13: addh h0.z(TRUE), h3.w, -h2.w + 14: addh h0.x(TRUE), h2.w, h0 + 15: nrmh h1.xz(TRUE), h0_n + 16: minh_m8 h0.x(TRUE), |h1|, |h1.z| + 17: maxh h4.w(TRUE), h0, h1 + 18: divx h2.xy(TRUE), h1_n.xzzw, h0_n + 19: movr r1.zw(TRUE), v4.xxxy + 20: madr r2.xz(TRUE), -h1, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zzww, r1.zzww + 22: minh h5.w(TRUE), h0, h1 + 23: texpkb h0(TRUE), r2.xzxx, #0 + 25: madr r0.zw(TRUE), h1.xzxz, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w), r1 + 27: maxh h4.x(TRUE), h2.z, h2.w + 28: texpkb h1(TRUE), r0.zwzz, #0 + 30: addh_d2 h1(TRUE), h0, h1 + 31: madr r0.xy(TRUE), -h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz + 33: texpkb h0(TRUE), r0, #0 + 35: minh h4.z(TRUE), h2, h2.w + 36: fenct TRUE + 37: madr r1.xy(TRUE), h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz + 39: texpkb h2(TRUE), r1, #0 + 41: addh_d2 h0(TRUE), h0, h2 + 42: maxh h2.w(TRUE), h4, h4.x + 43: minh h2.x(TRUE), h5.w, h4.z + 44: addh_d2 h0(TRUE), h0, h1 + 45: slth h2.x(TRUE), h0.w, h2 + 46: sgth h2.w(TRUE), h0, h2 + 47: movh h0(TRUE), h0 + 48: addx.c0 rc(TRUE), h2, h2.w + 49: movh h0(c0.NE.x), h1 + +IPU0 ------ Simplified schedule: -------- +Pass | Unit | uOp | PC: Op +-----+--------+------+------------------------- + 1 | SCT0/1 | mov | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; + | TEX | txl | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; + | SCB1 | add | 2: ADDh h2.z, h0.--w-, const.--x-; + | | | + 2 | SCT0/1 | mov | 4: TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0; + | TEX | txl | 4: TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0; + | SCB1 | add | 6: ADDh h0.z,-h2, h0.--w-; + | | | + 3 | SCT0/1 | mov | 7: TXLr h1.w, g[TEX1], const.xxxx, TEX0; + | TEX | txl | 7: TXLr h1.w, g[TEX1], const.xxxx, TEX0; + | SCB0 | add | 9: ADDh h0.x, h0.z---,-h1.w---; + | SCB1 | add | 10: ADDh h3.w, h0.---z, h1; + | | | + 4 | SCT0/1 | mov | 11: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; + | TEX | txl | 11: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; + | SCB0 | add | 14: ADDh h0.x, h2.w---, h0; + | SCB1 | add | 13: ADDh h0.z, h3.--w-,-h2.--w-; + | | | + 5 | SCT1 | mov | 15: NRMh h1.xz, h0; + | SRB | nrm | 15: NRMh h1.xz, h0; + | SCB0 | min | 16: MINh*8 h0.x, |h1|, |h1.z---|; + | SCB1 | max | 17: MAXh h4.w, h0, h1; + | | | + 6 | SCT0 | div | 18: DIVx h2.xy, h1.xz--, h0; + | SCT1 | mov | 19: MOVr r1.zw, g[TEX0].--xy; + | SCB0 | mad | 20: MADr r2.xz,-h1, const.z-w-, r1.z-w-; + | SCB1 | min | 22: MINh h5.w, h0, h1; + | | | + 7 | SCT0/1 | mov | 23: TXLr h0, r2.xzxx, const.xxxx, TEX0; + | TEX | txl | 23: TXLr h0, r2.xzxx, const.xxxx, TEX0; + | SCB0 | max | 27: MAXh h4.x, h2.z---, h2.w---; + | SCB1 | mad | 25: MADr r0.zw, h1.--xz, const, r1; + | | | + 8 | SCT0/1 | mov | 28: TXLr h1, r0.zwzz, const.xxxx, TEX0; + | TEX | txl | 28: TXLr h1, r0.zwzz, const.xxxx, TEX0; + | SCB0/1 | add | 30: ADDh/2 h1, h0, h1; + | | | + 9 | SCT0 | mad | 31: MADr r0.xy,-h2, const.xy--, r1.zw--; + | SCT1 | mov | 33: TXLr h0, r0, const.zzzz, TEX0; + | TEX | txl | 33: TXLr h0, r0, const.zzzz, TEX0; + | SCB1 | min | 35: MINh h4.z, h2, h2.--w-; + | | | + 10 | SCT0 | mad | 37: MADr r1.xy, h2, const.xy--, r1.zw--; + | SCT1 | mov | 39: TXLr h2, r1, const.zzzz, TEX0; + | TEX | txl | 39: TXLr h2, r1, const.zzzz, TEX0; + | SCB0/1 | add | 41: ADDh/2 h0, h0, h2; + | | | + 11 | SCT0 | min | 43: MINh h2.x, h5.w---, h4.z---; + | SCT1 | max | 42: MAXh h2.w, h4, h4.---x; + | SCB0/1 | add | 44: ADDh/2 h0, h0, h1; + | | | + 12 | SCT0 | set | 45: SLTh h2.x, h0.w---, h2; + | SCT1 | set | 46: SGTh h2.w, h0, h2; + | SCB0/1 | mul | 47: MOVh h0, h0; + | | | + 13 | SCT0 | mad | 48: ADDxc0_s rc, h2, h2.w---; + | SCB0/1 | mul | 49: MOVh h0(NE0.xxxx), h1; + +Pass SCT TEX SCB + 1: 0% 100% 25% + 2: 0% 100% 25% + 3: 0% 100% 50% + 4: 0% 100% 50% + 5: 0% 0% 50% + 6: 100% 0% 75% + 7: 0% 100% 75% + 8: 0% 100% 100% + 9: 0% 100% 25% + 10: 0% 100% 100% + 11: 50% 0% 100% + 12: 50% 0% 100% + 13: 25% 0% 100% + +MEAN: 17% 61% 67% + +Pass SCT0 SCT1 TEX SCB0 SCB1 + 1: 0% 0% 100% 0% 100% + 2: 0% 0% 100% 0% 100% + 3: 0% 0% 100% 100% 100% + 4: 0% 0% 100% 100% 100% + 5: 0% 0% 0% 100% 100% + 6: 100% 100% 0% 100% 100% + 7: 0% 0% 100% 100% 100% + 8: 0% 0% 100% 100% 100% + 9: 0% 0% 100% 0% 100% + 10: 0% 0% 100% 100% 100% + 11: 100% 100% 0% 100% 100% + 12: 100% 100% 0% 100% 100% + 13: 100% 0% 0% 100% 100% + +MEAN: 30% 23% 61% 76% 100% +Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5 +Results 13 cycles, 3 r regs, 923,076,923 pixels/s +============================================================================*/ +#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 0) +/*--------------------------------------------------------------------------*/ +#pragma regcount 7 +#pragma disablepc all +#pragma option O3 +#pragma option OutColorPrec=fp16 +#pragma texformat default RGBA8 +/*==========================================================================*/ +half4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + FxaaFloat2 pos, + FxaaFloat4 fxaaConsolePosPos, + FxaaTex tex, + FxaaTex fxaaConsole360TexExpBiasNegOne, + FxaaTex fxaaConsole360TexExpBiasNegTwo, + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ +// (1) + half4 dir; + half4 lumaNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + lumaNe.w += half(1.0/512.0); + dir.x = -lumaNe.w; + dir.z = -lumaNe.w; + #else + lumaNe.y += half(1.0/512.0); + dir.x = -lumaNe.y; + dir.z = -lumaNe.y; + #endif +/*--------------------------------------------------------------------------*/ +// (2) + half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + dir.x += lumaSw.w; + dir.z += lumaSw.w; + #else + dir.x += lumaSw.y; + dir.z += lumaSw.y; + #endif +/*--------------------------------------------------------------------------*/ +// (3) + half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + dir.x -= lumaNw.w; + dir.z += lumaNw.w; + #else + dir.x -= lumaNw.y; + dir.z += lumaNw.y; + #endif +/*--------------------------------------------------------------------------*/ +// (4) + half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + dir.x += lumaSe.w; + dir.z -= lumaSe.w; + #else + dir.x += lumaSe.y; + dir.z -= lumaSe.y; + #endif +/*--------------------------------------------------------------------------*/ +// (5) + half4 dir1_pos; + dir1_pos.xy = normalize(dir.xyz).xz; + half dirAbsMinTimesC = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS); +/*--------------------------------------------------------------------------*/ +// (6) + half4 dir2_pos; + dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimesC, half(-2.0), half(2.0)); + dir1_pos.zw = pos.xy; + dir2_pos.zw = pos.xy; + half4 temp1N; + temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; +/*--------------------------------------------------------------------------*/ +// (7) + temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0)); + half4 rgby1; + rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; +/*--------------------------------------------------------------------------*/ +// (8) + rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0)); + rgby1 = (temp1N + rgby1) * 0.5; +/*--------------------------------------------------------------------------*/ +// (9) + half4 temp2N; + temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; + temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0)); +/*--------------------------------------------------------------------------*/ +// (10) + half4 rgby2; + rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; + rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0)); + rgby2 = (temp2N + rgby2) * 0.5; +/*--------------------------------------------------------------------------*/ +// (11) + // compilier moves these scalar ops up to other cycles + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaMin = min(min(lumaNw.w, lumaSw.w), min(lumaNe.w, lumaSe.w)); + half lumaMax = max(max(lumaNw.w, lumaSw.w), max(lumaNe.w, lumaSe.w)); + #else + half lumaMin = min(min(lumaNw.y, lumaSw.y), min(lumaNe.y, lumaSe.y)); + half lumaMax = max(max(lumaNw.y, lumaSw.y), max(lumaNe.y, lumaSe.y)); + #endif + rgby2 = (rgby2 + rgby1) * 0.5; +/*--------------------------------------------------------------------------*/ +// (12) + #if (FXAA_GREEN_AS_LUMA == 0) + bool twoTapLt = rgby2.w < lumaMin; + bool twoTapGt = rgby2.w > lumaMax; + #else + bool twoTapLt = rgby2.y < lumaMin; + bool twoTapGt = rgby2.y > lumaMax; + #endif +/*--------------------------------------------------------------------------*/ +// (13) + if(twoTapLt || twoTapGt) rgby2 = rgby1; +/*--------------------------------------------------------------------------*/ + return rgby2; } +/*==========================================================================*/ +#endif + + + +/*============================================================================ + + FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (WITH EARLY EXIT) + +============================================================================== +The code mostly matches the assembly. +I have a feeling that 14 cycles is possible, but was not able to get there. +Might have to increase register count to get full performance. +Note this shader does not use perspective interpolation. + +Use the following cgc options, + + --fenable-bx2 --fastmath --fastprecision --nofloatbindings + +Use of FXAA_GREEN_AS_LUMA currently adds a cycle (16 clks). +Will look at fixing this for FXAA 3.12. +------------------------------------------------------------------------------ + NVSHADERPERF OUTPUT +------------------------------------------------------------------------------ +For reference and to aid in debug, output of NVShaderPerf should match this, + +Shader to schedule: + 0: texpkb h0.w(TRUE), v5.zyxx, #0 + 2: addh h2.y(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x + 4: texpkb h1.w(TRUE), v5.xwxx, #0 + 6: addh h0.x(TRUE), h1.w, -h2.y + 7: texpkb h2.w(TRUE), v5.zwzz, #0 + 9: minh h4.w(TRUE), h2.y, h2 + 10: maxh h5.x(TRUE), h2.y, h2.w + 11: texpkb h0.w(TRUE), v5, #0 + 13: addh h3.w(TRUE), -h0, h0.x + 14: addh h0.x(TRUE), h0.w, h0 + 15: addh h0.z(TRUE), -h2.w, h0.x + 16: addh h0.x(TRUE), h2.w, h3.w + 17: minh h5.y(TRUE), h0.w, h1.w + 18: nrmh h2.xz(TRUE), h0_n + 19: minh_m8 h2.w(TRUE), |h2.x|, |h2.z| + 20: divx h4.xy(TRUE), h2_n.xzzw, h2_n.w + 21: movr r1.zw(TRUE), v4.xxxy + 22: maxh h2.w(TRUE), h0, h1 + 23: fenct TRUE + 24: madr r0.xy(TRUE), -h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz + 26: texpkb h0(TRUE), r0, #0 + 28: maxh h5.x(TRUE), h2.w, h5 + 29: minh h5.w(TRUE), h5.y, h4 + 30: madr r1.xy(TRUE), h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz + 32: texpkb h2(TRUE), r1, #0 + 34: addh_d2 h2(TRUE), h0, h2 + 35: texpkb h1(TRUE), v4, #0 + 37: maxh h5.y(TRUE), h5.x, h1.w + 38: minh h4.w(TRUE), h1, h5 + 39: madr r0.xy(TRUE), -h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz + 41: texpkb h0(TRUE), r0, #0 + 43: addh_m8 h5.z(TRUE), h5.y, -h4.w + 44: madr r2.xy(TRUE), h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz + 46: texpkb h3(TRUE), r2, #0 + 48: addh_d2 h0(TRUE), h0, h3 + 49: addh_d2 h3(TRUE), h0, h2 + 50: movh h0(TRUE), h3 + 51: slth h3.x(TRUE), h3.w, h5.w + 52: sgth h3.w(TRUE), h3, h5.x + 53: addx.c0 rc(TRUE), h3.x, h3 + 54: slth.c0 rc(TRUE), h5.z, h5 + 55: movh h0(c0.NE.w), h2 + 56: movh h0(c0.NE.x), h1 + +IPU0 ------ Simplified schedule: -------- +Pass | Unit | uOp | PC: Op +-----+--------+------+------------------------- + 1 | SCT0/1 | mov | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; + | TEX | txl | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; + | SCB0 | add | 2: ADDh h2.y, h0.-w--, const.-x--; + | | | + 2 | SCT0/1 | mov | 4: TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0; + | TEX | txl | 4: TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0; + | SCB0 | add | 6: ADDh h0.x, h1.w---,-h2.y---; + | | | + 3 | SCT0/1 | mov | 7: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; + | TEX | txl | 7: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; + | SCB0 | max | 10: MAXh h5.x, h2.y---, h2.w---; + | SCB1 | min | 9: MINh h4.w, h2.---y, h2; + | | | + 4 | SCT0/1 | mov | 11: TXLr h0.w, g[TEX1], const.xxxx, TEX0; + | TEX | txl | 11: TXLr h0.w, g[TEX1], const.xxxx, TEX0; + | SCB0 | add | 14: ADDh h0.x, h0.w---, h0; + | SCB1 | add | 13: ADDh h3.w,-h0, h0.---x; + | | | + 5 | SCT0 | mad | 16: ADDh h0.x, h2.w---, h3.w---; + | SCT1 | mad | 15: ADDh h0.z,-h2.--w-, h0.--x-; + | SCB0 | min | 17: MINh h5.y, h0.-w--, h1.-w--; + | | | + 6 | SCT1 | mov | 18: NRMh h2.xz, h0; + | SRB | nrm | 18: NRMh h2.xz, h0; + | SCB1 | min | 19: MINh*8 h2.w, |h2.---x|, |h2.---z|; + | | | + 7 | SCT0 | div | 20: DIVx h4.xy, h2.xz--, h2.ww--; + | SCT1 | mov | 21: MOVr r1.zw, g[TEX0].--xy; + | SCB1 | max | 22: MAXh h2.w, h0, h1; + | | | + 8 | SCT0 | mad | 24: MADr r0.xy,-h2.xz--, const.zw--, r1.zw--; + | SCT1 | mov | 26: TXLr h0, r0, const.xxxx, TEX0; + | TEX | txl | 26: TXLr h0, r0, const.xxxx, TEX0; + | SCB0 | max | 28: MAXh h5.x, h2.w---, h5; + | SCB1 | min | 29: MINh h5.w, h5.---y, h4; + | | | + 9 | SCT0 | mad | 30: MADr r1.xy, h2.xz--, const.zw--, r1.zw--; + | SCT1 | mov | 32: TXLr h2, r1, const.xxxx, TEX0; + | TEX | txl | 32: TXLr h2, r1, const.xxxx, TEX0; + | SCB0/1 | add | 34: ADDh/2 h2, h0, h2; + | | | + 10 | SCT0/1 | mov | 35: TXLr h1, g[TEX0], const.xxxx, TEX0; + | TEX | txl | 35: TXLr h1, g[TEX0], const.xxxx, TEX0; + | SCB0 | max | 37: MAXh h5.y, h5.-x--, h1.-w--; + | SCB1 | min | 38: MINh h4.w, h1, h5; + | | | + 11 | SCT0 | mad | 39: MADr r0.xy,-h4, const.xy--, r1.zw--; + | SCT1 | mov | 41: TXLr h0, r0, const.zzzz, TEX0; + | TEX | txl | 41: TXLr h0, r0, const.zzzz, TEX0; + | SCB0 | mad | 44: MADr r2.xy, h4, const.xy--, r1.zw--; + | SCB1 | add | 43: ADDh*8 h5.z, h5.--y-,-h4.--w-; + | | | + 12 | SCT0/1 | mov | 46: TXLr h3, r2, const.xxxx, TEX0; + | TEX | txl | 46: TXLr h3, r2, const.xxxx, TEX0; + | SCB0/1 | add | 48: ADDh/2 h0, h0, h3; + | | | + 13 | SCT0/1 | mad | 49: ADDh/2 h3, h0, h2; + | SCB0/1 | mul | 50: MOVh h0, h3; + | | | + 14 | SCT0 | set | 51: SLTh h3.x, h3.w---, h5.w---; + | SCT1 | set | 52: SGTh h3.w, h3, h5.---x; + | SCB0 | set | 54: SLThc0 rc, h5.z---, h5; + | SCB1 | add | 53: ADDxc0_s rc, h3.---x, h3; + | | | + 15 | SCT0/1 | mul | 55: MOVh h0(NE0.wwww), h2; + | SCB0/1 | mul | 56: MOVh h0(NE0.xxxx), h1; + +Pass SCT TEX SCB + 1: 0% 100% 25% + 2: 0% 100% 25% + 3: 0% 100% 50% + 4: 0% 100% 50% + 5: 50% 0% 25% + 6: 0% 0% 25% + 7: 100% 0% 25% + 8: 0% 100% 50% + 9: 0% 100% 100% + 10: 0% 100% 50% + 11: 0% 100% 75% + 12: 0% 100% 100% + 13: 100% 0% 100% + 14: 50% 0% 50% + 15: 100% 0% 100% + +MEAN: 26% 60% 56% + +Pass SCT0 SCT1 TEX SCB0 SCB1 + 1: 0% 0% 100% 100% 0% + 2: 0% 0% 100% 100% 0% + 3: 0% 0% 100% 100% 100% + 4: 0% 0% 100% 100% 100% + 5: 100% 100% 0% 100% 0% + 6: 0% 0% 0% 0% 100% + 7: 100% 100% 0% 0% 100% + 8: 0% 0% 100% 100% 100% + 9: 0% 0% 100% 100% 100% + 10: 0% 0% 100% 100% 100% + 11: 0% 0% 100% 100% 100% + 12: 0% 0% 100% 100% 100% + 13: 100% 100% 0% 100% 100% + 14: 100% 100% 0% 100% 100% + 15: 100% 100% 0% 100% 100% + +MEAN: 33% 33% 60% 86% 80% +Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5 +Results 15 cycles, 3 r regs, 800,000,000 pixels/s +============================================================================*/ +#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 1) +/*--------------------------------------------------------------------------*/ +#pragma regcount 7 +#pragma disablepc all +#pragma option O2 +#pragma option OutColorPrec=fp16 +#pragma texformat default RGBA8 +/*==========================================================================*/ +half4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + FxaaFloat2 pos, + FxaaFloat4 fxaaConsolePosPos, + FxaaTex tex, + FxaaTex fxaaConsole360TexExpBiasNegOne, + FxaaTex fxaaConsole360TexExpBiasNegTwo, + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ +// (1) + half4 rgbyNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaNe = rgbyNe.w + half(1.0/512.0); + #else + half lumaNe = rgbyNe.y + half(1.0/512.0); + #endif +/*--------------------------------------------------------------------------*/ +// (2) + half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaSwNegNe = lumaSw.w - lumaNe; + #else + half lumaSwNegNe = lumaSw.y - lumaNe; + #endif +/*--------------------------------------------------------------------------*/ +// (3) + half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaMaxNwSw = max(lumaNw.w, lumaSw.w); + half lumaMinNwSw = min(lumaNw.w, lumaSw.w); + #else + half lumaMaxNwSw = max(lumaNw.y, lumaSw.y); + half lumaMinNwSw = min(lumaNw.y, lumaSw.y); + #endif +/*--------------------------------------------------------------------------*/ +// (4) + half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half dirZ = lumaNw.w + lumaSwNegNe; + half dirX = -lumaNw.w + lumaSwNegNe; + #else + half dirZ = lumaNw.y + lumaSwNegNe; + half dirX = -lumaNw.y + lumaSwNegNe; + #endif +/*--------------------------------------------------------------------------*/ +// (5) + half3 dir; + dir.y = 0.0; + #if (FXAA_GREEN_AS_LUMA == 0) + dir.x = lumaSe.w + dirX; + dir.z = -lumaSe.w + dirZ; + half lumaMinNeSe = min(lumaNe, lumaSe.w); + #else + dir.x = lumaSe.y + dirX; + dir.z = -lumaSe.y + dirZ; + half lumaMinNeSe = min(lumaNe, lumaSe.y); + #endif +/*--------------------------------------------------------------------------*/ +// (6) + half4 dir1_pos; + dir1_pos.xy = normalize(dir).xz; + half dirAbsMinTimes8 = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS); +/*--------------------------------------------------------------------------*/ +// (7) + half4 dir2_pos; + dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimes8, half(-2.0), half(2.0)); + dir1_pos.zw = pos.xy; + dir2_pos.zw = pos.xy; + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaMaxNeSe = max(lumaNe, lumaSe.w); + #else + half lumaMaxNeSe = max(lumaNe, lumaSe.y); + #endif +/*--------------------------------------------------------------------------*/ +// (8) + half4 temp1N; + temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; + temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0)); + half lumaMax = max(lumaMaxNwSw, lumaMaxNeSe); + half lumaMin = min(lumaMinNwSw, lumaMinNeSe); +/*--------------------------------------------------------------------------*/ +// (9) + half4 rgby1; + rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; + rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0)); + rgby1 = (temp1N + rgby1) * 0.5; +/*--------------------------------------------------------------------------*/ +// (10) + half4 rgbyM = h4tex2Dlod(tex, half4(pos.xy, 0.0, 0.0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaMaxM = max(lumaMax, rgbyM.w); + half lumaMinM = min(lumaMin, rgbyM.w); + #else + half lumaMaxM = max(lumaMax, rgbyM.y); + half lumaMinM = min(lumaMin, rgbyM.y); + #endif +/*--------------------------------------------------------------------------*/ +// (11) + half4 temp2N; + temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; + temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0)); + half4 rgby2; + rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; + half lumaRangeM = (lumaMaxM - lumaMinM) / FXAA_CONSOLE__PS3_EDGE_THRESHOLD; +/*--------------------------------------------------------------------------*/ +// (12) + rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0)); + rgby2 = (temp2N + rgby2) * 0.5; +/*--------------------------------------------------------------------------*/ +// (13) + rgby2 = (rgby2 + rgby1) * 0.5; +/*--------------------------------------------------------------------------*/ +// (14) + #if (FXAA_GREEN_AS_LUMA == 0) + bool twoTapLt = rgby2.w < lumaMin; + bool twoTapGt = rgby2.w > lumaMax; + #else + bool twoTapLt = rgby2.y < lumaMin; + bool twoTapGt = rgby2.y > lumaMax; + #endif + bool earlyExit = lumaRangeM < lumaMax; + bool twoTap = twoTapLt || twoTapGt; +/*--------------------------------------------------------------------------*/ +// (15) + if(twoTap) rgby2 = rgby1; + if(earlyExit) rgby2 = rgbyM; +/*--------------------------------------------------------------------------*/ + return rgby2; } +/*==========================================================================*/ +#endif diff --git a/Templates/Empty/game/shaders/common/postFx/fxaa/fxaaP.hlsl b/Templates/Empty/game/shaders/common/postFx/fxaa/fxaaP.hlsl new file mode 100644 index 000000000..357b794e4 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/fxaa/fxaaP.hlsl @@ -0,0 +1,128 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#define FXAA_PC 1 +#define FXAA_HLSL_3 1 +#define FXAA_QUALITY__PRESET 12 +#define FXAA_GREEN_AS_LUMA 1 + +#include "Fxaa3_11.h" +#include "../postFx.hlsl" + +struct VertToPix +{ + float4 hpos : POSITION; + float2 uv0 : TEXCOORD0; +}; + +uniform sampler2D colorTex : register(S0); + +uniform float2 oneOverTargetSize; + + +float4 main( VertToPix IN ) : COLOR +{ + return FxaaPixelShader( + + IN.uv0, // vertex position + + 0, // Unused... console stuff + + colorTex, // The color back buffer + + colorTex, // Used for 360 optimization + + colorTex, // Used for 360 optimization + + oneOverTargetSize, + + 0, // Unused... console stuff + + 0, // Unused... console stuff + + 0, // Unused... console stuff + + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__SUBPIX define. + // It is here now to allow easier tuning. + // Choose the amount of sub-pixel aliasing removal. + // This can effect sharpness. + // 1.00 - upper limit (softer) + // 0.75 - default amount of filtering + // 0.50 - lower limit (sharper, less sub-pixel aliasing removal) + // 0.25 - almost off + // 0.00 - completely off + 0.75, + + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD define. + // It is here now to allow easier tuning. + // The minimum amount of local contrast required to apply algorithm. + // 0.333 - too little (faster) + // 0.250 - low quality + // 0.166 - default + // 0.125 - high quality + // 0.063 - overkill (slower) + 0.166, + + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD_MIN define. + // It is here now to allow easier tuning. + // Trims the algorithm from processing darks. + // 0.0833 - upper limit (default, the start of visible unfiltered edges) + // 0.0625 - high quality (faster) + // 0.0312 - visible limit (slower) + // Special notes when using FXAA_GREEN_AS_LUMA, + // Likely want to set this to zero. + // As colors that are mostly not-green + // will appear very dark in the green channel! + // Tune by looking at mostly non-green content, + // then start at zero and increase until aliasing is a problem. + 0, + + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define. + // It is here now to allow easier tuning. + // This does not effect PS3, as this needs to be compiled in. + // Use FXAA_CONSOLE__PS3_EDGE_SHARPNESS for PS3. + // Due to the PS3 being ALU bound, + // there are only three safe values here: 2 and 4 and 8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // For all other platforms can be a non-power of two. + // 8.0 is sharper (default!!!) + // 4.0 is softer + // 2.0 is really soft (good only for vector graphics inputs) + 8, + + 0, // Unused... console stuff + + 0, // Unused... console stuff + + 0 // Unused... console stuff + + ); +} + diff --git a/Templates/Empty/game/shaders/common/postFx/fxaa/fxaaV.hlsl b/Templates/Empty/game/shaders/common/postFx/fxaa/fxaaV.hlsl new file mode 100644 index 000000000..ea2c3d106 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/fxaa/fxaaV.hlsl @@ -0,0 +1,42 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "./../../torque.hlsl" +#include "./../postFX.hlsl" + +struct VertToPix +{ + float4 hpos : POSITION; + float2 uv0 : TEXCOORD0; +}; + +uniform float4 rtParams0; + +VertToPix main( PFXVert IN ) +{ + VertToPix OUT; + + OUT.hpos = IN.pos; + OUT.uv0 = viewportCoordToRenderTarget( IN.uv, rtParams0 ); + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/postFx/gammaP.hlsl b/Templates/Empty/game/shaders/common/postFx/gammaP.hlsl new file mode 100644 index 000000000..dedfe8eb5 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/gammaP.hlsl @@ -0,0 +1,46 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" +#include "./postFx.hlsl" +#include "../torque.hlsl" + +uniform sampler2D backBuffer : register(S0); +uniform sampler1D colorCorrectionTex : register( s1 ); + +uniform float OneOverGamma; + + +float4 main( PFXVertToPix IN ) : COLOR0 +{ + float4 color = tex2D(backBuffer, IN.uv0.xy); + + // Apply the color correction. + color.r = tex1D( colorCorrectionTex, color.r ).r; + color.g = tex1D( colorCorrectionTex, color.g ).g; + color.b = tex1D( colorCorrectionTex, color.b ).b; + + // Apply gamma correction + color.rgb = pow( abs(color.rgb), OneOverGamma ); + + return color; +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/postFx/glowBlurP.hlsl b/Templates/Empty/game/shaders/common/postFx/glowBlurP.hlsl new file mode 100644 index 000000000..65ae96c6f --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/glowBlurP.hlsl @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "./postFx.hlsl" + +uniform sampler2D diffuseMap : register(S0); + +struct VertToPix +{ + float4 hpos : POSITION; + + float2 uv0 : TEXCOORD0; + float2 uv1 : TEXCOORD1; + float2 uv2 : TEXCOORD2; + float2 uv3 : TEXCOORD3; + + float2 uv4 : TEXCOORD4; + float2 uv5 : TEXCOORD5; + float2 uv6 : TEXCOORD6; + float2 uv7 : TEXCOORD7; +}; + +float4 main( VertToPix IN ) : COLOR +{ + float4 kernel = float4( 0.175, 0.275, 0.375, 0.475 ) * 0.5f; + + float4 OUT = 0; + OUT += tex2D( diffuseMap, IN.uv0 ) * kernel.x; + OUT += tex2D( diffuseMap, IN.uv1 ) * kernel.y; + OUT += tex2D( diffuseMap, IN.uv2 ) * kernel.z; + OUT += tex2D( diffuseMap, IN.uv3 ) * kernel.w; + + OUT += tex2D( diffuseMap, IN.uv4 ) * kernel.x; + OUT += tex2D( diffuseMap, IN.uv5 ) * kernel.y; + OUT += tex2D( diffuseMap, IN.uv6 ) * kernel.z; + OUT += tex2D( diffuseMap, IN.uv7 ) * kernel.w; + + // Calculate a lumenance value in the alpha so we + // can use alpha test to save fillrate. + float3 rgb2lum = float3( 0.30, 0.59, 0.11 ); + OUT.a = dot( OUT.rgb, rgb2lum ); + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/postFx/glowBlurV.hlsl b/Templates/Empty/game/shaders/common/postFx/glowBlurV.hlsl new file mode 100644 index 000000000..c9c9052ec --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/glowBlurV.hlsl @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "./postFx.hlsl" +#include "./../torque.hlsl" + + +uniform float2 texSize0; + +struct VertToPix +{ + float4 hpos : POSITION; + + float2 uv0 : TEXCOORD0; + float2 uv1 : TEXCOORD1; + float2 uv2 : TEXCOORD2; + float2 uv3 : TEXCOORD3; + + float2 uv4 : TEXCOORD4; + float2 uv5 : TEXCOORD5; + float2 uv6 : TEXCOORD6; + float2 uv7 : TEXCOORD7; +}; + +VertToPix main( PFXVert IN ) +{ + VertToPix OUT; + + OUT.hpos = IN.pos; + + float2 uv = IN.uv + (0.5f / texSize0); + + OUT.uv0 = uv + ( ( BLUR_DIR * 3.5f ) / texSize0 ); + OUT.uv1 = uv + ( ( BLUR_DIR * 2.5f ) / texSize0 ); + OUT.uv2 = uv + ( ( BLUR_DIR * 1.5f ) / texSize0 ); + OUT.uv3 = uv + ( ( BLUR_DIR * 0.5f ) / texSize0 ); + + OUT.uv4 = uv - ( ( BLUR_DIR * 3.5f ) / texSize0 ); + OUT.uv5 = uv - ( ( BLUR_DIR * 2.5f ) / texSize0 ); + OUT.uv6 = uv - ( ( BLUR_DIR * 1.5f ) / texSize0 ); + OUT.uv7 = uv - ( ( BLUR_DIR * 0.5f ) / texSize0 ); + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/postFx/hdr/bloomGaussBlurHP.hlsl b/Templates/Empty/game/shaders/common/postFx/hdr/bloomGaussBlurHP.hlsl new file mode 100644 index 000000000..c28f9eb83 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/hdr/bloomGaussBlurHP.hlsl @@ -0,0 +1,69 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "../postFx.hlsl" +#include "shadergen:/autogenConditioners.h" + +uniform sampler2D inputTex : register(S0); +uniform float2 oneOverTargetSize; +uniform float gaussMultiplier; +uniform float gaussMean; +uniform float gaussStdDev; + +#define PI 3.141592654 + +float computeGaussianValue( float x, float mean, float std_deviation ) +{ + // The gaussian equation is defined as such: + /* + -(x - mean)^2 + ------------- + 1.0 2*std_dev^2 + f(x,mean,std_dev) = -------------------- * e^ + sqrt(2*pi*std_dev^2) + + */ + + float tmp = ( 1.0f / sqrt( 2.0f * PI * std_deviation * std_deviation ) ); + float tmp2 = exp( ( -( ( x - mean ) * ( x - mean ) ) ) / ( 2.0f * std_deviation * std_deviation ) ); + return tmp * tmp2; +} + +float4 main( PFXVertToPix IN ) : COLOR +{ + float4 color = { 0.0f, 0.0f, 0.0f, 0.0f }; + float offset = 0; + float weight = 0; + float x = 0; + float fI = 0; + + for( int i = 0; i < 9; i++ ) + { + fI = (float)i; + offset = (i - 4.0) * oneOverTargetSize.x; + x = (i - 4.0) / 4.0; + weight = gaussMultiplier * computeGaussianValue( x, gaussMean, gaussStdDev ); + color += (tex2D( inputTex, IN.uv0 + float2( offset, 0.0f ) ) * weight ); + } + + return float4( color.rgb, 1.0f ); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/postFx/hdr/bloomGaussBlurVP.hlsl b/Templates/Empty/game/shaders/common/postFx/hdr/bloomGaussBlurVP.hlsl new file mode 100644 index 000000000..93e6b8382 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/hdr/bloomGaussBlurVP.hlsl @@ -0,0 +1,68 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "../postFx.hlsl" +#include "shadergen:/autogenConditioners.h" + +uniform sampler2D inputTex : register(S0); +uniform float2 oneOverTargetSize; +uniform float gaussMultiplier; +uniform float gaussMean; +uniform float gaussStdDev; + +#define D3DX_PI 3.141592654 + +float computeGaussianValue( float x, float mean, float std_deviation ) +{ + // The gaussian equation is defined as such: + /* + -(x - mean)^2 + ------------- + 1.0 2*std_dev^2 + f(x,mean,std_dev) = -------------------- * e^ + sqrt(2*pi*std_dev^2) + + */ + float tmp = ( 1.0f / sqrt( 2.0f * D3DX_PI * std_deviation * std_deviation ) ); + float tmp2 = exp( ( -( ( x - mean ) * ( x - mean ) ) ) / ( 2.0f * std_deviation * std_deviation ) ); + return tmp * tmp2; +} + +float4 main( PFXVertToPix IN ) : COLOR +{ + float4 color = { 0.0f, 0.0f, 0.0f, 0.0f }; + float offset = 0; + float weight = 0; + float x = 0; + float fI = 0; + + for( int i = 0; i < 9; i++ ) + { + fI = (float)i; + offset = (fI - 4.0) * oneOverTargetSize.y; + x = (fI - 4.0) / 4.0; + weight = gaussMultiplier * computeGaussianValue( x, gaussMean, gaussStdDev ); + color += (tex2D( inputTex, IN.uv0 + float2( 0.0f, offset ) ) * weight ); + } + + return float4( color.rgb, 1.0f ); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/postFx/hdr/brightPassFilterP.hlsl b/Templates/Empty/game/shaders/common/postFx/hdr/brightPassFilterP.hlsl new file mode 100644 index 000000000..c438a5153 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/hdr/brightPassFilterP.hlsl @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "../postFx.hlsl" +#include "shadergen:/autogenConditioners.h" +#include "../../torque.hlsl" + + +uniform sampler2D inputTex : register(S0); +uniform sampler2D luminanceTex : register(S1); +uniform float2 oneOverTargetSize; +uniform float brightPassThreshold; +uniform float g_fMiddleGray; + +static const float3 LUMINANCE_VECTOR = float3(0.3125f, 0.6154f, 0.0721f); + + +static float2 gTapOffsets[4] = +{ + { -0.5, 0.5 }, { 0.5, -0.5 }, + { -0.5, -0.5 }, { 0.5, 0.5 } +}; + +float4 main( PFXVertToPix IN ) : COLOR +{ + float4 average = { 0.0f, 0.0f, 0.0f, 0.0f }; + + // Combine and average 4 samples from the source HDR texture. + for( int i = 0; i < 4; i++ ) + average += hdrDecode( tex2D( inputTex, IN.uv0 + ( gTapOffsets[i] * oneOverTargetSize ) ) ); + average *= 0.25f; + + // Determine the brightness of this particular pixel. + float adaptedLum = tex2D( luminanceTex, float2( 0.5f, 0.5f ) ).r; + float lum = (g_fMiddleGray / (adaptedLum + 0.0001)) * hdrLuminance( average.rgb ); + //float lum = hdrLuminance( average.rgb ); + + // Determine whether this pixel passes the test... + if ( lum < brightPassThreshold ) + average = float4( 0.0f, 0.0f, 0.0f, 1.0f ); + + // Write the colour to the bright-pass render target + return hdrEncode( average ); +} diff --git a/Templates/Empty/game/shaders/common/postFx/hdr/calculateAdaptedLumP.hlsl b/Templates/Empty/game/shaders/common/postFx/hdr/calculateAdaptedLumP.hlsl new file mode 100644 index 000000000..3f443611c --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/hdr/calculateAdaptedLumP.hlsl @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "../postFx.hlsl" +#include "shadergen:/autogenConditioners.h" + +uniform sampler2D currLum : register( S0 ); +uniform sampler2D lastAdaptedLum : register( S1 ); + +uniform float adaptRate; +uniform float deltaTime; + +float4 main( PFXVertToPix IN ) : COLOR +{ + float fAdaptedLum = tex2D( lastAdaptedLum, float2(0.5f, 0.5f) ).r; + float fCurrentLum = tex2D( currLum, float2(0.5f, 0.5f) ).r; + + // The user's adapted luminance level is simulated by closing the gap between + // adapted luminance and current luminance by 2% every frame, based on a + // 30 fps rate. This is not an accurate model of human adaptation, which can + // take longer than half an hour. + float diff = fCurrentLum - fAdaptedLum; + float fNewAdaptation = fAdaptedLum + ( diff * ( 1.0 - exp( -deltaTime * adaptRate ) ) ); + + return float4( fNewAdaptation, 0.0, 0.0, 1.0f ); +} diff --git a/Templates/Empty/game/shaders/common/postFx/hdr/downScale4x4P.hlsl b/Templates/Empty/game/shaders/common/postFx/hdr/downScale4x4P.hlsl new file mode 100644 index 000000000..3ce68452c --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/hdr/downScale4x4P.hlsl @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#define IN_HLSL +#include "../../shdrConsts.h" +#include "../postFx.hlsl" + +//----------------------------------------------------------------------------- +// Data +//----------------------------------------------------------------------------- +struct VertIn +{ + float4 hpos : POSITION; + float4 texCoords[8] : TEXCOORD0; +}; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +float4 main( VertIn IN, + uniform sampler2D inputTex : register(S0) ) : COLOR +{ + // We calculate the texture coords + // in the vertex shader as an optimization. + float4 sample = 0.0f; + for ( int i = 0; i < 8; i++ ) + { + sample += tex2D( inputTex, IN.texCoords[i].xy ); + sample += tex2D( inputTex, IN.texCoords[i].zw ); + } + + return sample / 16; +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/postFx/hdr/downScale4x4V.hlsl b/Templates/Empty/game/shaders/common/postFx/hdr/downScale4x4V.hlsl new file mode 100644 index 000000000..88794204e --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/hdr/downScale4x4V.hlsl @@ -0,0 +1,137 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#define IN_HLSL +#include "../../shdrConsts.h" +#include "../postFx.hlsl" +//----------------------------------------------------------------------------- +// Constants +//----------------------------------------------------------------------------- + +struct Conn +{ + float4 hpos : POSITION; + float4 texCoords[8] : TEXCOORD0; +}; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Conn main( PFXVert In, + uniform float2 targetSize : register(C0) ) +{ + Conn Out; + + Out.hpos = In.pos; + + // Sample from the 16 surrounding points. Since the center point will be in + // the exact center of 16 texels, a 0.5f offset is needed to specify a texel + // center. + float2 texSize = float2( 1.0 / (targetSize.x - 1.0), 1.0 / (targetSize.y - 1.0) ); + + float4 uv; + uv.xy = In.uv.xy; + uv.zw = In.uv.xy; + + Out.texCoords[0] = uv; + Out.texCoords[0].x += texSize.x; + Out.texCoords[0].y += texSize.y; + Out.texCoords[0].z += texSize.x; + Out.texCoords[0].w += texSize.y; + Out.texCoords[0].x += ( 0 - 1.5 ) * texSize.x; + Out.texCoords[0].y += ( 0 - 1.5 ) * texSize.y; + Out.texCoords[0].z += ( 1 - 1.5 ) * texSize.x; + Out.texCoords[0].w += ( 0 - 1.5 ) * texSize.y; + + Out.texCoords[1] = uv; + Out.texCoords[1].x += texSize.x; + Out.texCoords[1].y += texSize.y; + Out.texCoords[1].z += texSize.x; + Out.texCoords[1].w += texSize.y; + Out.texCoords[1].x += ( 2 - 1.5 ) * texSize.x; + Out.texCoords[1].y += ( 0 - 1.5 ) * texSize.y; + Out.texCoords[1].z += ( 3 - 1.5 ) * texSize.x; + Out.texCoords[1].w += ( 0 - 1.5 ) * texSize.y; + + Out.texCoords[2] = uv; + Out.texCoords[2].x += texSize.x; + Out.texCoords[2].y += texSize.y; + Out.texCoords[2].z += texSize.x; + Out.texCoords[2].w += texSize.y; + Out.texCoords[2].x += ( 0 - 1.5 ) * texSize.x; + Out.texCoords[2].y += ( 1 - 1.5 ) * texSize.y; + Out.texCoords[2].z += ( 1 - 1.5 ) * texSize.x; + Out.texCoords[2].w += ( 1 - 1.5 ) * texSize.y; + + Out.texCoords[3] = uv; + Out.texCoords[3].x += texSize.x; + Out.texCoords[3].y += texSize.y; + Out.texCoords[3].z += texSize.x; + Out.texCoords[3].w += texSize.y; + Out.texCoords[3].x += ( 2 - 1.5 ) * texSize.x; + Out.texCoords[3].y += ( 1 - 1.5 ) * texSize.y; + Out.texCoords[3].z += ( 3 - 1.5 ) * texSize.x; + Out.texCoords[3].w += ( 1 - 1.5 ) * texSize.y; + + Out.texCoords[4] = uv; + Out.texCoords[4].x += texSize.x; + Out.texCoords[4].y += texSize.y; + Out.texCoords[4].z += texSize.x; + Out.texCoords[4].w += texSize.y; + Out.texCoords[4].x += ( 0 - 1.5 ) * texSize.x; + Out.texCoords[4].y += ( 2 - 1.5 ) * texSize.y; + Out.texCoords[4].z += ( 1 - 1.5 ) * texSize.x; + Out.texCoords[4].w += ( 2 - 1.5 ) * texSize.y; + + Out.texCoords[5] = uv; + Out.texCoords[5].x += texSize.x; + Out.texCoords[5].y += texSize.y; + Out.texCoords[5].z += texSize.x; + Out.texCoords[5].w += texSize.y; + Out.texCoords[5].x += ( 2 - 1.5 ) * texSize.x; + Out.texCoords[5].y += ( 2 - 1.5 ) * texSize.y; + Out.texCoords[5].z += ( 3 - 1.5 ) * texSize.x; + Out.texCoords[5].w += ( 2 - 1.5 ) * texSize.y; + + Out.texCoords[6] = uv; + Out.texCoords[6].x += texSize.x; + Out.texCoords[6].y += texSize.y; + Out.texCoords[6].z += texSize.x; + Out.texCoords[6].w += texSize.y; + Out.texCoords[6].x += ( 0 - 1.5 ) * texSize.x; + Out.texCoords[6].y += ( 3 - 1.5 ) * texSize.y; + Out.texCoords[6].z += ( 1 - 1.5 ) * texSize.x; + Out.texCoords[6].w += ( 3 - 1.5 ) * texSize.y; + + Out.texCoords[7] = uv; + Out.texCoords[7].x += texSize.x; + Out.texCoords[7].y += texSize.y; + Out.texCoords[7].z += texSize.x; + Out.texCoords[7].w += texSize.y; + Out.texCoords[7].x += ( 2 - 1.5 ) * texSize.x; + Out.texCoords[7].y += ( 3 - 1.5 ) * texSize.y; + Out.texCoords[7].z += ( 3 - 1.5 ) * texSize.x; + Out.texCoords[7].w += ( 3 - 1.5 ) * texSize.y; + + return Out; +} + diff --git a/Templates/Empty/game/shaders/common/postFx/hdr/finalPassCombineP.hlsl b/Templates/Empty/game/shaders/common/postFx/hdr/finalPassCombineP.hlsl new file mode 100644 index 000000000..7ac71bebd --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/hdr/finalPassCombineP.hlsl @@ -0,0 +1,95 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "../../torque.hlsl" +#include "../postFx.hlsl" + +uniform sampler2D sceneTex : register( s0 ); +uniform sampler2D luminanceTex : register( s1 ); +uniform sampler2D bloomTex : register( s2 ); +uniform sampler1D colorCorrectionTex : register( s3 ); + +uniform float2 texSize0; +uniform float2 texSize2; + +uniform float g_fEnableToneMapping; +uniform float g_fMiddleGray; +uniform float g_fWhiteCutoff; + +uniform float g_fEnableBlueShift; +uniform float3 g_fBlueShiftColor; + +uniform float g_fBloomScale; + +uniform float g_fOneOverGamma; + + +float4 main( PFXVertToPix IN ) : COLOR0 +{ + float4 sample = hdrDecode( tex2D( sceneTex, IN.uv0 ) ); + float adaptedLum = tex2D( luminanceTex, float2( 0.5f, 0.5f ) ).r; + float4 bloom = tex2D( bloomTex, IN.uv0 ); + + // For very low light conditions, the rods will dominate the perception + // of light, and therefore color will be desaturated and shifted + // towards blue. + if ( g_fEnableBlueShift > 0.0f ) + { + const float3 LUMINANCE_VECTOR = float3(0.2125f, 0.7154f, 0.0721f); + + // Define a linear blending from -1.5 to 2.6 (log scale) which + // determines the lerp amount for blue shift + float coef = 1.0f - ( adaptedLum + 1.5 ) / 4.1; + coef = saturate( coef * g_fEnableBlueShift ); + + // Lerp between current color and blue, desaturated copy + float3 rodColor = dot( sample.rgb, LUMINANCE_VECTOR ) * g_fBlueShiftColor; + sample.rgb = lerp( sample.rgb, rodColor, coef ); + + rodColor = dot( bloom.rgb, LUMINANCE_VECTOR ) * g_fBlueShiftColor; + bloom.rgb = lerp( bloom.rgb, rodColor, coef ); + } + + // Map the high range of color values into a range appropriate for + // display, taking into account the user's adaptation level, + // white point, and selected value for for middle gray. + if ( g_fEnableToneMapping > 0.0f ) + { + float Lp = (g_fMiddleGray / (adaptedLum + 0.0001)) * hdrLuminance( sample.rgb ); + //float toneScalar = ( Lp * ( 1.0 + ( Lp / ( g_fWhiteCutoff ) ) ) ) / ( 1.0 + Lp ); + float toneScalar = Lp; + sample.rgb = lerp( sample.rgb, sample.rgb * toneScalar, g_fEnableToneMapping ); + } + + // Add the bloom effect. + sample += g_fBloomScale * bloom; + + // Apply the color correction. + sample.r = tex1D( colorCorrectionTex, sample.r ).r; + sample.g = tex1D( colorCorrectionTex, sample.g ).g; + sample.b = tex1D( colorCorrectionTex, sample.b ).b; + + // Apply gamma correction + sample.rgb = pow( abs(sample.rgb), g_fOneOverGamma ); + + return sample; +} diff --git a/Templates/Empty/game/shaders/common/postFx/hdr/luminanceVisP.hlsl b/Templates/Empty/game/shaders/common/postFx/hdr/luminanceVisP.hlsl new file mode 100644 index 000000000..593a24e7b --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/hdr/luminanceVisP.hlsl @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "../postFx.hlsl" +#include "../../torque.hlsl" +#include "shadergen:/autogenConditioners.h" + + +uniform sampler2D inputTex : register(S0); +uniform float brightPassThreshold; + +float4 main( PFXVertToPix IN ) : COLOR +{ + float4 sample = hdrDecode( tex2D( inputTex, IN.uv0 ) ); + + // Determine the brightness of this particular pixel. + float lum = hdrLuminance( sample.rgb ); + + // Write the colour to the bright-pass render target + return ( float4( lum.rrr, 1 ) ); +} diff --git a/Templates/Empty/game/shaders/common/postFx/hdr/sampleLumInitialP.hlsl b/Templates/Empty/game/shaders/common/postFx/hdr/sampleLumInitialP.hlsl new file mode 100644 index 000000000..39fd9dccc --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/hdr/sampleLumInitialP.hlsl @@ -0,0 +1,59 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "../../torque.hlsl" +#include "../postFx.hlsl" + +uniform sampler2D inputTex : register( S0 ); +uniform float2 texSize0; + +uniform float g_fMinLuminace; + +static float2 gTapOffsets[9] = +{ + { -1.0, -1.0 }, { 0.0, -1.0 }, { 1.0, -1.0 }, + { -1.0, 0.0 }, { 0.0, 0.0 }, { 1.0, 0.0 }, + { -1.0, 1.0 }, { 0.0, 1.0 }, { 1.0, 1.0 } +}; + + +float4 main( PFXVertToPix IN ) : COLOR +{ + float2 tsize = 1.0 / texSize0; + + float3 sample; + float average = 0.0; + + for ( int i = 0; i < 9; i++ ) + { + // Decode the hdr value. + sample = hdrDecode( tex2D( inputTex, IN.uv0 + ( gTapOffsets[i] * tsize ) ).rgb ); + + // Get the luminance and add it to the average. + float lum = max( hdrLuminance( sample ), g_fMinLuminace ); + average += log( lum ); + } + + average = exp( average / 9.0 ); + + return float4( average, 0.0, 0.0, 1.0 ); +} diff --git a/Templates/Empty/game/shaders/common/postFx/hdr/sampleLumIterativeP.hlsl b/Templates/Empty/game/shaders/common/postFx/hdr/sampleLumIterativeP.hlsl new file mode 100644 index 000000000..59e91f0db --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/hdr/sampleLumIterativeP.hlsl @@ -0,0 +1,50 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "../postFx.hlsl" + +uniform sampler2D inputTex : register( S0 ); +uniform float2 oneOverTargetSize; + + +static float2 gTapOffsets[16] = +{ + { -1.5, -1.5 }, { -0.5, -1.5 }, { 0.5, -1.5 }, { 1.5, -1.5 }, + { -1.5, -0.5 }, { -0.5, -0.5 }, { 0.5, -0.5 }, { 1.5, -0.5 }, + { -1.5, 0.5 }, { -0.5, 0.5 }, { 0.5, 0.5 }, { 1.5, 0.5 }, + { -1.5, 1.5 }, { -0.5, 1.5 }, { 0.5, 1.5 }, { 1.5, 1.5 } +}; + +float4 main( PFXVertToPix IN ) : COLOR +{ + float2 pixelSize = oneOverTargetSize; + + float average = 0.0; + + for ( int i = 0; i < 16; i++ ) + { + float lum = tex2D( inputTex, IN.uv0 + ( gTapOffsets[i] * pixelSize ) ).r; + average += lum; + } + + return float4( average / 16.0, 0.0, 0.0, 1.0 ); +} diff --git a/Templates/Empty/game/shaders/common/postFx/lightRay/lightRayOccludeP.hlsl b/Templates/Empty/game/shaders/common/postFx/lightRay/lightRayOccludeP.hlsl new file mode 100644 index 000000000..8769905f6 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/lightRay/lightRayOccludeP.hlsl @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" +#include "../postFx.hlsl" + +uniform sampler2D backBuffer : register( s0 ); // The original backbuffer. +uniform sampler2D prepassTex : register( s1 ); // The pre-pass depth and normals. + +uniform float brightScalar; + +static const float3 LUMINANCE_VECTOR = float3(0.3125f, 0.6154f, 0.0721f); + + +float4 main( PFXVertToPix IN ) : COLOR0 +{ + float4 col = float4( 0, 0, 0, 1 ); + + // Get the depth at this pixel. + float depth = prepassUncondition( prepassTex, IN.uv0 ).w; + + // If the depth is equal to 1.0, read from the backbuffer + // and perform the exposure calculation on the result. + if ( depth >= 0.999 ) + { + col = tex2D( backBuffer, IN.uv0 ); + + //col = 1 - exp(-120000 * col); + col += dot( col, LUMINANCE_VECTOR ) + 0.0001f; + col *= brightScalar; + } + + return col; +} diff --git a/Templates/Empty/game/shaders/common/postFx/lightRay/lightRayP.hlsl b/Templates/Empty/game/shaders/common/postFx/lightRay/lightRayP.hlsl new file mode 100644 index 000000000..7dd334607 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/lightRay/lightRayP.hlsl @@ -0,0 +1,88 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "../postFx.hlsl" + +uniform sampler2D frameSampler : register( s0 ); +uniform sampler2D backBuffer : register( s1 ); + +uniform float3 camForward; +uniform float3 lightDirection; +uniform float2 screenSunPos; +uniform float2 oneOverTargetSize; +uniform int numSamples; +uniform float density; +uniform float weight; +uniform float decay; +uniform float exposure; + +float4 main( PFXVertToPix IN ) : COLOR0 +{ + float4 texCoord = float4( IN.uv0.xy, 0, 0 ); + + // Store initial sample. + half3 color = (half3)tex2D( frameSampler, texCoord.xy ).rgb; + + // Store original bb color. + float4 bbCol = tex2D( backBuffer, IN.uv1 ); + + // Set up illumination decay factor. + half illuminationDecay = 1.0; + + float amount = saturate( dot( -lightDirection, camForward ) ); + + int samples = numSamples * amount; + + if ( samples <= 0 ) + return bbCol; + + // Calculate vector from pixel to light source in screen space. + half2 deltaTexCoord = (half2)( texCoord.xy - screenSunPos ); + + // Divide by number of samples and scale by control factor. + deltaTexCoord *= 1.0 / (half)samples * density; + + // Evaluate summation from Equation 3 NUM_SAMPLES iterations. + for ( int i = 0; i < samples; i++ ) + { + // Step sample location along ray. + texCoord.xy -= deltaTexCoord; + + // Retrieve sample at new location. + half3 sample = (half3)tex2Dlod( frameSampler, texCoord ); + + // Apply sample attenuation scale/decay factors. + sample *= illuminationDecay * weight; + + // Accumulate combined color. + color += sample; + + // Update exponential decay factor. + illuminationDecay *= decay; + } + + //return saturate( amount ) * color * Exposure; + //return bbCol * decay; + + // Output final color with a further scale control factor. + return saturate( amount ) * float4( color * exposure, 1 ) + bbCol; +} diff --git a/Templates/Empty/game/shaders/common/postFx/mlaa/blendWeightCalculationP.hlsl b/Templates/Empty/game/shaders/common/postFx/mlaa/blendWeightCalculationP.hlsl new file mode 100644 index 000000000..2c4777c36 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/mlaa/blendWeightCalculationP.hlsl @@ -0,0 +1,78 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// An implementation of "Practical Morphological Anti-Aliasing" from +// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria, +// Fernando Navarro, and Diego Gutierrez. +// +// http://www.iryoku.com/mlaa/ + + +uniform sampler2D edgesMap : register(S0); +uniform sampler2D edgesMapL : register(S1); +uniform sampler2D areaMap : register(S2); + +#include "./functions.hlsl" + + +float4 main(float2 texcoord : TEXCOORD0) : COLOR0 +{ + float4 areas = 0.0; + + float2 e = tex2D(edgesMap, texcoord).rg; + + [branch] + if (e.g) // Edge at north + { + // Search distances to the left and to the right: + float2 d = float2(SearchXLeft(texcoord), SearchXRight(texcoord)); + + // Now fetch the crossing edges. Instead of sampling between edgels, we + // sample at -0.25, to be able to discern what value has each edgel: + float4 coords = mad(float4(d.x, -0.25, d.y + 1.0, -0.25), + PIXEL_SIZE.xyxy, texcoord.xyxy); + float e1 = tex2Dlevel0(edgesMapL, coords.xy).r; + float e2 = tex2Dlevel0(edgesMapL, coords.zw).r; + + // Ok, we know how this pattern looks like, now it is time for getting + // the actual area: + areas.rg = Area(abs(d), e1, e2); + } + + [branch] + if (e.r) // Edge at west + { + // Search distances to the top and to the bottom: + float2 d = float2(SearchYUp(texcoord), SearchYDown(texcoord)); + + // Now fetch the crossing edges (yet again): + float4 coords = mad(float4(-0.25, d.x, -0.25, d.y + 1.0), + PIXEL_SIZE.xyxy, texcoord.xyxy); + float e1 = tex2Dlevel0(edgesMapL, coords.xy).g; + float e2 = tex2Dlevel0(edgesMapL, coords.zw).g; + + // Get the area for this direction: + areas.ba = Area(abs(d), e1, e2); + } + + return areas; +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/postFx/mlaa/edgeDetectionP.hlsl b/Templates/Empty/game/shaders/common/postFx/mlaa/edgeDetectionP.hlsl new file mode 100644 index 000000000..364bd948f --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/mlaa/edgeDetectionP.hlsl @@ -0,0 +1,72 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// An implementation of "Practical Morphological Anti-Aliasing" from +// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria, +// Fernando Navarro, and Diego Gutierrez. +// +// http://www.iryoku.com/mlaa/ + +#include "shadergen:/autogenConditioners.h" + +uniform sampler2D colorMapG : register(S0); +uniform sampler2D prepassMap : register(S1); + +uniform float3 lumaCoefficients; +uniform float threshold; +uniform float depthThreshold; + + +float4 main( float2 texcoord : TEXCOORD0, + float4 offset[2]: TEXCOORD1) : COLOR0 +{ + // Luma calculation requires gamma-corrected colors (texture 'colorMapG'). + // + // Note that there is a lot of overlapped luma calculations; performance + // can be improved if this luma calculation is performed in the main pass, + // which may give you an edge if used in conjunction with a z prepass. + + float L = dot(tex2D(colorMapG, texcoord).rgb, lumaCoefficients); + + float Lleft = dot(tex2D(colorMapG, offset[0].xy).rgb, lumaCoefficients); + float Ltop = dot(tex2D(colorMapG, offset[0].zw).rgb, lumaCoefficients); + float Lright = dot(tex2D(colorMapG, offset[1].xy).rgb, lumaCoefficients); + float Lbottom = dot(tex2D(colorMapG, offset[1].zw).rgb, lumaCoefficients); + + float4 delta = abs(L.xxxx - float4(Lleft, Ltop, Lright, Lbottom)); + float4 edges = step(threshold, delta); + + // Add depth edges to color edges + float D = prepassUncondition(prepassMap, texcoord).w; + float Dleft = prepassUncondition(prepassMap, offset[0].xy).w; + float Dtop = prepassUncondition(prepassMap, offset[0].zw).w; + float Dright = prepassUncondition(prepassMap, offset[1].xy).w; + float Dbottom = prepassUncondition(prepassMap, offset[1].zw).w; + + delta = abs(D.xxxx - float4(Dleft, Dtop, Dright, Dbottom)); + edges += step(depthThreshold, delta); + + if (dot(edges, 1.0) == 0.0) + discard; + + return edges; +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/postFx/mlaa/functions.hlsl b/Templates/Empty/game/shaders/common/postFx/mlaa/functions.hlsl new file mode 100644 index 000000000..9935a5e30 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/mlaa/functions.hlsl @@ -0,0 +1,145 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// An implementation of "Practical Morphological Anti-Aliasing" from +// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria, +// Fernando Navarro, and Diego Gutierrez. +// +// http://www.iryoku.com/mlaa/ + + +uniform float2 texSize0; + +#if !defined(PIXEL_SIZE) +#define PIXEL_SIZE (1.0 / texSize0) +#define MAX_SEARCH_STEPS 8 +#define MAX_DISTANCE 33 +#endif + +// Typical Multiply-Add operation to ease translation to assembly code. + +float4 mad(float4 m, float4 a, float4 b) +{ + #if defined(XBOX) + float4 result; + asm { + mad result, m, a, b + }; + return result; + #else + return m * a + b; + #endif +} + + +// This one just returns the first level of a mip map chain, which allow us to +// avoid the nasty ddx/ddy warnings, even improving the performance a little +// bit. +float4 tex2Dlevel0(sampler2D map, float2 texcoord) +{ + return tex2Dlod(map, float4(texcoord, 0.0, 0.0)); +} + + +// Same as above, this eases translation to assembly code; +float4 tex2Doffset(sampler2D map, float2 texcoord, float2 offset) +{ + #if defined(XBOX) && MAX_SEARCH_STEPS < 6 + float4 result; + float x = offset.x; + float y = offset.y; + asm { + tfetch2D result, texcoord, map, OffsetX = x, OffsetY = y + }; + return result; + #else + return tex2Dlevel0(map, texcoord + PIXEL_SIZE * offset); + #endif +} + + +// Ok, we have the distance and both crossing edges, can you please return +// the float2 blending weights? +float2 Area(float2 distance, float e1, float e2) +{ + // * By dividing by areaSize - 1.0 below we are implicitely offsetting to + // always fall inside of a pixel + // * Rounding prevents bilinear access precision problems + float areaSize = MAX_DISTANCE * 5.0; + float2 pixcoord = MAX_DISTANCE * round(4.0 * float2(e1, e2)) + distance; + float2 texcoord = pixcoord / (areaSize - 1.0); + return tex2Dlevel0(areaMap, texcoord).rg; +} + + +// Search functions for the 2nd pass. +float SearchXLeft(float2 texcoord) +{ + // We compare with 0.9 to prevent bilinear access precision problems. + float i; + float e = 0.0; + for (i = -1.5; i > -2.0 * MAX_SEARCH_STEPS; i -= 2.0) + { + e = tex2Doffset(edgesMapL, texcoord, float2(i, 0.0)).g; + [flatten] if (e < 0.9) break; + } + return max(i + 1.5 - 2.0 * e, -2.0 * MAX_SEARCH_STEPS); +} + +// Search functions for the 2nd pass. +float SearchXRight(float2 texcoord) +{ + float i; + float e = 0.0; + for (i = 1.5; i < 2.0 * MAX_SEARCH_STEPS; i += 2.0) + { + e = tex2Doffset(edgesMapL, texcoord, float2(i, 0.0)).g; + [flatten] if (e < 0.9) break; + } + return min(i - 1.5 + 2.0 * e, 2.0 * MAX_SEARCH_STEPS); +} + +// Search functions for the 2nd pass. +float SearchYUp(float2 texcoord) +{ + float i; + float e = 0.0; + for (i = -1.5; i > -2.0 * MAX_SEARCH_STEPS; i -= 2.0) + { + e = tex2Doffset(edgesMapL, texcoord, float2(i, 0.0).yx).r; + [flatten] if (e < 0.9) break; + } + return max(i + 1.5 - 2.0 * e, -2.0 * MAX_SEARCH_STEPS); +} + +// Search functions for the 2nd pass. +float SearchYDown(float2 texcoord) +{ + float i; + float e = 0.0; + for (i = 1.5; i < 2.0 * MAX_SEARCH_STEPS; i += 2.0) + { + e = tex2Doffset(edgesMapL, texcoord, float2(i, 0.0).yx).r; + [flatten] if (e < 0.9) break; + } + return min(i - 1.5 + 2.0 * e, 2.0 * MAX_SEARCH_STEPS); +} diff --git a/Templates/Empty/game/shaders/common/postFx/mlaa/neighborhoodBlendingP.hlsl b/Templates/Empty/game/shaders/common/postFx/mlaa/neighborhoodBlendingP.hlsl new file mode 100644 index 000000000..aaaacafe2 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/mlaa/neighborhoodBlendingP.hlsl @@ -0,0 +1,84 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// An implementation of "Practical Morphological Anti-Aliasing" from +// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria, +// Fernando Navarro, and Diego Gutierrez. +// +// http://www.iryoku.com/mlaa/ + + +uniform sampler2D blendMap : register(S0); +uniform sampler2D colorMapL : register(S1); +uniform sampler2D colorMap : register(S2); + +// Dummy sampers to please include. +sampler2D areaMap; +sampler2D edgesMapL; +#include "./functions.hlsl" + + +float4 main( float2 texcoord : TEXCOORD0, + float4 offset[2]: TEXCOORD1 ) : COLOR0 +{ + // Fetch the blending weights for current pixel: + float4 topLeft = tex2D(blendMap, texcoord); + float bottom = tex2D(blendMap, offset[1].zw).g; + float right = tex2D(blendMap, offset[1].xy).a; + float4 a = float4(topLeft.r, bottom, topLeft.b, right); + + // Up to 4 lines can be crossing a pixel (one in each edge). So, we perform + // a weighted average, where the weight of each line is 'a' cubed, which + // favors blending and works well in practice. + float4 w = a * a * a; + + // There is some blending weight with a value greater than 0.0? + float sum = dot(w, 1.0); + if (sum < 1e-5) + discard; + + float4 color = 0.0; + + // Add the contributions of the possible 4 lines that can cross this pixel: + #ifdef BILINEAR_FILTER_TRICK + float4 coords = mad(float4( 0.0, -a.r, 0.0, a.g), PIXEL_SIZE.yyyy, texcoord.xyxy); + color = mad(tex2D(colorMapL, coords.xy), w.r, color); + color = mad(tex2D(colorMapL, coords.zw), w.g, color); + + coords = mad(float4(-a.b, 0.0, a.a, 0.0), PIXEL_SIZE.xxxx, texcoord.xyxy); + color = mad(tex2D(colorMapL, coords.xy), w.b, color); + color = mad(tex2D(colorMapL, coords.zw), w.a, color); + #else + float4 C = tex2D(colorMap, texcoord); + float4 Cleft = tex2D(colorMap, offset[0].xy); + float4 Ctop = tex2D(colorMap, offset[0].zw); + float4 Cright = tex2D(colorMap, offset[1].xy); + float4 Cbottom = tex2D(colorMap, offset[1].zw); + color = mad(lerp(C, Ctop, a.r), w.r, color); + color = mad(lerp(C, Cbottom, a.g), w.g, color); + color = mad(lerp(C, Cleft, a.b), w.b, color); + color = mad(lerp(C, Cright, a.a), w.a, color); + #endif + + // Normalize the resulting color and we are finished! + return color / sum; +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/postFx/mlaa/offsetV.hlsl b/Templates/Empty/game/shaders/common/postFx/mlaa/offsetV.hlsl new file mode 100644 index 000000000..d9c922afd --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/mlaa/offsetV.hlsl @@ -0,0 +1,42 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// An implementation of "Practical Morphological Anti-Aliasing" from +// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria, +// Fernando Navarro, and Diego Gutierrez. +// +// http://www.iryoku.com/mlaa/ + + +uniform float2 texSize0; + +void main( inout float4 position : POSITION0, + inout float2 texcoord : TEXCOORD0, + out float4 offset[2] : TEXCOORD1 ) +{ + float2 PIXEL_SIZE = 1.0 / texSize0; + + texcoord.xy += PIXEL_SIZE * 0.5; + + offset[0] = texcoord.xyxy + PIXEL_SIZE.xyxy * float4(-1.0, 0.0, 0.0, -1.0); + offset[1] = texcoord.xyxy + PIXEL_SIZE.xyxy * float4( 1.0, 0.0, 0.0, 1.0); +} diff --git a/Templates/Empty/game/shaders/common/postFx/mlaa/passthruV.hlsl b/Templates/Empty/game/shaders/common/postFx/mlaa/passthruV.hlsl new file mode 100644 index 000000000..24ef534fd --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/mlaa/passthruV.hlsl @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// An implementation of "Practical Morphological Anti-Aliasing" from +// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria, +// Fernando Navarro, and Diego Gutierrez. +// +// http://www.iryoku.com/mlaa/ + + +uniform float2 texSize0; + +void main( inout float4 position : POSITION0, + inout float2 texcoord : TEXCOORD0) +{ + float2 PIXEL_SIZE = 1.0 / texSize0; + texcoord.xy += PIXEL_SIZE * 0.5; +} diff --git a/Templates/Empty/game/shaders/common/postFx/passthruP.hlsl b/Templates/Empty/game/shaders/common/postFx/passthruP.hlsl new file mode 100644 index 000000000..8a29d0091 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/passthruP.hlsl @@ -0,0 +1,30 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "./postFx.hlsl" + +uniform sampler2D inputTex : register(S0); + +float4 main( PFXVertToPix IN ) : COLOR +{ + return tex2D( inputTex, IN.uv0 ); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/postFx/postFx.hlsl b/Templates/Empty/game/shaders/common/postFx/postFx.hlsl new file mode 100644 index 000000000..6f28168e2 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/postFx.hlsl @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +struct PFXVert +{ + float4 pos : POSITION; + float2 uv : TEXCOORD0; + float3 wsEyeRay : TEXCOORD1; +}; + +struct PFXVertToPix +{ + float4 hpos : POSITION; + float2 uv0 : TEXCOORD0; + float2 uv1 : TEXCOORD1; + float2 uv2 : TEXCOORD2; + float2 uv3 : TEXCOORD3; + float3 wsEyeRay : TEXCOORD4; +}; diff --git a/Templates/Empty/game/shaders/common/postFx/postFxV.glsl b/Templates/Empty/game/shaders/common/postFx/postFxV.glsl new file mode 100644 index 000000000..3aded2e0f --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/postFxV.glsl @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "./../gl/torque.glsl" + + +uniform vec4 rtParams0; +uniform vec4 rtParams1; +uniform vec4 rtParams2; +uniform vec4 rtParams3; + +varying vec2 uv0; +varying vec2 uv1; +varying vec2 uv2; +varying vec2 uv3; +varying vec3 wsEyeRay; + + +void main() +{ + gl_Position = gl_Vertex; + + uv0 = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams0 ); + uv1 = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams1 ); + uv2 = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams2 ); + uv3 = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams3 ); + + wsEyeRay = gl_MultiTexCoord1.xyz; +} diff --git a/Templates/Empty/game/shaders/common/postFx/postFxV.hlsl b/Templates/Empty/game/shaders/common/postFx/postFxV.hlsl new file mode 100644 index 000000000..b7511e8db --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/postFxV.hlsl @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "./postFx.hlsl" +#include "./../torque.hlsl" + + +uniform float4 rtParams0; +uniform float4 rtParams1; +uniform float4 rtParams2; +uniform float4 rtParams3; + +PFXVertToPix main( PFXVert IN ) +{ + PFXVertToPix OUT; + + OUT.hpos = IN.pos; + OUT.uv0 = viewportCoordToRenderTarget( IN.uv, rtParams0 ); + OUT.uv1 = viewportCoordToRenderTarget( IN.uv, rtParams1 ); + OUT.uv2 = viewportCoordToRenderTarget( IN.uv, rtParams2 ); + OUT.uv3 = viewportCoordToRenderTarget( IN.uv, rtParams3 ); + + OUT.wsEyeRay = IN.wsEyeRay; + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/postFx/ssao/SSAO_Blur_P.hlsl b/Templates/Empty/game/shaders/common/postFx/ssao/SSAO_Blur_P.hlsl new file mode 100644 index 000000000..a6085e4bf --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/ssao/SSAO_Blur_P.hlsl @@ -0,0 +1,106 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" +//#include "./../postFx.hlsl" + +uniform sampler2D occludeMap : register(S0); +uniform sampler2D prepassMap : register(S1); + +struct VertToPix +{ + float4 hpos : POSITION; + + float4 uv0 : TEXCOORD0; + float2 uv1 : TEXCOORD1; + float2 uv2 : TEXCOORD2; + float2 uv3 : TEXCOORD3; + + float2 uv4 : TEXCOORD4; + float2 uv5 : TEXCOORD5; + float2 uv6 : TEXCOORD6; + float2 uv7 : TEXCOORD7; +}; + + +uniform float blurDepthTol; +uniform float blurNormalTol; + + +void sample( float2 uv, float weight, float4 centerTap, inout int usedCount, inout float occlusion, inout float total ) +{ + //return; + float4 tap = prepassUncondition( prepassMap, uv ); + + if ( abs( tap.a - centerTap.a ) < blurDepthTol ) + { + if ( dot( tap.xyz, centerTap.xyz ) > blurNormalTol ) + { + usedCount++; + total += weight; + occlusion += tex2D( occludeMap, uv ).r * weight; + } + } +} + +float4 main( VertToPix IN ) : COLOR +{ + //float4 centerTap; + float4 centerTap = prepassUncondition( prepassMap, IN.uv0.zw ); + + //return centerTap; + + //float centerOcclude = tex2D( occludeMap, IN.uv0.zw ).r; + //return float4( centerOcclude.rrr, 1 ); + + float4 kernel = float4( 0.175, 0.275, 0.375, 0.475 ); //25f; + + float occlusion = 0; + int usedCount = 0; + float total = 0.0; + + sample( IN.uv0.xy, kernel.x, centerTap, usedCount, occlusion, total ); + sample( IN.uv1, kernel.y, centerTap, usedCount, occlusion, total ); + sample( IN.uv2, kernel.z, centerTap, usedCount, occlusion, total ); + sample( IN.uv3, kernel.w, centerTap, usedCount, occlusion, total ); + + sample( IN.uv4, kernel.x, centerTap, usedCount, occlusion, total ); + sample( IN.uv5, kernel.y, centerTap, usedCount, occlusion, total ); + sample( IN.uv6, kernel.z, centerTap, usedCount, occlusion, total ); + sample( IN.uv7, kernel.w, centerTap, usedCount, occlusion, total ); + + occlusion += tex2D( occludeMap, IN.uv0.zw ).r * 0.5; + total += 0.5; + //occlusion /= 3.0; + + //occlusion /= (float)usedCount / 8.0; + occlusion /= total; + + return float4( occlusion.rrr, 1 ); + + + //return float4( 0,0,0,occlusion ); + + //float3 color = tex2D( colorMap, IN.uv0.zw ); + + //return float4( color, occlusion ); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/postFx/ssao/SSAO_Blur_V.hlsl b/Templates/Empty/game/shaders/common/postFx/ssao/SSAO_Blur_V.hlsl new file mode 100644 index 000000000..cdf31a01f --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/ssao/SSAO_Blur_V.hlsl @@ -0,0 +1,86 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "./../postFx.hlsl" +#include "./../../torque.hlsl" + + +uniform float2 texSize0; +uniform float4 rtParams0; +uniform float2 oneOverTargetSize; + +struct VertToPix +{ + float4 hpos : POSITION; + + float4 uv0 : TEXCOORD0; + float2 uv1 : TEXCOORD1; + float2 uv2 : TEXCOORD2; + float2 uv3 : TEXCOORD3; + + float2 uv4 : TEXCOORD4; + float2 uv5 : TEXCOORD5; + float2 uv6 : TEXCOORD6; + float2 uv7 : TEXCOORD7; +}; + +VertToPix main( PFXVert IN ) +{ + VertToPix OUT; + + OUT.hpos = IN.pos; + + IN.uv = viewportCoordToRenderTarget( IN.uv, rtParams0 ); + + //float4 step = float4( 3.5, 2.5, 1.5, 0.5 ); + //float4 step = float4( 4.0, 3.0, 2.0, 1.0 ); + float4 step = float4( 9.0, 5.0, 2.5, 0.5 ); + + // I don't know why this offset is necessary, but it is. + //IN.uv = IN.uv * oneOverTargetSize; + + OUT.uv0.xy = IN.uv + ( ( BLUR_DIR * step.x ) / texSize0 ); + OUT.uv1 = IN.uv + ( ( BLUR_DIR * step.y ) / texSize0 ); + OUT.uv2 = IN.uv + ( ( BLUR_DIR * step.z ) / texSize0 ); + OUT.uv3 = IN.uv + ( ( BLUR_DIR * step.w ) / texSize0 ); + + OUT.uv4 = IN.uv - ( ( BLUR_DIR * step.x ) / texSize0 ); + OUT.uv5 = IN.uv - ( ( BLUR_DIR * step.y ) / texSize0 ); + OUT.uv6 = IN.uv - ( ( BLUR_DIR * step.z ) / texSize0 ); + OUT.uv7 = IN.uv - ( ( BLUR_DIR * step.w ) / texSize0 ); + + OUT.uv0.zw = IN.uv; + + /* + OUT.uv0 = viewportCoordToRenderTarget( OUT.uv0, rtParams0 ); + OUT.uv1 = viewportCoordToRenderTarget( OUT.uv1, rtParams0 ); + OUT.uv2 = viewportCoordToRenderTarget( OUT.uv2, rtParams0 ); + OUT.uv3 = viewportCoordToRenderTarget( OUT.uv3, rtParams0 ); + + OUT.uv4 = viewportCoordToRenderTarget( OUT.uv4, rtParams0 ); + OUT.uv5 = viewportCoordToRenderTarget( OUT.uv5, rtParams0 ); + OUT.uv6 = viewportCoordToRenderTarget( OUT.uv6, rtParams0 ); + OUT.uv7 = viewportCoordToRenderTarget( OUT.uv7, rtParams0 ); + */ + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/postFx/ssao/SSAO_P.hlsl b/Templates/Empty/game/shaders/common/postFx/ssao/SSAO_P.hlsl new file mode 100644 index 000000000..b0521c697 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/ssao/SSAO_P.hlsl @@ -0,0 +1,272 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" +#include "./../postFx.hlsl" + +#define DOSMALL +#define DOLARGE + +uniform sampler2D prepassMap : register(S0); +uniform sampler2D randNormalTex : register(S1); +uniform sampler1D powTable : register(S2); + +uniform float2 nearFar; +uniform float2 worldToScreenScale; +uniform float2 texSize0; +uniform float2 texSize1; +uniform float2 targetSize; + +// Script-set constants. + +uniform float overallStrength; + +uniform float sRadius; +uniform float sStrength; +uniform float sDepthMin; +uniform float sDepthMax; +uniform float sDepthPow; +uniform float sNormalTol; +uniform float sNormalPow; + +uniform float lRadius; +uniform float lStrength; +uniform float lDepthMin; +uniform float lDepthMax; +uniform float lDepthPow; +uniform float lNormalTol; +uniform float lNormalPow; + + +#ifndef QUALITY + #define QUALITY 2 +#endif + + +#if QUALITY == 0 + #define sSampleCount 4 + #define totalSampleCount 12 +#elif QUALITY == 1 + #define sSampleCount 6 + #define totalSampleCount 24 +#elif QUALITY == 2 + #define sSampleCount 8 + #define totalSampleCount 32 +#endif + + +float getOcclusion( float depthDiff, float depthMin, float depthMax, float depthPow, + float normalDiff, float dt, float normalTol, float normalPow ) +{ + if ( depthDiff < 0.0 ) + return 0.0; + + float delta = abs( depthDiff ); + + if ( delta < depthMin || delta > depthMax ) + return 0.0; + + delta = saturate( delta / depthMax ); + + if ( dt > 0.0 ) + normalDiff *= dt; + else + normalDiff = 1.0; + + + normalDiff *= 1.0 - ( dt * 0.5 + 0.5 ); + + return ( 1.0 - tex1D( powTable, delta ).r ) * normalDiff; +} + + +float4 main( PFXVertToPix IN ) : COLOR +{ + float3 ptSphere[32] = + { + float3( 0.295184, 0.077723, 0.068429 ), + float3( -0.271976, -0.365221, -0.838363 ), + float3( 0.547713, 0.467576, 0.488515 ), + float3( 0.662808, -0.031733, -0.584758 ), + float3( -0.025717, 0.218955, -0.657094 ), + float3( -0.310153, -0.365223, -0.370701 ), + float3( -0.101407, -0.006313, -0.747665 ), + float3( -0.769138, 0.360399, -0.086847 ), + float3( -0.271988, -0.275140, -0.905353 ), + float3( 0.096740, -0.566901, 0.700151 ), + float3( 0.562872, -0.735136, -0.094647 ), + float3( 0.379877, 0.359278, 0.190061 ), + float3( 0.519064, -0.023055, 0.405068 ), + float3( -0.301036, 0.114696, -0.088885 ), + float3( -0.282922, 0.598305, 0.487214 ), + float3( -0.181859, 0.251670, -0.679702 ), + float3( -0.191463, -0.635818, -0.512919 ), + float3( -0.293655, 0.427423, 0.078921 ), + float3( -0.267983, 0.680534, -0.132880 ), + float3( 0.139611, 0.319637, 0.477439 ), + float3( -0.352086, 0.311040, 0.653913 ), + float3( 0.321032, 0.805279, 0.487345 ), + float3( 0.073516, 0.820734, -0.414183 ), + float3( -0.155324, 0.589983, -0.411460 ), + float3( 0.335976, 0.170782, -0.527627 ), + float3( 0.463460, -0.355658, -0.167689 ), + float3( 0.222654, 0.596550, -0.769406 ), + float3( 0.922138, -0.042070, 0.147555 ), + float3( -0.727050, -0.329192, 0.369826 ), + float3( -0.090731, 0.533820, 0.463767 ), + float3( -0.323457, -0.876559, -0.238524 ), + float3( -0.663277, -0.372384, -0.342856 ) + }; + + // Sample a random normal for reflecting the + // sphere vector later in our loop. + float4 noiseMapUV = float4( ( IN.uv1 * ( targetSize / texSize1 ) ).xy, 0, 0 ); + float3 reflectNormal = normalize( tex2Dlod( randNormalTex, noiseMapUV ).xyz * 2.0 - 1.0 ); + //return float4( reflectNormal, 1 ); + + float4 prepass = prepassUncondition( prepassMap, IN.uv0 ); + float3 normal = prepass.xyz; + float depth = prepass.a; + //return float4( ( depth ).xxx, 1 ); + + // Early out if too far away. + if ( depth > 0.99999999 ) + return float4( 0,0,0,0 ); + + // current fragment coords in screen space + float3 ep = float3( IN.uv0, depth ); + + float bl; + float3 baseRay, ray, se, occNorm, projRadius; + float normalDiff = 0; + float depthMin, depthMax, dt, depthDiff; + float4 occluderFragment; + int i; + float sOcclusion = 0.0; + float lOcclusion = 0.0; + + //------------------------------------------------------------ + // Small radius + //------------------------------------------------------------ + +#ifdef DOSMALL + + bl = 0.0; + + projRadius.xy = ( float2( sRadius.rr ) / ( depth * nearFar.y ) ) * ( worldToScreenScale / texSize0 ); + projRadius.z = sRadius / nearFar.y; + + depthMin = projRadius.z * sDepthMin; + depthMax = projRadius.z * sDepthMax; + + //float maxr = 1; + //radiusDepth = clamp( radiusDepth, 0.0001, maxr.rrr ); + //if ( radiusDepth.x < 1.0 / targetSize.x ) + // return color; + //radiusDepth.xyz = 0.0009; + + for ( i = 0; i < sSampleCount; i++ ) + { + baseRay = reflect( ptSphere[i], reflectNormal ); + + dt = dot( baseRay.xyz, normal ); + + baseRay *= sign( dt ); + + ray = ( projRadius * baseRay.xzy ); + ray.y = -ray.y; + + se = ep + ray; + + occluderFragment = prepassUncondition( prepassMap, se.xy ); + + depthDiff = se.z - occluderFragment.a; + + dt = dot( occluderFragment.xyz, baseRay.xyz ); + normalDiff = dot( occluderFragment.xyz, normal ); + + bl += getOcclusion( depthDiff, depthMin, depthMax, sDepthPow, normalDiff, dt, sNormalTol, sNormalPow ); + } + + sOcclusion = sStrength * ( bl / (float)sSampleCount ); + +#endif // DOSMALL + + + //------------------------------------------------------------ + // Large radius + //------------------------------------------------------------ + +#ifdef DOLARGE + + bl = 0.0; + + projRadius.xy = ( float2( lRadius.rr ) / ( depth * nearFar.y ) ) * ( worldToScreenScale / texSize0 ); + projRadius.z = lRadius / nearFar.y; + + depthMin = projRadius.z * lDepthMin; + depthMax = projRadius.z * lDepthMax; + + //projRadius.xy = clamp( projRadius.xy, 0.0, 0.01 ); + //float maxr = 1; + //radiusDepth = clamp( radiusDepth, 0.0001, maxr.rrr ); + //if ( radiusDepth.x < 1.0 / targetSize.x ) + // return color; + //radiusDepth.xyz = 0.0009; + + for ( i = sSampleCount; i < totalSampleCount; i++ ) + { + baseRay = reflect( ptSphere[i], reflectNormal ); + + dt = dot( baseRay.xyz, normal ); + + baseRay *= sign( dt ); + + ray = ( projRadius * baseRay.xzy ); + ray.y = -ray.y; + + se = ep + ray; + + occluderFragment = prepassUncondition( prepassMap, se.xy ); + + depthDiff = se.z - occluderFragment.a; + + normalDiff = dot( occluderFragment.xyz, normal ); + dt = dot( occluderFragment.xyz, baseRay.xyz ); + + bl += getOcclusion( depthDiff, depthMin, depthMax, lDepthPow, normalDiff, dt, lNormalTol, lNormalPow ); + } + + lOcclusion = lStrength * ( bl / (float)( totalSampleCount - sSampleCount ) ); + +#endif // DOLARGE + + float occlusion = saturate( max( sOcclusion, lOcclusion ) * overallStrength ); + + // Note black is unoccluded and white is fully occluded. This + // seems backwards, but it makes it simple to deal with the SSAO + // being disabled in the lighting shaders. + + return occlusion; +} + + diff --git a/Templates/Empty/game/shaders/common/postFx/ssao/SSAO_PowerTable_P.hlsl b/Templates/Empty/game/shaders/common/postFx/ssao/SSAO_PowerTable_P.hlsl new file mode 100644 index 000000000..359aabf85 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/ssao/SSAO_PowerTable_P.hlsl @@ -0,0 +1,29 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "./../postFx.hlsl" + +float4 main( PFXVertToPix IN ) : COLOR +{ + float power = pow( max( IN.uv0.x, 0 ), 0.1 ); + return float4( power, 0, 0, 1 ); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/postFx/ssao/SSAO_PowerTable_V.hlsl b/Templates/Empty/game/shaders/common/postFx/ssao/SSAO_PowerTable_V.hlsl new file mode 100644 index 000000000..614a24928 --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/ssao/SSAO_PowerTable_V.hlsl @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "./../postFx.hlsl" +#include "./../../torque.hlsl" + + +uniform float4 rtParams0; +uniform float4 rtParams1; +uniform float4 rtParams2; +uniform float4 rtParams3; + +PFXVertToPix main( PFXVert IN ) +{ + PFXVertToPix OUT; + + OUT.hpos = IN.pos; + OUT.uv0 = IN.uv; //viewportCoordToRenderTarget( IN.uv, rtParams0 ); + OUT.uv1 = IN.uv; //viewportCoordToRenderTarget( IN.uv, rtParams1 ); + OUT.uv2 = IN.uv; //viewportCoordToRenderTarget( IN.uv, rtParams2 ); + OUT.uv3 = IN.uv; //viewportCoordToRenderTarget( IN.uv, rtParams3 ); + + OUT.wsEyeRay = IN.wsEyeRay; + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/postFx/underwaterFogP.hlsl b/Templates/Empty/game/shaders/common/postFx/underwaterFogP.hlsl new file mode 100644 index 000000000..a0aa90ecd --- /dev/null +++ b/Templates/Empty/game/shaders/common/postFx/underwaterFogP.hlsl @@ -0,0 +1,138 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" +#include "./postFx.hlsl" +#include "../torque.hlsl" + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- + +// oceanFogData +#define FOG_DENSITY waterFogData[0] +#define FOG_DENSITY_OFFSET waterFogData[1] +#define WET_DEPTH waterFogData[2] +#define WET_DARKENING waterFogData[3] + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- + +uniform sampler2D prepassTex : register(S0); +uniform sampler2D backbuffer : register(S1); +uniform sampler1D waterDepthGradMap : register(S2); +uniform float3 eyePosWorld; +uniform float3 ambientColor; +uniform float4 waterColor; +uniform float4 waterFogData; +uniform float4 waterFogPlane; +uniform float2 nearFar; +uniform float4 rtParams0; +uniform float waterDepthGradMax; + + +float4 main( PFXVertToPix IN ) : COLOR +{ + //float2 prepassCoord = IN.uv0; + //IN.uv0 = ( IN.uv0.xy * rtParams0.zw ) + rtParams0.xy; + float depth = prepassUncondition( prepassTex, IN.uv0 ).w; + //return float4( depth.rrr, 1 ); + + // Skip fogging the extreme far plane so that + // the canvas clear color always appears. + //clip( 0.9 - depth ); + + // We assume that the eye position is below water because + // otherwise this shader/posteffect should not be active. + + depth *= nearFar.y; + + float3 eyeRay = normalize( IN.wsEyeRay ); + + float3 rayStart = eyePosWorld; + float3 rayEnd = eyePosWorld + ( eyeRay * depth ); + //return float4( rayEnd, 1 ); + + float4 plane = waterFogPlane; //float4( 0, 0, 1, -waterHeight ); + //plane.w -= 0.15; + + float startSide = dot( plane.xyz, rayStart ) + plane.w; + if ( startSide > 0 ) + { + rayStart.z -= ( startSide ); + //return float4( 1, 0, 0, 1 ); + } + + float3 hitPos; + float3 ray = rayEnd - rayStart; + float rayLen = length( ray ); + float3 rayDir = normalize( ray ); + + float endSide = dot( plane.xyz, rayEnd ) + plane.w; + float planeDist; + + if ( endSide < -0.005 ) + { + //return float4( 0, 0, 1, 1 ); + hitPos = rayEnd; + planeDist = endSide; + } + else + { + //return float4( 0, 0, 0, 0 ); + float den = dot( ray, plane.xyz ); + + // Parallal to the plane, return the endPnt. + //if ( den == 0.0f ) + // return endPnt; + + float dist = -( dot( plane.xyz, rayStart ) + plane.w ) / den; + if ( dist < 0.0 ) + dist = 0.0; + //return float4( 1, 0, 0, 1 ); + //return float4( ( dist ).rrr, 1 ); + + + hitPos = lerp( rayStart, rayEnd, dist ); + + planeDist = dist; + } + + float delta = length( hitPos - rayStart ); + + float fogAmt = 1.0 - saturate( exp( -FOG_DENSITY * ( delta - FOG_DENSITY_OFFSET ) ) ); + //return float4( fogAmt.rrr, 1 ); + + // Calculate the water "base" color based on depth. + float4 fogColor = waterColor * tex1D( waterDepthGradMap, saturate( delta / waterDepthGradMax ) ); + // Modulate baseColor by the ambientColor. + fogColor *= float4( ambientColor.rgb, 1 ); + + float3 inColor = hdrDecode( tex2D( backbuffer, IN.uv0 ).rgb ); + inColor.rgb *= 1.0 - saturate( abs( planeDist ) / WET_DEPTH ) * WET_DARKENING; + //return float4( inColor, 1 ); + + float3 outColor = lerp( inColor, fogColor, fogAmt ); + + return float4( hdrEncode( outColor ), 1 ); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/precipP.hlsl b/Templates/Empty/game/shaders/common/precipP.hlsl new file mode 100644 index 000000000..2d33e421c --- /dev/null +++ b/Templates/Empty/game/shaders/common/precipP.hlsl @@ -0,0 +1,49 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +struct Conn +{ + float2 texCoord : TEXCOORD0; + float4 color : COLOR0; +}; + +struct Frag +{ + float4 col : COLOR0; +}; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Frag main( Conn In, + uniform sampler2D diffuseMap : register(S0) +) +{ + Frag Out; + + Out.col = tex2D(diffuseMap, In.texCoord) * In.color; + + return Out; +} diff --git a/Templates/Empty/game/shaders/common/precipV.hlsl b/Templates/Empty/game/shaders/common/precipV.hlsl new file mode 100644 index 000000000..1d5c05fc6 --- /dev/null +++ b/Templates/Empty/game/shaders/common/precipV.hlsl @@ -0,0 +1,67 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//***************************************************************************** +// Precipitation vertex shader +//***************************************************************************** +//----------------------------------------------------------------------------- +// Constants +//----------------------------------------------------------------------------- +struct Vert +{ + float4 position : POSITION; + float4 texCoord : TEXCOORD0; +}; + +struct Conn +{ + float4 position : POSITION; + float4 texCoord : TEXCOORD0; + float4 color : COLOR0; +}; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Conn main( Vert In, + uniform float4x4 modelview : register(C0), + uniform float2 fadeStartEnd : register(C4), + uniform float3 cameraPos : register(C5), + uniform float3 ambient : register(C6) +) +{ + Conn Out; + + Out.position = mul(modelview, In.position); + Out.texCoord = In.texCoord; + Out.color = float4( ambient.r, ambient.g, ambient.b, 1 ); + + // Do we need to do a distance fade? + if ( fadeStartEnd.x < fadeStartEnd.y ) { + + float distance = length( cameraPos - In.position ); + Out.color.a = abs( clamp( ( distance - fadeStartEnd.x ) / ( fadeStartEnd.y - fadeStartEnd.x ), 0, 1 ) - 1 ); + } + + return Out; +} + diff --git a/Templates/Empty/game/shaders/common/projectedShadowP.hlsl b/Templates/Empty/game/shaders/common/projectedShadowP.hlsl new file mode 100644 index 000000000..aed42723c --- /dev/null +++ b/Templates/Empty/game/shaders/common/projectedShadowP.hlsl @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +struct Conn +{ + float2 texCoord : TEXCOORD0; + float4 color : COLOR0; + float fade : TEXCOORD1; +}; + +uniform sampler2D inputTex : register(S0); +uniform float4 ambient; + +float4 main( Conn IN ) : COLOR0 +{ + float shadow = tex2D( inputTex, IN.texCoord ).a * IN.color.a; + return ( ambient * shadow ) + ( 1 - shadow ); +} diff --git a/Templates/Empty/game/shaders/common/projectedShadowV.hlsl b/Templates/Empty/game/shaders/common/projectedShadowV.hlsl new file mode 100644 index 000000000..77f4da0c0 --- /dev/null +++ b/Templates/Empty/game/shaders/common/projectedShadowV.hlsl @@ -0,0 +1,58 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +struct Vert +{ + float3 position : POSITION; + float3 normal : NORMAL; + float3 T : TANGENT; + float4 color : COLOR0; + float2 texCoord : TEXCOORD0; +}; + +struct Conn +{ + float4 position : POSITION; + float4 color : COLOR0; + float2 texCoord : TEXCOORD0; + float fade : TEXCOORD1; +}; + +uniform float4x4 modelview; +uniform float shadowLength; +uniform float3 shadowCasterPosition; + +Conn main( Vert In ) +{ + Conn Out; + + // Decals are in world space. + Out.position = mul( modelview, float4( In.position.xyz, 1.0 ) ); + + Out.color = In.color; + Out.texCoord = In.texCoord; + + float fromCasterDist = length( In.position.xyz - shadowCasterPosition ) - shadowLength; + Out.fade = 1.0 - saturate( fromCasterDist / shadowLength ); + + return Out; +} diff --git a/Templates/Empty/game/shaders/common/scatterSkyP.hlsl b/Templates/Empty/game/shaders/common/scatterSkyP.hlsl new file mode 100644 index 000000000..572abdd74 --- /dev/null +++ b/Templates/Empty/game/shaders/common/scatterSkyP.hlsl @@ -0,0 +1,67 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "torque.hlsl" + + +struct Conn +{ + float4 rayleighColor : TEXCOORD0; + float4 mieColor : TEXCOORD1; + float3 v3Direction : TEXCOORD2; + float3 pos : TEXCOORD3; +}; + +uniform samplerCUBE nightSky : register(S0); +uniform float4 nightColor; +uniform float2 nightInterpAndExposure; +uniform float useCubemap; +uniform float3 lightDir; +uniform float3 sunDir; + +float4 main( Conn In ) : COLOR0 +{ + + float fCos = dot( lightDir, In.v3Direction ) / length(In.v3Direction); + float fCos2 = fCos*fCos; + + float g = -0.991; + float g2 = -0.991 * -0.991; + + float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos2) / pow(abs(1.0 + g2 - 2.0*g*fCos), 1.5); + + float4 color = In.rayleighColor + fMiePhase * In.mieColor; + color.a = color.b; + + float4 Out; + + float4 nightSkyColor = texCUBE( nightSky, -In.v3Direction ); + nightSkyColor = lerp( nightColor, nightSkyColor, useCubemap ); + + float fac = dot( normalize( In.pos ), sunDir ); + fac = max( nightInterpAndExposure.y, pow( saturate( fac ), 2 ) ); + Out = lerp( color, nightSkyColor, nightInterpAndExposure.y ); + + Out.a = 1; + + return hdrEncode( Out ); +} diff --git a/Templates/Empty/game/shaders/common/scatterSkyV.hlsl b/Templates/Empty/game/shaders/common/scatterSkyV.hlsl new file mode 100644 index 000000000..649922a4e --- /dev/null +++ b/Templates/Empty/game/shaders/common/scatterSkyV.hlsl @@ -0,0 +1,144 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +// The scale equation calculated by Vernier's Graphical Analysis +float vernierScale(float fCos) +{ + float x = 1.0 - fCos; + float x5 = x * 5.25; + float x5p6 = (-6.80 + x5); + float xnew = (3.83 + x * x5p6); + float xfinal = (0.459 + x * xnew); + float xfinal2 = -0.00287 + x * xfinal; + float outx = exp( xfinal2 ); + return 0.25 * outx; +} + +// This is the shader input vertex structure. +struct Vert +{ + // .xyz = point + float4 position : POSITION; + + float3 normal : NORMAL; + + float4 color : TEXCOORD0; +}; + +// This is the shader output data. +struct Conn +{ + float4 position : POSITION; + float4 rayleighColor : TEXCOORD0; + float4 mieColor : TEXCOORD1; + float3 v3Direction : TEXCOORD2; + float3 pos : TEXCOORD3; +}; + +Conn main( Vert In, + uniform float4x4 modelView : register(C0), + uniform float4 misc : register(C4), + uniform float4 sphereRadii : register(C5), + uniform float4 scatteringCoeffs : register(C6), + uniform float3 camPos : register(C7), + uniform float3 lightDir : register(C8), + uniform float4 invWaveLength : register(C9) + ) +{ + // Pull some variables out: + float camHeight = misc.x; + float camHeightSqr = misc.y; + + float scale = misc.z; + float scaleOverScaleDepth = misc.w; + + float outerRadius = sphereRadii.x; + float outerRadiusSqr = sphereRadii.y; + + float innerRadius = sphereRadii.z; + float innerRadiusSqr = sphereRadii.w; + + float rayleighBrightness = scatteringCoeffs.x; // Kr * ESun + float rayleigh4PI = scatteringCoeffs.y; // Kr * 4 * PI + + float mieBrightness = scatteringCoeffs.z; // Km * ESun + float mie4PI = scatteringCoeffs.w; // Km * 4 * PI + + // Get the ray from the camera to the vertex, + // and its length (which is the far point of the ray + // passing through the atmosphere). + float4 v3Pos = In.position / 6378000.0; // outerRadius; + float3 newCamPos = float3( 0, 0, camHeight ); + v3Pos.z += innerRadius; + float3 v3Ray = v3Pos.xyz - newCamPos; + float fFar = length(v3Ray); + v3Ray /= fFar; + + // Calculate the ray's starting position, + // then calculate its scattering offset. + float3 v3Start = newCamPos; + float fHeight = length(v3Start); + float fDepth = exp(scaleOverScaleDepth * (innerRadius - camHeight)); + float fStartAngle = dot(v3Ray, v3Start) / fHeight; + + float fStartOffset = fDepth * vernierScale( fStartAngle ); + + // Initialize the scattering loop variables. + float fSampleLength = fFar / 2; + float fScaledLength = fSampleLength * scale; + float3 v3SampleRay = v3Ray * fSampleLength; + float3 v3SamplePoint = v3Start + v3SampleRay * 0.5; + + // Now loop through the sample rays + float3 v3FrontColor = float3(0.0, 0.0, 0.0); + for(int i=0; i<2; i++) + { + float fHeight = length(v3SamplePoint); + float fDepth = exp(scaleOverScaleDepth * (innerRadius - fHeight)); + float fLightAngle = dot(lightDir, v3SamplePoint) / fHeight; + float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight; + + float vscale3 = vernierScale( fCameraAngle ); + float vscale2 = vernierScale( fLightAngle ); + + float fScatter = (fStartOffset + fDepth*(vscale2 - vscale3)); + float3 v3Attenuate = exp(-fScatter * (invWaveLength.xyz * rayleigh4PI + mie4PI)); + v3FrontColor += v3Attenuate * (fDepth * fScaledLength); + v3SamplePoint += v3SampleRay; + } + + Conn Out; + + // Finally, scale the Mie and Rayleigh colors + // and set up the varying variables for the pixel shader. + Out.position = mul( modelView, In.position ); + Out.mieColor.rgb = v3FrontColor * mieBrightness; + Out.mieColor.a = 1.0f; + Out.rayleighColor.rgb = v3FrontColor * (invWaveLength.xyz * rayleighBrightness); + Out.rayleighColor.a = 1.0f; + Out.v3Direction = newCamPos - v3Pos.xyz; + Out.pos = In.position.xyz; + + return Out; +} + diff --git a/Templates/Empty/game/shaders/common/shdrConsts.h b/Templates/Empty/game/shaders/common/shdrConsts.h new file mode 100644 index 000000000..8c262b76a --- /dev/null +++ b/Templates/Empty/game/shaders/common/shdrConsts.h @@ -0,0 +1,117 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#ifdef IN_HLSL + +#define VC_WORLD_PROJ C0 + +#define VC_TEX_TRANS1 C4 +#define VC_LIGHT_TRANS C8 +#define VC_OBJ_TRANS C12 + +#define VC_CUBE_TRANS C16 +#define VC_CUBE_EYE_POS C19 // in cubemap space +#define VC_EYE_POS C20 // in object space +#define VC_MAT_SPECPOWER C21 + +#define VC_FOGDATA C22 + +#define VC_LIGHT_POS1 C23 +#define VC_LIGHT_DIR1 C24 +#define VC_LIGHT_DIFFUSE1 C25 +#define VC_LIGHT_SPEC1 C26 + +#define VC_LIGHT_POS2 C27 +//#define VC_LIGHT_DIR2 C28 +//#define VC_LIGHT_DIFFUSE2 C29 +//#define VC_LIGHT_SPEC2 C30 +#define VC_LIGHT_TRANS2 C31 + +//#define VC_LIGHT_POS4 C35 +//#define VC_LIGHT_DIR4 C36 +//#define VC_LIGHT_DIFFUSE4 C37 +//#define VC_LIGHT_SPEC4 C38 + +#define VC_DETAIL_SCALE C40 + + +#define PC_MAT_SPECCOLOR C0 +#define PC_MAT_SPECPOWER C1 +#define PC_DIFF_COLOR C2 +#define PC_AMBIENT_COLOR C3 +#define PC_ACCUM_TIME C4 +#define PC_DIFF_COLOR2 C5 +#define PC_VISIBILITY C6 +#define PC_COLORMULTIPLY C7 + +#define PC_USERDEF1 C8 + +// Mirror of above. Couldn't be cleaner because HLSL doesn't support function macros +#else + +#define VC_WORLD_PROJ 0 + +#define VC_TEX_TRANS1 4 +#define VC_LIGHT_TRANS 8 +#define VC_OBJ_TRANS 12 + +#define VC_CUBE_TRANS 16 +#define VC_CUBE_EYE_POS 19 // in cubemap space +#define VC_EYE_POS 20 // in object space +#define VC_MAT_SPECPOWER 21 + +#define VC_FOGDATA 22 + +#define VC_LIGHT_POS1 23 +#define VC_LIGHT_DIR1 24 +#define VC_LIGHT_DIFFUSE1 25 +#define VC_LIGHT_SPEC1 26 + +#define VC_LIGHT_POS2 27 +//#define VC_LIGHT_DIR2 28 +//#define VC_LIGHT_DIFFUSE2 29 +//#define VC_LIGHT_SPEC2 30 +#define VC_LIGHT_TRANS2 31 + +//#define VC_LIGHT_POS4 35 +//#define VC_LIGHT_DIR4 36 +//#define VC_LIGHT_DIFFUSE4 37 +//#define VC_LIGHT_SPEC4 38 + +#define VC_DETAIL_SCALE 40 + + + +#define PC_MAT_SPECCOLOR 0 +#define PC_MAT_SPECPOWER 1 +#define PC_DIFF_COLOR 2 +#define PC_AMBIENT_COLOR 3 +#define PC_ACCUM_TIME 4 +#define PC_DIFF_COLOR2 5 +#define PC_VISIBILITY 6 +#define PC_COLORMULTIPLY 7 + +#define PC_USERDEF1 8 + +#endif + + diff --git a/Templates/Empty/game/shaders/common/terrain/blendP.hlsl b/Templates/Empty/game/shaders/common/terrain/blendP.hlsl new file mode 100644 index 000000000..f71088928 --- /dev/null +++ b/Templates/Empty/game/shaders/common/terrain/blendP.hlsl @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "terrain.hlsl" + +struct ConnectData +{ + float4 hpos : POSITION; + float2 layerCoord : TEXCOORD0; + float2 texCoord : TEXCOORD1; +}; + +float4 main( ConnectData IN, + uniform sampler2D layerTex : register(S0), + uniform sampler2D textureMap : register(S1), + uniform float texId, + uniform float layerSize ) : COLOR +{ + float4 layerSample = round( tex2D( layerTex, IN.layerCoord ) * 255.0f ); + + float blend = calcBlend( texId, IN.layerCoord, layerSize, layerSample ); + + clip( blend - 0.0001 ); + + return float4( tex2D( textureMap, IN.texCoord ).rgb, blend ); +} diff --git a/Templates/Empty/game/shaders/common/terrain/blendV.hlsl b/Templates/Empty/game/shaders/common/terrain/blendV.hlsl new file mode 100644 index 000000000..7a79d2de4 --- /dev/null +++ b/Templates/Empty/game/shaders/common/terrain/blendV.hlsl @@ -0,0 +1,49 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +/// The vertex shader used in the generation and caching of the +/// base terrain texture. + +struct VertData +{ + float3 position : POSITION; + float2 texCoord : TEXCOORD0; +}; + +struct ConnectData +{ + float4 hpos : POSITION; + float2 layerCoord : TEXCOORD0; + float2 texCoord : TEXCOORD1; +}; + +ConnectData main( VertData IN, + uniform float2 texScale : register(C0) ) +{ + ConnectData OUT; + + OUT.hpos = float4( IN.position.xyz, 1 ); + OUT.layerCoord = IN.texCoord; + OUT.texCoord = IN.texCoord * texScale; + + return OUT; +} diff --git a/Templates/Empty/game/shaders/common/terrain/gl/blendP.glsl b/Templates/Empty/game/shaders/common/terrain/gl/blendP.glsl new file mode 100644 index 000000000..3817e1de2 --- /dev/null +++ b/Templates/Empty/game/shaders/common/terrain/gl/blendP.glsl @@ -0,0 +1,44 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "../terrain.glsl" +#include "../../gl/hlslCompat.glsl" + +varying vec2 layerCoord; +varying vec2 texCoord; + +uniform sampler2D layerTex; +uniform sampler2D textureMap; +uniform float texId; +uniform float layerSize; + +void main() +{ + vec4 layerSample = round(texture2D( layerTex, layerCoord ) * 255.0); + + float blend = calcBlend( texId, layerCoord, layerSize, layerSample ); + + if(blend - 0.0001 < 0.0) + discard; + + gl_FragColor = vec4( texture2D( textureMap, texCoord ).rgb, blend ); +} diff --git a/Templates/Empty/game/shaders/common/terrain/gl/blendV.glsl b/Templates/Empty/game/shaders/common/terrain/gl/blendV.glsl new file mode 100644 index 000000000..44362085b --- /dev/null +++ b/Templates/Empty/game/shaders/common/terrain/gl/blendV.glsl @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +/// The vertex shader used in the generation and caching of the +/// base terrain texture. + +varying vec2 layerCoord; +varying vec2 texCoord; + +uniform vec2 texScale; + +void main() +{ + gl_Position = vec4(gl_Vertex.xyz, 1.0); + layerCoord = gl_MultiTexCoord0.st; + texCoord = gl_MultiTexCoord0.st * texScale; +} diff --git a/Templates/Empty/game/shaders/common/terrain/terrain.glsl b/Templates/Empty/game/shaders/common/terrain/terrain.glsl new file mode 100644 index 000000000..1fe7a483e --- /dev/null +++ b/Templates/Empty/game/shaders/common/terrain/terrain.glsl @@ -0,0 +1,50 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +float calcBlend( float texId, vec2 layerCoord, float layerSize, vec4 layerSample ) +{ + // This is here to disable the blend if none of + // the neighbors equal the current id. + // + // We depend on the input layer samples being + // rounded to the correct integer ids. + // + vec4 diff = clamp( abs( layerSample - texId ), 0.0, 1.0 ); + float noBlend = float(any( bvec4(1 - diff) )); + + // Use step to see if any of the layer samples + // match the current texture id. + vec4 factors = step( texId, layerSample ); + + // This is a custom bilinear filter. + + vec2 uv = layerCoord * layerSize; + vec2 xy = floor( uv ); + vec2 ratio = uv - xy; + vec2 opposite = 1 - ratio; + + float blend = ( factors.b * opposite.x + factors.g * ratio.x ) * opposite.y + + ( factors.r * opposite.x + factors.a * ratio.x ) * ratio.y; + + return noBlend * blend; +} diff --git a/Templates/Empty/game/shaders/common/terrain/terrain.hlsl b/Templates/Empty/game/shaders/common/terrain/terrain.hlsl new file mode 100644 index 000000000..328acae7f --- /dev/null +++ b/Templates/Empty/game/shaders/common/terrain/terrain.hlsl @@ -0,0 +1,51 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +float calcBlend( float texId, float2 layerCoord, float layerSize, float4 layerSample ) +{ + // This is here to disable the blend if none of + // the neighbors equal the current id. + // + // We depend on the input layer samples being + // rounded to the correct integer ids. + // + float4 diff = saturate( abs( layerSample - texId ) ); + float noBlend = any( 1 - diff ); + + // Use step to see if any of the layer samples + // match the current texture id. + float4 factors = step( texId, layerSample ); + + // This is a custom bilinear filter. + + float2 uv = layerCoord * layerSize; + float2 xy = floor( uv ); + float2 ratio = uv - xy; + float2 opposite = 1 - ratio; + + // NOTE: This will optimize down to two lerp operations. + float blend = ( factors.b * opposite.x + factors.g * ratio.x ) * opposite.y + + ( factors.r * opposite.x + factors.a * ratio.x ) * ratio.y; + + return noBlend * blend; +} diff --git a/Templates/Empty/game/shaders/common/torque.hlsl b/Templates/Empty/game/shaders/common/torque.hlsl new file mode 100644 index 000000000..3821ce693 --- /dev/null +++ b/Templates/Empty/game/shaders/common/torque.hlsl @@ -0,0 +1,266 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#ifndef _TORQUE_HLSL_ +#define _TORQUE_HLSL_ + + +static float M_HALFPI_F = 1.57079632679489661923f; +static float M_PI_F = 3.14159265358979323846f; +static float M_2PI_F = 6.28318530717958647692f; + + +/// Calculate fog based on a start and end positions in worldSpace. +float computeSceneFog( float3 startPos, + float3 endPos, + float fogDensity, + float fogDensityOffset, + float fogHeightFalloff ) +{ + float f = length( startPos - endPos ) - fogDensityOffset; + float h = 1.0 - ( endPos.z * fogHeightFalloff ); + return exp( -fogDensity * f * h ); +} + + +/// Calculate fog based on a start and end position and a height. +/// Positions do not need to be in worldSpace but height does. +float computeSceneFog( float3 startPos, + float3 endPos, + float height, + float fogDensity, + float fogDensityOffset, + float fogHeightFalloff ) +{ + float f = length( startPos - endPos ) - fogDensityOffset; + float h = 1.0 - ( height * fogHeightFalloff ); + return exp( -fogDensity * f * h ); +} + + +/// Calculate fog based on a distance, height is not used. +float computeSceneFog( float dist, float fogDensity, float fogDensityOffset ) +{ + float f = dist - fogDensityOffset; + return exp( -fogDensity * f ); +} + + +/// Convert a float4 uv in viewport space to render target space. +float2 viewportCoordToRenderTarget( float4 inCoord, float4 rtParams ) +{ + float2 outCoord = inCoord.xy / inCoord.w; + outCoord = ( outCoord * rtParams.zw ) + rtParams.xy; + return outCoord; +} + + +/// Convert a float2 uv in viewport space to render target space. +float2 viewportCoordToRenderTarget( float2 inCoord, float4 rtParams ) +{ + float2 outCoord = ( inCoord * rtParams.zw ) + rtParams.xy; + return outCoord; +} + + +/// Convert a float4 quaternion into a 3x3 matrix. +float3x3 quatToMat( float4 quat ) +{ + float xs = quat.x * 2.0f; + float ys = quat.y * 2.0f; + float zs = quat.z * 2.0f; + + float wx = quat.w * xs; + float wy = quat.w * ys; + float wz = quat.w * zs; + + float xx = quat.x * xs; + float xy = quat.x * ys; + float xz = quat.x * zs; + + float yy = quat.y * ys; + float yz = quat.y * zs; + float zz = quat.z * zs; + + float3x3 mat; + + mat[0][0] = 1.0f - (yy + zz); + mat[0][1] = xy - wz; + mat[0][2] = xz + wy; + + mat[1][0] = xy + wz; + mat[1][1] = 1.0f - (xx + zz); + mat[1][2] = yz - wx; + + mat[2][0] = xz - wy; + mat[2][1] = yz + wx; + mat[2][2] = 1.0f - (xx + yy); + + return mat; +} + + +/// The number of additional substeps we take when refining +/// the results of the offset parallax mapping function below. +/// +/// You should turn down the number of steps if your needing +/// more performance out of your parallax surfaces. Increasing +/// the number doesn't yeild much better results and is rarely +/// worth the additional cost. +/// +#define PARALLAX_REFINE_STEPS 3 + +/// Performs fast parallax offset mapping using +/// multiple refinement steps. +/// +/// @param texMap The texture map whos alpha channel we sample the parallax depth. +/// @param texCoord The incoming texture coordinate for sampling the parallax depth. +/// @param negViewTS The negative view vector in tangent space. +/// @param depthScale The parallax factor used to scale the depth result. +/// +float2 parallaxOffset( sampler2D texMap, float2 texCoord, float3 negViewTS, float depthScale ) +{ + float depth = tex2D( texMap, texCoord ).a; + float2 offset = negViewTS.xy * ( depth * depthScale ); + + for ( int i=0; i < PARALLAX_REFINE_STEPS; i++ ) + { + depth = ( depth + tex2D( texMap, texCoord + offset ).a ) * 0.5; + offset = negViewTS.xy * ( depth * depthScale ); + } + + return offset; +} + + +/// The maximum value for 16bit per component integer HDR encoding. +static const float HDR_RGB16_MAX = 100.0; + +/// The maximum value for 10bit per component integer HDR encoding. +static const float HDR_RGB10_MAX = 4.0; + +/// Encodes an HDR color for storage into a target. +float3 hdrEncode( float3 sample ) +{ + #if defined( TORQUE_HDR_RGB16 ) + + return sample / HDR_RGB16_MAX; + + #elif defined( TORQUE_HDR_RGB10 ) + + return sample / HDR_RGB10_MAX; + + #else + + // No encoding. + return sample; + + #endif +} + +/// Encodes an HDR color for storage into a target. +float4 hdrEncode( float4 sample ) +{ + return float4( hdrEncode( sample.rgb ), sample.a ); +} + +/// Decodes an HDR color from a target. +float3 hdrDecode( float3 sample ) +{ + #if defined( TORQUE_HDR_RGB16 ) + + return sample * HDR_RGB16_MAX; + + #elif defined( TORQUE_HDR_RGB10 ) + + return sample * HDR_RGB10_MAX; + + #else + + // No encoding. + return sample; + + #endif +} + +/// Decodes an HDR color from a target. +float4 hdrDecode( float4 sample ) +{ + return float4( hdrDecode( sample.rgb ), sample.a ); +} + +/// Returns the luminance for an HDR pixel. +float hdrLuminance( float3 sample ) +{ + // There are quite a few different ways to + // calculate luminance from an rgb value. + // + // If you want to use a different technique + // then plug it in here. + // + + //////////////////////////////////////////////////////////////////////////// + // + // Max component luminance. + // + //float lum = max( sample.r, max( sample.g, sample.b ) ); + + //////////////////////////////////////////////////////////////////////////// + // The perceptual relative luminance. + // + // See http://en.wikipedia.org/wiki/Luminance_(relative) + // + const float3 RELATIVE_LUMINANCE = float3( 0.2126, 0.7152, 0.0722 ); + float lum = dot( sample, RELATIVE_LUMINANCE ); + + //////////////////////////////////////////////////////////////////////////// + // + // The average component luminance. + // + //const float3 AVERAGE_LUMINANCE = float3( 0.3333, 0.3333, 0.3333 ); + //float lum = dot( sample, AVERAGE_LUMINANCE ); + + return lum; +} + +/// Called from the visibility feature to do screen +/// door transparency for fading of objects. +void fizzle(float2 vpos, float visibility) +{ + // NOTE: The magic values below are what give us + // the nice even pattern during the fizzle. + // + // These values can be changed to get different + // patterns... some better than others. + // + // Horizontal Blinds - { vpos.x, 0.916, vpos.y, 0 } + // Vertical Lines - { vpos.x, 12.9898, vpos.y, 78.233 } + // + // I'm sure there are many more patterns here to + // discover for different effects. + + float2x2 m = { vpos.x, 0.916, vpos.y, 0.350 }; + clip( visibility - frac( determinant( m ) ) ); +} + + +#endif // _TORQUE_HLSL_ diff --git a/Templates/Empty/game/shaders/common/water/gl/waterBasicP.glsl b/Templates/Empty/game/shaders/common/water/gl/waterBasicP.glsl new file mode 100644 index 000000000..72232622a --- /dev/null +++ b/Templates/Empty/game/shaders/common/water/gl/waterBasicP.glsl @@ -0,0 +1,197 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "../../gl/torque.glsl" +#include "../../gl/hlslCompat.glsl" + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- + +// miscParams +#define FRESNEL_BIAS miscParams[0] +#define FRESNEL_POWER miscParams[1] +#define CLARITY miscParams[2] +#define ISRIVER miscParams[3] + +// reflectParams +#define REFLECT_PLANE_Z reflectParams[0] +#define REFLECT_MIN_DIST reflectParams[1] +#define REFLECT_MAX_DIST reflectParams[2] +#define NO_REFLECT reflectParams[3] + +// distortionParams +#define DISTORT_START_DIST distortionParams[0] +#define DISTORT_END_DIST distortionParams[1] +#define DISTORT_FULL_DEPTH distortionParams[2] + +// ConnectData.misc +#define LIGHT_VEC misc.xyz +#define WORLD_Z objPos.w + +// specularParams +#define SPEC_POWER specularParams[3] +#define SPEC_COLOR specularParams.xyz + +// TexCoord 0 and 1 (xy,zw) for ripple texture lookup +varying vec4 rippleTexCoord01; + +// TexCoord 2 for ripple texture lookup +varying vec2 rippleTexCoord2; + +// Screenspace vert position BEFORE wave transformation +varying vec4 posPreWave; + +// Screenspace vert position AFTER wave transformation +varying vec4 posPostWave; + +// Worldspace unit distance/depth of this vertex/pixel +varying float pixelDist; + +// Objectspace vert position BEFORE wave transformation +// w coord is world space z position. +varying vec4 objPos; + +varying vec3 misc; + +//----------------------------------------------------------------------------- +// approximate Fresnel function +//----------------------------------------------------------------------------- +float fresnel(float NdotV, float bias, float power) +{ + return bias + (1.0-bias)*pow(abs(1.0 - max(NdotV, 0.0)), power); +} + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- +uniform sampler2D bumpMap; +//uniform sampler2D prepassTex; +uniform sampler2D reflectMap; +uniform sampler2D refractBuff; +uniform samplerCube skyMap; +//uniform sampler foamMap; +uniform vec4 baseColor; +uniform vec4 miscParams; +uniform vec4 reflectParams; +uniform vec3 ambientColor; +uniform vec3 eyePos; +uniform vec3 distortionParams; +uniform vec3 fogData; +uniform vec4 fogColor; +uniform vec3 rippleMagnitude; +uniform vec4 specularParams; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + // Modulate baseColor by the ambientColor. + vec4 waterBaseColor = baseColor * vec4( ambientColor.rgb, 1.0 ); + + // Get the bumpNorm... + vec3 bumpNorm = ( texture2D( bumpMap, rippleTexCoord01.xy ).rgb * 2.0 - 1.0 ) * rippleMagnitude.x; + bumpNorm += ( texture2D( bumpMap, rippleTexCoord01.zw ).rgb * 2.0 - 1.0 ) * rippleMagnitude.y; + bumpNorm += ( texture2D( bumpMap, rippleTexCoord2 ).rgb * 2.0 - 1.0 ) * rippleMagnitude.z; + + // We subtract a little from it so that we don't + // distort where the water surface intersects the + // camera near plane. + float distortAmt = saturate( pixelDist / 1.0 ) * 0.8; + + vec4 distortPos = posPostWave; + distortPos.xy += bumpNorm.xy * distortAmt; + + #ifdef UNDERWATER + gl_FragColor = texture2DProj( refractBuff, distortPos.xyz ); + #else + + vec3 eyeVec = objPos.xyz - eyePos; + vec3 reflectionVec = reflect( eyeVec, normalize(bumpNorm) ); + + // Color that replaces the reflection color when we do not + // have one that is appropriate. + vec4 fakeColor = vec4(ambientColor,1.0); + + // Use fakeColor for ripple-normals that are angled towards the camera + eyeVec = -eyeVec; + eyeVec = normalize( eyeVec ); + float ang = saturate( dot( eyeVec, bumpNorm ) ); + float fakeColorAmt = ang; + + // Get reflection map color + vec4 refMapColor = texture2DProj( reflectMap, distortPos ); + // If we do not have a reflection texture then we use the cubemap. + refMapColor = mix( refMapColor, textureCube( skyMap, -reflectionVec ), NO_REFLECT ); + + // Combine reflection color and fakeColor. + vec4 reflectColor = mix( refMapColor, fakeColor, fakeColorAmt ); + //return refMapColor; + + // Get refract color + vec4 refractColor = texture2DProj( refractBuff, distortPos.xyz ); + + // calc "diffuse" color by lerping from the water color + // to refraction image based on the water clarity. + vec4 diffuseColor = mix( refractColor, waterBaseColor, 1.0 - CLARITY ); + + // fresnel calculation + float fresnelTerm = fresnel( ang, FRESNEL_BIAS, FRESNEL_POWER ); + + // Also scale the frensel by our distance to the + // water surface. This removes the hard reflection + // when really close to the water surface. + fresnelTerm *= saturate( pixelDist - 0.1 ); + + // Combine the diffuse color and reflection image via the + // fresnel term and set out output color. + gl_FragColor = mix( diffuseColor, reflectColor, fresnelTerm ); + + #ifdef WATER_SPEC + + // Get some specular reflection. + vec3 newbump = bumpNorm; + newbump.xy *= 3.5; + newbump = normalize( bumpNorm ); + vec3 halfAng = normalize( eyeVec + -LIGHT_VEC ); + float specular = saturate( dot( newbump, halfAng ) ); + specular = pow( specular, SPEC_POWER ); + + gl_FragColor.rgb = gl_FragColor.rgb + ( SPEC_COLOR * specular.xxx ); + + #else // Disable fogging if spec is on because otherwise we run out of instructions. + + // Fog it. + float factor = computeSceneFog( eyePos, + objPos.xyz, + WORLD_Z, + fogData.x, + fogData.y, + fogData.z ); + + gl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor.rgb, 1.0 - saturate( factor ) ); + + #endif + +#endif +} diff --git a/Templates/Empty/game/shaders/common/water/gl/waterBasicV.glsl b/Templates/Empty/game/shaders/common/water/gl/waterBasicV.glsl new file mode 100644 index 000000000..bb2a0c954 --- /dev/null +++ b/Templates/Empty/game/shaders/common/water/gl/waterBasicV.glsl @@ -0,0 +1,260 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "../../gl/hlslCompat.glsl" + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- + +// TexCoord 0 and 1 (xy,zw) for ripple texture lookup +varying vec4 rippleTexCoord01; + +// TexCoord 2 for ripple texture lookup +varying vec2 rippleTexCoord2; + +// Screenspace vert position BEFORE wave transformation +varying vec4 posPreWave; + +// Screenspace vert position AFTER wave transformation +varying vec4 posPostWave; + +// Worldspace unit distance/depth of this vertex/pixel +varying float pixelDist; + +varying vec4 objPos; + +varying vec3 misc; + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- +uniform mat4 modelMat; +uniform mat4 modelview; +uniform vec4 rippleMat[3]; +uniform vec3 eyePos; +uniform vec2 waveDir[3]; +uniform vec2 waveData[3]; +uniform vec2 rippleDir[3]; +uniform vec2 rippleTexScale[3]; +uniform vec3 rippleSpeed; +uniform vec3 inLightVec; +uniform vec3 reflectNormal; +uniform float gridElementSize; +uniform float elapsedTime; +uniform float undulateMaxDist; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + vec4 position = gl_Vertex; + vec3 normal = gl_Normal; + vec2 undulateData = gl_MultiTexCoord0.st; + vec4 horizonFactor = gl_MultiTexCoord1; + + // use projection matrix for reflection / refraction texture coords + mat4 texGen = mat4(0.5, 0.0, 0.0, 0.0, + 0.0, 0.5, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.5, 0.5, 0.0, 1.0); + + // Move the vertex based on the horizonFactor if specified to do so for this vert. + //if ( horizonFactor.z > 0.0 ) + //{ + //vec2 offsetXY = eyePos.xy - mod(eyePos.xy, gridElementSize); + //position.xy += offsetXY; + //undulateData += offsetXY; + //} + + vec4 worldPos = modelMat * position; + //fogPos = position.xyz; + position.z = mix( position.z, eyePos.z, horizonFactor.x ); + + objPos.xyz = position.xyz; + objPos.w = worldPos.z; + + // Send pre-undulation screenspace position + posPreWave = modelview * position; + posPreWave = texGen * posPreWave; + + // Calculate the undulation amount for this vertex. + vec2 undulatePos = (modelMat * vec4( undulateData.xy, 0, 1 )).xy; + + //if ( undulatePos.x < 0.0 ) + //undulatePos = position.xy; + + float undulateAmt = 0.0; + + undulateAmt += waveData[0].y * sin( elapsedTime * waveData[0].x + + undulatePos.x * waveDir[0].x + + undulatePos.y * waveDir[0].y ); + undulateAmt += waveData[1].y * sin( elapsedTime * waveData[1].x + + undulatePos.x * waveDir[1].x + + undulatePos.y * waveDir[1].y ); + undulateAmt += waveData[2].y * sin( elapsedTime * waveData[2].x + + undulatePos.x * waveDir[2].x + + undulatePos.y * waveDir[2].y ); + + float undulateFade = 1.0; + + // Scale down wave magnitude amount based on distance from the camera. + float dist = length( position.xyz - eyePos ); + dist = clamp( dist, 1.0, undulateMaxDist ); + undulateFade *= ( 1.0 - dist / undulateMaxDist ); + + // Also scale down wave magnitude if the camera is very very close. + undulateFade *= saturate( ( length( position.xyz - eyePos ) - 0.5 ) / 10.0 ); + + undulateAmt *= undulateFade; + + //undulateAmt = 0; + + // Apply wave undulation to the vertex. + posPostWave = position; + posPostWave.xyz += normal.xyz * undulateAmt; + + // Save worldSpace position of this pixel/vert + //worldPos = posPostWave.xyz; + + //worldSpaceZ = ( modelMat * vec4(fogPos,1.0) ).z; + //if ( horizonFactor.x > 0.0 ) + //{ + //vec3 awayVec = normalize( fogPos.xyz - eyePos ); + //fogPos.xy += awayVec.xy * 1000.0; + //} + + // Convert to screen + posPostWave = modelview * posPostWave; + + // Setup the OUT position symantic variable + gl_Position = posPostWave; + //gl_Position.z = mix(gl_Position.z, gl_Position.w, horizonFactor.x); + + // Save world space camera dist/depth of the outgoing pixel + pixelDist = gl_Position.z; + + // Convert to reflection texture space + posPostWave = texGen * posPostWave; + + vec2 txPos = undulatePos; + if ( horizonFactor.x > 0.0 ) + txPos = normalize( txPos ) * 50000.0; + + + // set up tex coordinates for the 3 interacting normal maps + rippleTexCoord01.xy = txPos * rippleTexScale[0]; + rippleTexCoord01.xy += rippleDir[0] * elapsedTime * rippleSpeed.x; + + mat2 texMat; + texMat[0][0] = rippleMat[0].x; + texMat[1][0] = rippleMat[0].y; + texMat[0][1] = rippleMat[0].z; + texMat[1][1] = rippleMat[0].w; + rippleTexCoord01.xy = texMat * rippleTexCoord01.xy ; + + rippleTexCoord01.zw = txPos * rippleTexScale[1]; + rippleTexCoord01.zw += rippleDir[1] * elapsedTime * rippleSpeed.y; + + texMat[0][0] = rippleMat[1].x; + texMat[1][0] = rippleMat[1].y; + texMat[0][1] = rippleMat[1].z; + texMat[1][1] = rippleMat[1].w; + rippleTexCoord01.zw = texMat * rippleTexCoord01.zw ; + + rippleTexCoord2.xy = txPos * rippleTexScale[2]; + rippleTexCoord2.xy += rippleDir[2] * elapsedTime * rippleSpeed.z; + + texMat[0][0] = rippleMat[2].x; + texMat[1][0] = rippleMat[2].y; + texMat[0][1] = rippleMat[2].z; + texMat[1][1] = rippleMat[2].w; + rippleTexCoord2.xy = texMat * rippleTexCoord2.xy ; + + + /*rippleTexCoord01.xy = mix( position.xy * rippleTexScale[0], txPos.xy * rippleTexScale[0], horizonFactor.x ); + rippleTexCoord01.xy += rippleDir[0] * elapsedTime * rippleSpeed.x; + + rippleTexCoord01.zw = mix( position.xy * rippleTexScale[1], txPos.xy * rippleTexScale[1], horizonFactor.x ); + rippleTexCoord01.zw += rippleDir[1] * elapsedTime * rippleSpeed.y; + + rippleTexCoord2.xy = mix( position.xy * rippleTexScale[2], txPos.xy * rippleTexScale[2], horizonFactor.x ); + rippleTexCoord2.xy += rippleDir[2] * elapsedTime * rippleSpeed.z; */ + + + /*rippleTexCoord01.xy = mix( position.xy * rippleTexScale[0], txPos.xy * rippleTexScale[0], horizonFactor.x ); + rippleTexCoord01.xy += rippleDir[0] * elapsedTime * rippleSpeed.x; + mat2 texMat; + texMat[0][0] = rippleMat[0].x; + texMat[1][0] = rippleMat[0].y; + texMat[0][1] = rippleMat[0].z; + texMat[1][1] = rippleMat[0].w; + rippleTexCoord01.xy = texMat * rippleTexCoord01.xy ; + + rippleTexCoord01.zw = mix( position.xy * rippleTexScale[1], txPos.xy * rippleTexScale[1], horizonFactor.x ); + rippleTexCoord01.zw += rippleDir[1] * elapsedTime * rippleSpeed.y; + texMat[0][0] = rippleMat[1].x; + texMat[1][0] = rippleMat[1].y; + texMat[0][1] = rippleMat[1].z; + texMat[1][1] = rippleMat[1].w; + rippleTexCoord01.zw = texMat * rippleTexCoord01.zw ; + + rippleTexCoord2.xy = mix( position.xy * rippleTexScale[2], txPos.xy * rippleTexScale[2], horizonFactor.x ); + rippleTexCoord2.xy += rippleDir[2] * elapsedTime * rippleSpeed.z; + texMat[0][0] = rippleMat[2].x; + texMat[1][0] = rippleMat[2].y; + texMat[0][1] = rippleMat[2].z; + texMat[1][1] = rippleMat[2].w; + rippleTexCoord2.xy = texMat * rippleTexCoord2.xy ;*/ + +#ifdef WATER_SPEC + + vec3 binormal = vec3( 1, 0, 0 ); + vec3 tangent = vec3( 0, 1, 0 ); + vec3 normal; + for ( int i = 0; i < 3; i++ ) + { + binormal.z += undulateFade * waveDir[i].x * waveData[i].y * cos( waveDir[i].x * undulateData.x + waveDir[i].y * undulateData.y + elapsedTime * waveData[i].x ); + tangent.z += undulateFade * waveDir[i].y * waveData[i].y * cos( waveDir[i].x * undulateData.x + waveDir[i].y * undulateData.y + elapsedTime * waveData[i].x ); + } + + binormal = normalize( binormal ); + tangent = normalize( tangent ); + normal = cross( binormal, tangent ); + + mat3 worldToTangent; + worldToTangent[0] = binormal; + worldToTangent[1] = tangent; + worldToTangent[2] = normal; + + misc.xyz = inLightVec * modelMat; + misc.xyz = worldToTangent * misc.xyz; + +#else + + misc.xyz = inLightVec; + +#endif + +} + diff --git a/Templates/Empty/game/shaders/common/water/gl/waterP.glsl b/Templates/Empty/game/shaders/common/water/gl/waterP.glsl new file mode 100644 index 000000000..bf482d724 --- /dev/null +++ b/Templates/Empty/game/shaders/common/water/gl/waterP.glsl @@ -0,0 +1,456 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" +#include "../../gl/torque.glsl" + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- + +#ifdef TORQUE_BASIC_LIGHTING + #define BASIC +#endif + +// miscParams +#define FRESNEL_BIAS miscParams[0] +#define FRESNEL_POWER miscParams[1] +// miscParams[2] is unused +#define ISRIVER miscParams[3] + +// reflectParams +#define REFLECT_PLANE_Z reflectParams[0] +#define REFLECT_MIN_DIST reflectParams[1] +#define REFLECT_MAX_DIST reflectParams[2] +#define NO_REFLECT reflectParams[3] + +// fogParams +#define FOG_DENSITY fogParams[0] +#define FOG_DENSITY_OFFSET fogParams[1] + +// wetnessParams +#define WET_DEPTH wetnessParams[0] +#define WET_COLOR_FACTOR wetnessParams[1] + +// distortionParams +#define DISTORT_START_DIST distortionParams[0] +#define DISTORT_END_DIST distortionParams[1] +#define DISTORT_FULL_DEPTH distortionParams[2] + +// foamParams +#define FOAM_SCALE foamParams[0] +#define FOAM_MAX_DEPTH foamParams[1] + +// Incoming data +// Worldspace position of this pixel +varying vec3 worldPos; + +// TexCoord 0 and 1 (xy,zw) for ripple texture lookup +varying vec4 rippleTexCoord01; + +// TexCoord 2 for ripple texture lookup +varying vec2 rippleTexCoord2; + +// Screenspace vert position BEFORE wave transformation +varying vec4 posPreWave; + +// Screenspace vert position AFTER wave transformation +varying vec4 posPostWave; + +// Worldspace unit distance/depth of this vertex/pixel +varying float pixelDist; + +varying vec3 fogPos; + +varying float worldSpaceZ; + +varying vec4 foamTexCoords; + +//----------------------------------------------------------------------------- +// approximate Fresnel function +//----------------------------------------------------------------------------- +float fresnel(float NdotV, float bias, float power) +{ + return bias + (1.0-bias)*pow(abs(1.0 - max(NdotV, 0)), power); +} + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- +uniform sampler2D bumpMap; +uniform sampler2D prepassTex; +uniform sampler2D reflectMap; +uniform sampler2D refractBuff; +uniform samplerCUBE skyMap; +uniform sampler2D foamMap; +uniform vec4 specularColor; +uniform float specularPower; +uniform vec4 baseColor; +uniform vec4 miscParams; +uniform vec2 fogParams; +uniform vec4 reflectParams; +uniform vec3 reflectNormal; +uniform vec2 wetnessParams; +uniform float farPlaneDist; +uniform vec3 distortionParams; +//uniform vec4 renderTargetParams; +uniform vec2 foamParams; +uniform vec3 foamColorMod; +uniform vec3 ambientColor; +uniform vec3 eyePos; +uniform vec3 inLightVec; +uniform vec3 fogData; +uniform vec4 fogColor; +//uniform vec4 rtParams; +uniform vec2 rtScale; +uniform vec2 rtHalfPixel; +uniform vec4 rtOffset; +uniform vec3 rippleMagnitude; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + vec4 rtParams = vec4( rtOffset.x / rtOffset.z + rtHalfPixel.x, + rtOffset.y / rtOffset.w + rtHalfPixel.x, + rtScale ); + + // Modulate baseColor by the ambientColor. + vec4 waterBaseColor = baseColor * vec4( ambientColor.rgb, 1 ); + + // Get the bumpNorm... + vec3 bumpNorm = ( tex2D( bumpMap, IN.rippleTexCoord01.xy ) * 2.0 - 1.0 ) * rippleMagnitude.x; + bumpNorm += ( tex2D( bumpMap, IN.rippleTexCoord01.zw ) * 2.0 - 1.0 ) * rippleMagnitude.y; + bumpNorm += ( tex2D( bumpMap, IN.rippleTexCoord2 ) * 2.0 - 1.0 ) * rippleMagnitude.z; + + // JCF: this was here, but seems to make the dot product against the bump + // normal we use below for cubeMap fade-in to be less reliable. + //bumpNorm.xy *= 0.75; + //bumpNorm = normalize( bumpNorm ); + //return vec4( bumpNorm, 1 ); + + // Get depth of the water surface (this pixel). + // Convert from WorldSpace to EyeSpace. + float pixelDepth = IN.pixelDist / farPlaneDist; + + // Get prepass depth at the undistorted pixel. + //vec4 prepassCoord = IN.posPostWave; + //prepassCoord.xy += renderTargetParams.xy; + vec2 prepassCoord = viewportCoordToRenderTarget( IN.posPostWave, rtParams ); + //vec2 prepassCoord = IN.posPostWave.xy; + + float startDepth = prepassUncondition( tex2D( prepassTex, prepassCoord ) ).w; + //return vec4( startDepth.rrr, 1 ); + + // The water depth in world units of the undistorted pixel. + float startDelta = ( startDepth - pixelDepth ); + if ( startDelta <= 0.0 ) + { + //return vec4( 1, 0, 0, 1 ); + startDelta = 0; + } + + startDelta *= farPlaneDist; + + // Calculate the distortion amount for the water surface. + // + // We subtract a little from it so that we don't + // distort where the water surface intersects the + // camera near plane. + float distortAmt = saturate( ( IN.pixelDist - DISTORT_START_DIST ) / DISTORT_END_DIST ); + + // Scale down distortion in shallow water. + distortAmt *= saturate( startDelta / DISTORT_FULL_DEPTH ); + //distortAmt = 0; + + // Do the intial distortion... we might remove it below. + vec2 distortDelta = bumpNorm.xy * distortAmt; + vec4 distortPos = IN.posPostWave; + distortPos.xy += distortDelta; + + prepassCoord = viewportCoordToRenderTarget( distortPos, rtParams ); + //prepassCoord = distortPos; + //prepassCoord.xy += renderTargetParams.xy; + + // Get prepass depth at the position of this distorted pixel. + float prepassDepth = prepassUncondition( tex2D( prepassTex, prepassCoord ) ).w; + + float delta = ( prepassDepth - pixelDepth ) * farPlaneDist; + + if ( delta < 0.0 ) + { + // If we got a negative delta then the distorted + // sample is above the water surface. Mask it out + // by removing the distortion. + distortPos = IN.posPostWave; + delta = startDelta; + distortAmt = 0; + } + else + { + float diff = ( prepassDepth - startDepth ) * farPlaneDist; + + if ( diff < 0 ) + { + distortAmt = saturate( ( IN.pixelDist - DISTORT_START_DIST ) / DISTORT_END_DIST ); + distortAmt *= saturate( delta / DISTORT_FULL_DEPTH ); + + distortDelta = bumpNorm.xy * distortAmt; + + distortPos = IN.posPostWave; + distortPos.xy += distortDelta; + + prepassCoord = viewportCoordToRenderTarget( distortPos, rtParams ); + //prepassCoord = distortPos; + //prepassCoord.xy += renderTargetParams.xy; + + // Get prepass depth at the position of this distorted pixel. + prepassDepth = prepassUncondition( tex2D( prepassTex, prepassCoord ) ).w; + delta = ( prepassDepth - pixelDepth ) * farPlaneDist; + } + + if ( delta < 0.1 ) + { + // If we got a negative delta then the distorted + // sample is above the water surface. Mask it out + // by removing the distortion. + distortPos = IN.posPostWave; + delta = startDelta; + distortAmt = 0; + } + } + + //return vec4( prepassDepth.rrr, 1 ); + + vec4 temp = IN.posPreWave; + temp.xy += bumpNorm.xy * distortAmt; + vec2 reflectCoord = viewportCoordToRenderTarget( temp, rtParams ); + + vec2 refractCoord = viewportCoordToRenderTarget( distortPos, rtParams ); + + // Use cubemap colors instead of reflection colors in several cases... + + // First lookup the CubeMap color + // JCF: which do we want to use here, the reflectNormal or the bumpNormal + // neithor of them is exactly right and how can we combine the two together? + //bumpNorm = reflectNormal; + vec3 eyeVec = IN.worldPos - eyePos; + vec3 reflectionVec = reflect( eyeVec, bumpNorm ); + //vec4 cubeColor = texCUBE( skyMap, reflectionVec ); + //return cubeColor; + // JCF: using ambient color instead of cubeColor for waterPlane, how do we still use the cubemap for rivers? + vec4 cubeColor = vec4(ambientColor,1); + //cubeColor.rgb = vec3( 0, 0, 1 ); + + // Use cubeColor for waves that are angled towards camera + eyeVec = -eyeVec; + eyeVec = normalize( eyeVec ); + float ang = saturate( dot( eyeVec, bumpNorm ) ); + float cubeAmt = ang; + + //float rplaneDist = (reflectPlane.x * IN.pos.x + reflectPlane.y * IN.pos.y + reflectPlane.z * IN.pos.z) + reflectPlane.w; + //rplaneDist = saturate( abs( rplaneDist ) / 0.5 ); + + +//#ifdef RIVER + // for verts far from the reflect plane z position + float rplaneDist = abs( REFLECT_PLANE_Z - IN.worldPos.z ); + rplaneDist = saturate( ( rplaneDist - 1.0 ) / 2.0 ); + //rplaneDist = REFLECT_PLANE_Z / eyePos.z; + rplaneDist *= ISRIVER; + cubeAmt = max( cubeAmt, rplaneDist ); +//#endif + + //rplaneDist = IN.worldPos.z / eyePos.z; + + //return vec4( rplaneDist.rrr, 1 ); + //return vec4( (reflectParams[REFLECT_PLANE_Z] / 86.0 ).rrr, 1 ); + + // and for verts farther from the camera + //float cubeAmt = ( eyeDist - reflectParams[REFLECT_MIN_DIST] ) / ( reflectParams[REFLECT_MAX_DIST] - reflectParams[REFLECT_MIN_DIST] ); + //cubeAmt = saturate ( cubeAmt ); + + //float temp = ( eyeDist - reflectParams[REFLECT_MIN_DIST] ) / ( reflectParams[REFLECT_MAX_DIST] - reflectParams[REFLECT_MIN_DIST] ); + //temp = saturate ( temp ); + + // If the camera is very very close to the reflect plane. + //float eyeToPlaneDist = eyePos.z - REFLECT_PLANE_Z; // dot( reflectNormal, eyePos ) + REFLECT_PLANE_Z; + //eyeToPlaneDist = abs( eyeToPlaneDist ); + //eyeToPlaneDist = 1.0 - saturate( abs( eyeToPlaneDist ) / 1 ); + + //return vec4( eyeToPlaneDist.rrr, 1 ); + + //cubeAmt = max( cubeAmt, eyeToPlaneDist ); + //cubeAmt = max( cubeAmt, rplaneDist ); + //cubeAmt = max( cubeAmt, ang ); + //cubeAmt = max( cubeAmt, rplaneDist ); + //cubeAmt = max( cubeAmt, IN.depth.w ); + + // All cubemap if fullReflect is specifically user disabled + cubeAmt = max( cubeAmt, NO_REFLECT ); + +#ifndef UNDERWATER + + + // Get foam color and amount + IN.foamTexCoords.xy += distortDelta * 0.5; + IN.foamTexCoords.zw += distortDelta * 0.5; + + vec4 foamColor = tex2D( foamMap, IN.foamTexCoords.xy ); + foamColor += tex2D( foamMap, IN.foamTexCoords.zw ); + //foamColor += tex2D( foamMap, IN.rippleTexCoord2 ) * 0.3; + foamColor = saturate( foamColor ); + // Modulate foam color by ambient color so we don't have glowing white + // foam at night. + foamColor.rgb = lerp( foamColor.rgb, ambientColor.rgb, foamColorMod.rgb ); + + float foamDelta = saturate( delta / FOAM_MAX_DEPTH ); + float foamAmt = 1.0 - foamDelta; + + // Fade out the foam in very very low depth, + // this improves the shoreline a lot. + float diff = 0.8 - foamAmt; + if ( diff < 0.0 ) + { + //return vec4( 1,0,0,1 ); + foamAmt -= foamAmt * abs( diff ) / 0.2; + } + //return vec4( foamAmt.rrr, 1 ); + + foamAmt *= FOAM_SCALE * foamColor.a; + //return vec4( foamAmt.rrr, 1 ); + + // Get reflection map color + vec4 refMapColor = tex2D( reflectMap, reflectCoord ); + + //cubeAmt = 0; + + // Combine cube and foam colors into reflect color + vec4 reflectColor = lerp( refMapColor, cubeColor, cubeAmt ); + //return refMapColor; + + // This doesn't work because REFLECT_PLANE_Z is in worldSpace + // while eyePos is actually in objectSpace! + + //float eyeToPlaneDist = eyePos.z - REFLECT_PLANE_Z; // dot( reflectNormal, eyePos ) + REFLECT_PLANE_Z; + //float transitionFactor = 1.0 - saturate( ( abs( eyeToPlaneDist ) - 0.5 ) / 5 ); + //reflectColor = lerp( reflectColor, waterBaseColor, transitionFactor ); + + //return reflectColor; + + // Get refract color + vec4 refractColor = tex2D( refractBuff, refractCoord ); + //return refractColor; + + // We darken the refraction color a bit to make underwater + // elements look wet. We fade out this darkening near the + // surface in order to not have hard water edges. + // @param WET_DEPTH The depth in world units at which full darkening will be recieved. + // @param WET_COLOR_FACTOR The refract color is scaled down by this amount when at WET_DEPTH + refractColor.rgb *= 1.0f - ( saturate( delta / WET_DEPTH ) * WET_COLOR_FACTOR ); + + // Add Water fog/haze. + float fogDelta = delta - FOG_DENSITY_OFFSET; + //return vec4( fogDelta.rrr, 1 ); + if ( fogDelta < 0.0 ) + fogDelta = 0.0; + float fogAmt = 1.0 - saturate( exp( -FOG_DENSITY * fogDelta ) ); + //return vec4( fogAmt.rrr, 1 ); + + // calc "diffuse" color by lerping from the water color + // to refraction image based on the water clarity. + vec4 diffuseColor = lerp( refractColor, waterBaseColor, fogAmt ); + + // fresnel calculation + float fresnelTerm = fresnel( ang, FRESNEL_BIAS, FRESNEL_POWER ); + //return vec4( fresnelTerm.rrr, 1 ); + + // Scale the frensel strength by fog amount + // so that parts that are very clear get very little reflection. + fresnelTerm *= fogAmt; + //return vec4( fresnelTerm.rrr, 1 ); + + // Also scale the frensel by our distance to the + // water surface. This removes the hard reflection + // when really close to the water surface. + fresnelTerm *= saturate( IN.pixelDist - 0.1 ); + + // Combine the diffuse color and reflection image via the + // fresnel term and set out output color. + vec4 gl_FragColor = lerp( diffuseColor, reflectColor, fresnelTerm ); + + //float brightness = saturate( 1.0 - ( waterHeight - eyePosWorld.z - 5.0 ) / 50.0 ); + //gl_FragColor.rgb *= brightness; + +#else + vec4 refractColor = tex2D( refractBuff, refractCoord ); + vec4 gl_FragColor = refractColor; +#endif + +#ifndef UNDERWATER + gl_FragColor.rgb = lerp( gl_FragColor.rgb, foamColor.rgb, foamAmt ); +#endif + + gl_FragColor.a = 1.0; + + // specular experiments + +// 1: +/* + float fDot = dot( bumpNorm, inLightVec ); + vec3 reflect = normalize( 2.0 * bumpNorm * fDot - eyeVec ); + // float specular = saturate(dot( reflect, inLightVec ) ); + float specular = pow( reflect, specularPower ); + gl_FragColor += specularColor * specular; +*/ + + +// 2: This almost looks good +/* + bumpNorm.xy *= 2.0; + bumpNorm = normalize( bumpNorm ); + + vec3 halfAng = normalize( eyeVec + inLightVec ); + float specular = saturate( dot( bumpNorm, halfAng) ); + specular = pow(specular, specularPower); + gl_FragColor += specularColor * specular; +*/ + +#ifndef UNDERWATER + + float factor = computeSceneFog( eyePos, + IN.fogPos, + IN.worldSpaceZ, + fogData.x, + fogData.y, + fogData.z ); + + gl_FragColor.rgb = lerp( gl_FragColor.rgb, fogColor.rgb, 1.0 - saturate( factor ) ); + +#endif + + //return vec4( refMapColor.rgb, 1 ); + gl_FragColor.a = 1.0; + + return gl_FragColor; +} diff --git a/Templates/Empty/game/shaders/common/water/gl/waterV.glsl b/Templates/Empty/game/shaders/common/water/gl/waterV.glsl new file mode 100644 index 000000000..d4337476f --- /dev/null +++ b/Templates/Empty/game/shaders/common/water/gl/waterV.glsl @@ -0,0 +1,177 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- + +// waveData +#define WAVE_SPEED(i) waveData[i].x +#define WAVE_MAGNITUDE(i) waveData[i].y + +// Outgoing data +// Worldspace position of this pixel +varying vec3 worldPos; + +// TexCoord 0 and 1 (xy,zw) for ripple texture lookup +varying vec4 rippleTexCoord01; + +// TexCoord 2 for ripple texture lookup +varying vec2 rippleTexCoord2; + +// Screenspace vert position BEFORE wave transformation +varying vec4 posPreWave; + +// Screenspace vert position AFTER wave transformation +varying vec4 posPostWave; + +// Worldspace unit distance/depth of this vertex/pixel +varying float pixelDist; + +varying vec3 fogPos; + +varying float worldSpaceZ; + +varying vec4 foamTexCoords; + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- +uniform mat4 modelMat; +uniform mat4 modelview; +uniform mat3 cubeTrans; +uniform mat4 objTrans; +uniform vec3 cubeEyePos; +uniform vec3 eyePos; +uniform vec2 waveDir[3]; +uniform vec2 waveData[3]; +uniform vec2 rippleDir[3]; +uniform vec2 rippleTexScale[3]; +uniform vec3 rippleSpeed; +uniform vec2 reflectTexSize; +uniform vec3 inLightVec; +uniform vec3 reflectNormal; +uniform float gridElementSize; +uniform float elapsedTime; +uniform float undulateMaxDist; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + // Copy incoming attributes into locals so we can modify them in place. + vec4 position = gl_Vertex.xyzw; + vec3 normal = gl_Normal.xyz; + vec2 undulateData = gl_MultiTexCoord0.st; + vec4 horizonFactor = gl_MultiTexCoord1.xyzw; + + // use projection matrix for reflection / refraction texture coords + mat4 texGen = { 0.5, 0.0, 0.0, 0.5, //+ 0.5 / reflectTexSize.x, + 0.0, 0.5, 0.0, 0.5, //+ 1.0 / reflectTexSize.y, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 }; + + // Move the vertex based on the horizonFactor if specified to do so for this vert. + if ( horizonFactor.z > 0 ) + { + vec2 offsetXY = eyePos.xy - eyePos.xy % gridElementSize; + position.xy += offsetXY; + undulateData += offsetXY; + } + + fogPos = position; + position.z = mix( position.z, eyePos.z, horizonFactor.x ); + + // Send pre-undulation screenspace position + posPreWave = modelview * position; + posPreWave = texGen * posPreWave; + + // Calculate the undulation amount for this vertex. + vec2 undulatePos = undulateData; + float undulateAmt = 0; + + for ( int i = 0; i < 3; i++ ) + { + undulateAmt += WAVE_MAGNITUDE(i) * sin( elapsedTime * WAVE_SPEED(i) + + undulatePos.x * waveDir[i].x + + undulatePos.y * waveDir[i].y ); + } + + // Scale down wave magnitude amount based on distance from the camera. + float dist = distance( position, eyePos ); + dist = clamp( dist, 1.0, undulateMaxDist ); + undulateAmt *= ( 1 - dist / undulateMaxDist ); + + // Also scale down wave magnitude if the camera is very very close. + undulateAmt *= clamp( ( distance( IN.position, eyePos ) - 0.5 ) / 10.0, 0.0, 1.0 ); + + // Apply wave undulation to the vertex. + posPostWave = position; + posPostWave.xyz += normal.xyz * undulateAmt; + + // Save worldSpace position of this pixel/vert + worldPos = posPostWave.xyz; + + // Convert to screen + posPostWave = modelview * posPostWave; + + // Setup the OUT position symantic variable + gl_Position = posPostWave; + gl_Position.z = mix(gl_Position.z, gl_Position.w, horizonFactor.x); + + worldSpaceZ = modelMat * vec4(fogPos, 1.0) ).z; + if ( horizonFactor.x > 0.0 ) + { + vec3 awayVec = normalize( fogPos.xyz - eyePos ); + fogPos.xy += awayVec.xy * 1000.0; + } + + // Save world space camera dist/depth of the outgoing pixel + pixelDist = gl_Position.z; + + // Convert to reflection texture space + posPostWave = texGen * posPostWave; + + float2 ripplePos = undulateData; + float2 txPos = normalize( ripplePos ); + txPos *= 50000.0; + ripplePos = mix( ripplePos, txPos, IN.horizonFactor.x ); + + // set up tex coordinates for the 3 interacting normal maps + rippleTexCoord01.xy = mix( ripplePos * rippleTexScale[0], txPos.xy * rippleTexScale[0], IN.horizonFactor.x ); + rippleTexCoord01.xy += rippleDir[0] * elapsedTime * rippleSpeed.x; + + rippleTexCoord01.zw = mix( ripplePos * rippleTexScale[1], txPos.xy * rippleTexScale[1], IN.horizonFactor.x ); + rippleTexCoord01.zw += rippleDir[1] * elapsedTime * rippleSpeed.y; + + rippleTexCoord2.xy = mix( ripplePos * rippleTexScale[2], txPos.xy * rippleTexScale[2], IN.horizonFactor.x ); + rippleTexCoord2.xy += rippleDir[2] * elapsedTime * rippleSpeed.z; + + foamTexCoords.xy = mix( ripplePos * 0.2, txPos.xy * rippleTexScale[0], IN.horizonFactor.x ); + foamTexCoords.xy += rippleDir[0] * sin( ( elapsedTime + 500.0 ) * -0.4 ) * 0.15; + + foamTexCoords.zw = mix( ripplePos * 0.3, txPos.xy * rippleTexScale[1], IN.horizonFactor.x ); + foamTexCoords.zw += rippleDir[1] * sin( elapsedTime * 0.4 ) * 0.15; +} diff --git a/Templates/Empty/game/shaders/common/water/waterBasicP.hlsl b/Templates/Empty/game/shaders/common/water/waterBasicP.hlsl new file mode 100644 index 000000000..d27b28c67 --- /dev/null +++ b/Templates/Empty/game/shaders/common/water/waterBasicP.hlsl @@ -0,0 +1,213 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "../torque.hlsl" + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- + +// miscParams +#define FRESNEL_BIAS miscParams[0] +#define FRESNEL_POWER miscParams[1] +#define CLARITY miscParams[2] +#define ISRIVER miscParams[3] + +// reflectParams +#define REFLECT_PLANE_Z reflectParams[0] +#define REFLECT_MIN_DIST reflectParams[1] +#define REFLECT_MAX_DIST reflectParams[2] +#define NO_REFLECT reflectParams[3] + +// distortionParams +#define DISTORT_START_DIST distortionParams[0] +#define DISTORT_END_DIST distortionParams[1] +#define DISTORT_FULL_DEPTH distortionParams[2] + +// ConnectData.misc +#define LIGHT_VEC IN.misc.xyz +#define WORLD_Z IN.objPos.w + +// specularParams +#define SPEC_POWER specularParams[3] +#define SPEC_COLOR specularParams.xyz + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- + +struct ConnectData +{ + float4 hpos : POSITION; + + // TexCoord 0 and 1 (xy,zw) for ripple texture lookup + float4 rippleTexCoord01 : TEXCOORD0; + + // TexCoord 2 for ripple texture lookup + float2 rippleTexCoord2 : TEXCOORD1; + + // Screenspace vert position BEFORE wave transformation + float4 posPreWave : TEXCOORD2; + + // Screenspace vert position AFTER wave transformation + float4 posPostWave : TEXCOORD3; + + // Worldspace unit distance/depth of this vertex/pixel + float pixelDist : TEXCOORD4; + + // Objectspace vert position BEFORE wave transformation + // w coord is world space z position. + float4 objPos : TEXCOORD5; + + float3 misc : TEXCOORD6; +}; + +//----------------------------------------------------------------------------- +// approximate Fresnel function +//----------------------------------------------------------------------------- +float fresnel(float NdotV, float bias, float power) +{ + return bias + (1.0-bias)*pow(abs(1.0 - max(NdotV, 0)), power); +} + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- +uniform sampler bumpMap : register( S0 ); +//uniform sampler2D prepassTex : register( S1 ); +uniform sampler2D reflectMap : register( S2 ); +uniform sampler refractBuff : register( S3 ); +uniform samplerCUBE skyMap : register( S4 ); +//uniform sampler foamMap : register( S5 ); +uniform float4 baseColor; +uniform float4 miscParams; +uniform float4 reflectParams; +uniform float3 ambientColor; +uniform float3 eyePos; +uniform float3 distortionParams; +uniform float3 fogData; +uniform float4 fogColor; +uniform float4 rippleMagnitude; +uniform float4 specularParams; +uniform float4x4 modelMat; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +float4 main( ConnectData IN ) : COLOR +{ + // Modulate baseColor by the ambientColor. + float4 waterBaseColor = baseColor * float4( ambientColor.rgb, 1 ); + + // Get the bumpNorm... + float3 bumpNorm = ( tex2D( bumpMap, IN.rippleTexCoord01.xy ).rgb * 2.0 - 1.0 ) * rippleMagnitude.x; + bumpNorm += ( tex2D( bumpMap, IN.rippleTexCoord01.zw ).rgb * 2.0 - 1.0 ) * rippleMagnitude.y; + bumpNorm += ( tex2D( bumpMap, IN.rippleTexCoord2 ).rgb * 2.0 - 1.0 ) * rippleMagnitude.z; + + bumpNorm = normalize( bumpNorm ); + bumpNorm = lerp( bumpNorm, float3(0,0,1), 1.0 - rippleMagnitude.w ); + + // We subtract a little from it so that we don't + // distort where the water surface intersects the + // camera near plane. + float distortAmt = saturate( IN.pixelDist / 1.0 ) * 0.8; + + float4 distortPos = IN.posPostWave; + distortPos.xy += bumpNorm.xy * distortAmt; + + #ifdef UNDERWATER + return hdrEncode( tex2Dproj( refractBuff, distortPos ) ); + #else + + float3 eyeVec = IN.objPos.xyz - eyePos; + eyeVec = mul( (float3x3)modelMat, eyeVec ); + float3 reflectionVec = reflect( eyeVec, bumpNorm ); + + // Color that replaces the reflection color when we do not + // have one that is appropriate. + float4 fakeColor = float4(ambientColor,1); + + // Use fakeColor for ripple-normals that are angled towards the camera + eyeVec = -eyeVec; + eyeVec = normalize( eyeVec ); + float ang = saturate( dot( eyeVec, bumpNorm ) ); + float fakeColorAmt = ang; + + // Get reflection map color + float4 refMapColor = hdrDecode( tex2Dproj( reflectMap, distortPos ) ); + // If we do not have a reflection texture then we use the cubemap. + refMapColor = lerp( refMapColor, texCUBE( skyMap, reflectionVec ), NO_REFLECT ); + + // Combine reflection color and fakeColor. + float4 reflectColor = lerp( refMapColor, fakeColor, fakeColorAmt ); + //return refMapColor; + + // Get refract color + float4 refractColor = hdrDecode( tex2Dproj( refractBuff, distortPos ) ); + + // calc "diffuse" color by lerping from the water color + // to refraction image based on the water clarity. + float4 diffuseColor = lerp( refractColor, waterBaseColor, 1.0f - CLARITY ); + + // fresnel calculation + float fresnelTerm = fresnel( ang, FRESNEL_BIAS, FRESNEL_POWER ); + //return float4( fresnelTerm.rrr, 1 ); + + // Also scale the frensel by our distance to the + // water surface. This removes the hard reflection + // when really close to the water surface. + fresnelTerm *= saturate( IN.pixelDist - 0.1 ); + + // Combine the diffuse color and reflection image via the + // fresnel term and set out output color. + float4 OUT = lerp( diffuseColor, reflectColor, fresnelTerm ); + + #ifdef WATER_SPEC + + // Get some specular reflection. + float3 newbump = bumpNorm; + newbump.xy *= 3.5; + newbump = normalize( bumpNorm ); + half3 halfAng = normalize( eyeVec + -LIGHT_VEC ); + float specular = saturate( dot( newbump, halfAng ) ); + specular = pow( specular, SPEC_POWER ); + + OUT.rgb = OUT.rgb + ( SPEC_COLOR * specular.xxx ); + + #else // Disable fogging if spec is on because otherwise we run out of instructions. + + // Fog it. + float factor = computeSceneFog( eyePos, + IN.objPos, + WORLD_Z, + fogData.x, + fogData.y, + fogData.z ); + + //OUT.rgb = lerp( OUT.rgb, fogColor.rgb, 1.0 - saturate( factor ) ); + + #endif + + return hdrEncode( OUT ); + +#endif +} diff --git a/Templates/Empty/game/shaders/common/water/waterBasicV.hlsl b/Templates/Empty/game/shaders/common/water/waterBasicV.hlsl new file mode 100644 index 000000000..2c201e675 --- /dev/null +++ b/Templates/Empty/game/shaders/common/water/waterBasicV.hlsl @@ -0,0 +1,236 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +struct VertData +{ + float4 position : POSITION; + float3 normal : NORMAL; + float2 undulateData : TEXCOORD0; + float4 horizonFactor : TEXCOORD1; +}; + +struct ConnectData +{ + float4 hpos : POSITION; + + // TexCoord 0 and 1 (xy,zw) for ripple texture lookup + float4 rippleTexCoord01 : TEXCOORD0; + + // TexCoord 2 for ripple texture lookup + float2 rippleTexCoord2 : TEXCOORD1; + + // Screenspace vert position BEFORE wave transformation + float4 posPreWave : TEXCOORD2; + + // Screenspace vert position AFTER wave transformation + float4 posPostWave : TEXCOORD3; + + // Worldspace unit distance/depth of this vertex/pixel + float pixelDist : TEXCOORD4; + + // Objectspace vert position BEFORE wave transformation + // w coord is world space z position. + float4 objPos : TEXCOORD5; + + float3 misc : TEXCOORD6; +}; + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- +uniform float4x4 modelMat; +uniform float4x4 modelview; +uniform float4 rippleMat[3]; +uniform float3 eyePos; +uniform float2 waveDir[3]; +uniform float2 waveData[3]; +uniform float2 rippleDir[3]; +uniform float2 rippleTexScale[3]; +uniform float3 rippleSpeed; +uniform float3 inLightVec; +uniform float3 reflectNormal; +uniform float gridElementSize; +uniform float elapsedTime; +uniform float undulateMaxDist; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( VertData IN ) +{ + ConnectData OUT; + + // use projection matrix for reflection / refraction texture coords + float4x4 texGen = { 0.5, 0.0, 0.0, 0.5, + 0.0, -0.5, 0.0, 0.5, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 }; + + // Move the vertex based on the horizonFactor if specified to do so for this vert. + // if ( IN.horizonFactor.z > 0 ) + // { + // float2 offsetXY = eyePos.xy - eyePos.xy % gridElementSize; + // IN.position.xy += offsetXY; + // IN.undulateData += offsetXY; + // } + + float4 worldPos = mul( modelMat, IN.position ); + + IN.position.z = lerp( IN.position.z, eyePos.z, IN.horizonFactor.x ); + + //OUT.objPos = worldPos; + OUT.objPos.xyz = IN.position.xyz; + OUT.objPos.w = worldPos.z; + + // Send pre-undulation screenspace position + OUT.posPreWave = mul( modelview, IN.position ); + OUT.posPreWave = mul( texGen, OUT.posPreWave ); + + // Calculate the undulation amount for this vertex. + float2 undulatePos = mul( modelMat, float4( IN.undulateData.xy, 0, 1 ) ); + //if ( undulatePos.x < 0 ) + // undulatePos = IN.position.xy; + + float undulateAmt = 0.0; + + undulateAmt += waveData[0].y * sin( elapsedTime * waveData[0].x + + undulatePos.x * waveDir[0].x + + undulatePos.y * waveDir[0].y ); + undulateAmt += waveData[1].y * sin( elapsedTime * waveData[1].x + + undulatePos.x * waveDir[1].x + + undulatePos.y * waveDir[1].y ); + undulateAmt += waveData[2].y * sin( elapsedTime * waveData[2].x + + undulatePos.x * waveDir[2].x + + undulatePos.y * waveDir[2].y ); + + float undulateFade = 1; + + // Scale down wave magnitude amount based on distance from the camera. + float dist = distance( IN.position.xyz, eyePos ); + dist = clamp( dist, 1.0, undulateMaxDist ); + undulateFade *= ( 1 - dist / undulateMaxDist ); + + // Also scale down wave magnitude if the camera is very very close. + undulateFade *= saturate( ( distance( IN.position.xyz, eyePos ) - 0.5 ) / 10.0 ); + + undulateAmt *= undulateFade; + + //#endif + //undulateAmt = 0; + + // Apply wave undulation to the vertex. + OUT.posPostWave = IN.position; + OUT.posPostWave.xyz += IN.normal.xyz * undulateAmt; + + // Save worldSpace position of this pixel/vert + //OUT.worldPos = OUT.posPostWave.xyz; + //OUT.worldPos = mul( modelMat, OUT.posPostWave.xyz ); + //OUT.worldPos.z += objTrans[2][2]; //91.16; + + // OUT.misc.w = mul( modelMat, OUT.fogPos ).z; + // if ( IN.horizonFactor.x > 0 ) + // { + // float3 awayVec = normalize( OUT.fogPos.xyz - eyePos ); + // OUT.fogPos.xy += awayVec.xy * 1000.0; + // } + + // Convert to screen + OUT.posPostWave = mul( modelview, OUT.posPostWave ); // mul( modelview, float4( OUT.posPostWave.xyz, 1 ) ); + + // Setup the OUT position symantic variable + OUT.hpos = OUT.posPostWave; // mul( modelview, float4( IN.position.xyz, 1 ) ); //float4( OUT.posPostWave.xyz, 1 ); + //OUT.hpos.z = lerp( OUT.hpos.z, OUT.hpos.w, IN.horizonFactor.x ); + + // Save world space camera dist/depth of the outgoing pixel + OUT.pixelDist = OUT.hpos.z; + + // Convert to reflection texture space + OUT.posPostWave = mul( texGen, OUT.posPostWave ); + + float2 txPos = undulatePos; + if ( IN.horizonFactor.x ) + txPos = normalize( txPos ) * 50000.0; + + // set up tex coordinates for the 3 interacting normal maps + OUT.rippleTexCoord01.xy = txPos * rippleTexScale[0]; + OUT.rippleTexCoord01.xy += rippleDir[0] * elapsedTime * rippleSpeed.x; + + float2x2 texMat; + texMat[0][0] = rippleMat[0].x; + texMat[0][1] = rippleMat[0].y; + texMat[1][0] = rippleMat[0].z; + texMat[1][1] = rippleMat[0].w; + OUT.rippleTexCoord01.xy = mul( texMat, OUT.rippleTexCoord01.xy ); + + OUT.rippleTexCoord01.zw = txPos * rippleTexScale[1]; + OUT.rippleTexCoord01.zw += rippleDir[1] * elapsedTime * rippleSpeed.y; + + texMat[0][0] = rippleMat[1].x; + texMat[0][1] = rippleMat[1].y; + texMat[1][0] = rippleMat[1].z; + texMat[1][1] = rippleMat[1].w; + OUT.rippleTexCoord01.zw = mul( texMat, OUT.rippleTexCoord01.zw ); + + OUT.rippleTexCoord2.xy = txPos * rippleTexScale[2]; + OUT.rippleTexCoord2.xy += rippleDir[2] * elapsedTime * rippleSpeed.z; + + texMat[0][0] = rippleMat[2].x; + texMat[0][1] = rippleMat[2].y; + texMat[1][0] = rippleMat[2].z; + texMat[1][1] = rippleMat[2].w; + OUT.rippleTexCoord2.xy = mul( texMat, OUT.rippleTexCoord2.xy ); + +#ifdef WATER_SPEC + + float3 binormal = float3( 1, 0, 0 ); + float3 tangent = float3( 0, 1, 0 ); + float3 normal; + for ( int i = 0; i < 3; i++ ) + { + binormal.z += undulateFade * waveDir[i].x * waveData[i].y * cos( waveDir[i].x * IN.undulateData.x + waveDir[i].y * IN.undulateData.y + elapsedTime * waveData[i].x ); + tangent.z += undulateFade * waveDir[i].y * waveData[i].y * cos( waveDir[i].x * IN.undulateData.x + waveDir[i].y * IN.undulateData.y + elapsedTime * waveData[i].x ); + } + + binormal = normalize( binormal ); + tangent = normalize( tangent ); + normal = cross( binormal, tangent ); + + float3x3 worldToTangent; + worldToTangent[0] = binormal; + worldToTangent[1] = tangent; + worldToTangent[2] = normal; + + OUT.misc.xyz = mul( inLightVec, modelMat ); + OUT.misc.xyz = mul( worldToTangent, OUT.misc.xyz ); + +#else + + OUT.misc.xyz = inLightVec; + +#endif + + return OUT; +} + diff --git a/Templates/Empty/game/shaders/common/water/waterP.hlsl b/Templates/Empty/game/shaders/common/water/waterP.hlsl new file mode 100644 index 000000000..851fb471f --- /dev/null +++ b/Templates/Empty/game/shaders/common/water/waterP.hlsl @@ -0,0 +1,383 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" +#include "../torque.hlsl" + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- + +#define PIXEL_DIST IN.rippleTexCoord2.z +// miscParams +#define FRESNEL_BIAS miscParams[0] +#define FRESNEL_POWER miscParams[1] +// miscParams[2] is unused +#define ISRIVER miscParams[3] + +// reflectParams +#define REFLECT_PLANE_Z reflectParams[0] +#define REFLECT_MIN_DIST reflectParams[1] +#define REFLECT_MAX_DIST reflectParams[2] +#define NO_REFLECT reflectParams[3] + +// fogParams +#define FOG_DENSITY fogParams[0] +#define FOG_DENSITY_OFFSET fogParams[1] + +// wetnessParams +#define WET_DEPTH wetnessParams[0] +#define WET_COLOR_FACTOR wetnessParams[1] + +// distortionParams +#define DISTORT_START_DIST distortionParams[0] +#define DISTORT_END_DIST distortionParams[1] +#define DISTORT_FULL_DEPTH distortionParams[2] + +// foamParams +#define FOAM_OPACITY foamParams[0] +#define FOAM_MAX_DEPTH foamParams[1] +#define FOAM_AMBIENT_LERP foamParams[2] +#define FOAM_RIPPLE_INFLUENCE foamParams[3] + +// specularParams +#define SPEC_POWER specularParams[3] +#define SPEC_COLOR specularParams.xyz + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- + +struct ConnectData +{ + float4 hpos : POSITION; + + // TexCoord 0 and 1 (xy,zw) for ripple texture lookup + float4 rippleTexCoord01 : TEXCOORD0; + + // xy is TexCoord 2 for ripple texture lookup + // z is the Worldspace unit distance/depth of this vertex/pixel + // w is amount of the crestFoam ( more at crest of waves ). + float4 rippleTexCoord2 : TEXCOORD1; + + // Screenspace vert position BEFORE wave transformation + float4 posPreWave : TEXCOORD2; + + // Screenspace vert position AFTER wave transformation + float4 posPostWave : TEXCOORD3; + + // Objectspace vert position BEFORE wave transformation + // w coord is world space z position. + float4 objPos : TEXCOORD4; + + float4 foamTexCoords : TEXCOORD5; + + float3x3 tangentMat : TEXCOORD6; +}; + +//----------------------------------------------------------------------------- +// approximate Fresnel function +//----------------------------------------------------------------------------- +float fresnel(float NdotV, float bias, float power) +{ + return bias + (1.0-bias)*pow(abs(1.0 - max(NdotV, 0)), power); +} + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- +uniform sampler bumpMap : register( S0 ); +uniform sampler2D prepassTex : register( S1 ); +uniform sampler2D reflectMap : register( S2 ); +uniform sampler refractBuff : register( S3 ); +uniform samplerCUBE skyMap : register( S4 ); +uniform sampler foamMap : register( S5 ); +uniform sampler1D depthGradMap : register( S6 ); +uniform float4 specularParams; +uniform float4 baseColor; +uniform float4 miscParams; +uniform float2 fogParams; +uniform float4 reflectParams; +uniform float3 reflectNormal; +uniform float2 wetnessParams; +uniform float farPlaneDist; +uniform float3 distortionParams; +uniform float4 foamParams; +uniform float3 ambientColor; +uniform float3 eyePos; // This is in object space! +uniform float3 fogData; +uniform float4 fogColor; +uniform float4 rippleMagnitude; +uniform float4 rtParams1; +uniform float depthGradMax; +uniform float3 inLightVec; +uniform float4x4 modelMat; +uniform float4 sunColor; +uniform float sunBrightness; +uniform float reflectivity; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +float4 main( ConnectData IN ) : COLOR +{ + // Get the bumpNorm... + float3 bumpNorm = ( tex2D( bumpMap, IN.rippleTexCoord01.xy ).rgb * 2.0 - 1.0 ) * rippleMagnitude.x; + bumpNorm += ( tex2D( bumpMap, IN.rippleTexCoord01.zw ).rgb * 2.0 - 1.0 ) * rippleMagnitude.y; + bumpNorm += ( tex2D( bumpMap, IN.rippleTexCoord2.xy ).rgb * 2.0 - 1.0 ) * rippleMagnitude.z; + + bumpNorm = normalize( bumpNorm ); + bumpNorm = lerp( bumpNorm, float3(0,0,1), 1.0 - rippleMagnitude.w ); + bumpNorm = mul( bumpNorm, IN.tangentMat ); + + // Get depth of the water surface (this pixel). + // Convert from WorldSpace to EyeSpace. + float pixelDepth = PIXEL_DIST / farPlaneDist; + + float2 prepassCoord = viewportCoordToRenderTarget( IN.posPostWave, rtParams1 ); + + float startDepth = prepassUncondition( prepassTex, prepassCoord ).w; + + // The water depth in world units of the undistorted pixel. + float startDelta = ( startDepth - pixelDepth ); + startDelta = max( startDelta, 0.0 ); + startDelta *= farPlaneDist; + + // Calculate the distortion amount for the water surface. + // + // We subtract a little from it so that we don't + // distort where the water surface intersects the + // camera near plane. + float distortAmt = saturate( ( PIXEL_DIST - DISTORT_START_DIST ) / DISTORT_END_DIST ); + + // Scale down distortion in shallow water. + distortAmt *= saturate( startDelta / DISTORT_FULL_DEPTH ); + + // Do the intial distortion... we might remove it below. + float2 distortDelta = bumpNorm.xy * distortAmt; + float4 distortPos = IN.posPostWave; + distortPos.xy += distortDelta; + + prepassCoord = viewportCoordToRenderTarget( distortPos, rtParams1 ); + + // Get prepass depth at the position of this distorted pixel. + float prepassDepth = prepassUncondition( prepassTex, prepassCoord ).w; + if ( prepassDepth > 0.99 ) + prepassDepth = 5.0; + + float delta = ( prepassDepth - pixelDepth ) * farPlaneDist; + + if ( delta < 0.0 ) + { + // If we got a negative delta then the distorted + // sample is above the water surface. Mask it out + // by removing the distortion. + distortPos = IN.posPostWave; + delta = startDelta; + distortAmt = 0; + } + else + { + float diff = ( prepassDepth - startDepth ) * farPlaneDist; + + if ( diff < 0 ) + { + distortAmt = saturate( ( PIXEL_DIST - DISTORT_START_DIST ) / DISTORT_END_DIST ); + distortAmt *= saturate( delta / DISTORT_FULL_DEPTH ); + + distortDelta = bumpNorm.xy * distortAmt; + + distortPos = IN.posPostWave; + distortPos.xy += distortDelta; + + prepassCoord = viewportCoordToRenderTarget( distortPos, rtParams1 ); + + // Get prepass depth at the position of this distorted pixel. + prepassDepth = prepassUncondition( prepassTex, prepassCoord ).w; + if ( prepassDepth > 0.99 ) + prepassDepth = 5.0; + delta = ( prepassDepth - pixelDepth ) * farPlaneDist; + } + + if ( delta < 0.1 ) + { + // If we got a negative delta then the distorted + // sample is above the water surface. Mask it out + // by removing the distortion. + distortPos = IN.posPostWave; + delta = startDelta; + distortAmt = 0; + } + } + + float4 temp = IN.posPreWave; + temp.xy += bumpNorm.xy * distortAmt; + float2 reflectCoord = viewportCoordToRenderTarget( temp, rtParams1 ); + + float2 refractCoord = viewportCoordToRenderTarget( distortPos, rtParams1 ); + + float4 fakeColor = float4(ambientColor,1); + float3 eyeVec = IN.objPos.xyz - eyePos; + eyeVec = mul( (float3x3)modelMat, eyeVec ); + eyeVec = mul( IN.tangentMat, eyeVec ); + float3 reflectionVec = reflect( eyeVec, bumpNorm ); + + // Use fakeColor for ripple-normals that are angled towards the camera + eyeVec = -eyeVec; + eyeVec = normalize( eyeVec ); + float ang = saturate( dot( eyeVec, bumpNorm ) ); + float fakeColorAmt = ang; + + // for verts far from the reflect plane z position + float rplaneDist = abs( REFLECT_PLANE_Z - IN.objPos.w ); + rplaneDist = saturate( ( rplaneDist - 1.0 ) / 2.0 ); + rplaneDist *= ISRIVER; + fakeColorAmt = max( fakeColorAmt, rplaneDist ); + +#ifndef UNDERWATER + + // Get foam color and amount + float2 foamRippleOffset = bumpNorm.xy * FOAM_RIPPLE_INFLUENCE; + IN.foamTexCoords.xy += foamRippleOffset; + IN.foamTexCoords.zw += foamRippleOffset; + + float4 foamColor = tex2D( foamMap, IN.foamTexCoords.xy ); + foamColor += tex2D( foamMap, IN.foamTexCoords.zw ); + foamColor = saturate( foamColor ); + + // Modulate foam color by ambient color + // so we don't have glowing white foam at night. + foamColor.rgb = lerp( foamColor.rgb, ambientColor.rgb, FOAM_AMBIENT_LERP ); + + float foamDelta = saturate( delta / FOAM_MAX_DEPTH ); + float foamAmt = 1 - pow( foamDelta, 2 ); + + // Fade out the foam in very very low depth, + // this improves the shoreline a lot. + float diff = 0.8 - foamAmt; + if ( diff < 0.0 ) + foamAmt -= foamAmt * abs( diff ) / 0.2; + + foamAmt *= FOAM_OPACITY * foamColor.a; + + foamColor.rgb *= FOAM_OPACITY * foamAmt * foamColor.a; + + // Get reflection map color. + float4 refMapColor = hdrDecode( tex2D( reflectMap, reflectCoord ) ); + + // If we do not have a reflection texture then we use the cubemap. + refMapColor = lerp( refMapColor, texCUBE( skyMap, reflectionVec ), NO_REFLECT ); + + fakeColor = ( texCUBE( skyMap, reflectionVec ) ); + fakeColor.a = 1; + // Combine reflection color and fakeColor. + float4 reflectColor = lerp( refMapColor, fakeColor, fakeColorAmt ); + + // Get refract color + float4 refractColor = hdrDecode( tex2D( refractBuff, refractCoord ) ); + + // We darken the refraction color a bit to make underwater + // elements look wet. We fade out this darkening near the + // surface in order to not have hard water edges. + // @param WET_DEPTH The depth in world units at which full darkening will be recieved. + // @param WET_COLOR_FACTOR The refract color is scaled down by this amount when at WET_DEPTH + refractColor.rgb *= 1.0f - ( saturate( delta / WET_DEPTH ) * WET_COLOR_FACTOR ); + + // Add Water fog/haze. + float fogDelta = delta - FOG_DENSITY_OFFSET; + + if ( fogDelta < 0.0 ) + fogDelta = 0.0; + float fogAmt = 1.0 - saturate( exp( -FOG_DENSITY * fogDelta ) ); + + // Calculate the water "base" color based on depth. + float4 waterBaseColor = baseColor * tex1D( depthGradMap, saturate( delta / depthGradMax ) ); + + // Modulate baseColor by the ambientColor. + waterBaseColor *= float4( ambientColor.rgb, 1 ); + + // calc "diffuse" color by lerping from the water color + // to refraction image based on the water clarity. + float4 diffuseColor = lerp( refractColor, waterBaseColor, fogAmt ); + + // fresnel calculation + float fresnelTerm = fresnel( ang, FRESNEL_BIAS, FRESNEL_POWER ); + + // Scale the frensel strength by fog amount + // so that parts that are very clear get very little reflection. + fresnelTerm *= fogAmt; + + // Also scale the frensel by our distance to the + // water surface. This removes the hard reflection + // when really close to the water surface. + fresnelTerm *= saturate( PIXEL_DIST - 0.1 ); + + fresnelTerm *= reflectivity; + + // Combine the diffuse color and reflection image via the + // fresnel term and set out output color. + float4 OUT = lerp( diffuseColor, reflectColor, fresnelTerm ); + + float3 lightVec = inLightVec; + + // Get some specular reflection. + float3 newbump = bumpNorm; + newbump.xy *= 3.5; + newbump = normalize( bumpNorm ); + float3 halfAng = normalize( eyeVec + -lightVec ); + float specular = saturate( dot( newbump, halfAng ) ); + specular = pow( specular, SPEC_POWER ); + + // Scale down specularity in very shallow water to improve the transparency of the shoreline. + specular *= saturate( delta / 2 ); + OUT.rgb = OUT.rgb + ( SPEC_COLOR * specular.xxx ); + +#else + + float4 refractColor = hdrDecode( tex2D( refractBuff, refractCoord ) ); + float4 OUT = refractColor; + +#endif + +#ifndef UNDERWATER + + OUT.rgb = OUT.rgb + foamColor.rgb; + + float factor = computeSceneFog( eyePos, + IN.objPos.xyz, + IN.objPos.w, + fogData.x, + fogData.y, + fogData.z ); + + OUT.rgb = lerp( OUT.rgb, fogColor.rgb, 1.0 - saturate( factor ) ); + + //OUT.rgb = fogColor.rgb; + +#endif + + OUT.a = 1.0; + + //return OUT; + + return hdrEncode( OUT ); +} diff --git a/Templates/Empty/game/shaders/common/water/waterV.hlsl b/Templates/Empty/game/shaders/common/water/waterV.hlsl new file mode 100644 index 000000000..d2b097bc5 --- /dev/null +++ b/Templates/Empty/game/shaders/common/water/waterV.hlsl @@ -0,0 +1,216 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +struct VertData +{ + float4 position : POSITION; + float3 normal : NORMAL; + float2 undulateData : TEXCOORD0; + float4 horizonFactor : TEXCOORD1; +}; + +struct ConnectData +{ + float4 hpos : POSITION; + + // TexCoord 0 and 1 (xy,zw) for ripple texture lookup + float4 rippleTexCoord01 : TEXCOORD0; + + // xy is TexCoord 2 for ripple texture lookup + // z is the Worldspace unit distance/depth of this vertex/pixel + // w is amount of the crestFoam ( more at crest of waves ). + float4 rippleTexCoord2 : TEXCOORD1; + + // Screenspace vert position BEFORE wave transformation + float4 posPreWave : TEXCOORD2; + + // Screenspace vert position AFTER wave transformation + float4 posPostWave : TEXCOORD3; + + // Objectspace vert position BEFORE wave transformation + // w coord is world space z position. + float4 objPos : TEXCOORD4; + + float4 foamTexCoords : TEXCOORD5; + + float3x3 tangentMat : TEXCOORD6; +}; + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- +uniform float4x4 modelMat; +uniform float4x4 modelview; +uniform float4 rippleMat[3]; +uniform float3 eyePos; +uniform float2 waveDir[3]; +uniform float2 waveData[3]; +uniform float2 rippleDir[3]; +uniform float2 rippleTexScale[3]; +uniform float3 rippleSpeed; +uniform float4 foamDir; +uniform float4 foamTexScale; +uniform float2 foamSpeed; +uniform float3 inLightVec; +uniform float gridElementSize; +uniform float elapsedTime; +uniform float undulateMaxDist; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( VertData IN ) +{ + ConnectData OUT; + + // use projection matrix for reflection / refraction texture coords + float4x4 texGen = { 0.5, 0.0, 0.0, 0.5, + 0.0, -0.5, 0.0, 0.5, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 }; + + IN.position.z = lerp( IN.position.z, eyePos.z, IN.horizonFactor.x ); + + OUT.objPos = IN.position; + OUT.objPos.w = mul( modelMat, IN.position ).z; + + // Send pre-undulation screenspace position + OUT.posPreWave = mul( modelview, IN.position ); + OUT.posPreWave = mul( texGen, OUT.posPreWave ); + + // Calculate the undulation amount for this vertex. + float2 undulatePos = mul( modelMat, float4( IN.undulateData.xy, 0, 1 ) ).xy; + float undulateAmt = 0.0; + + undulateAmt += waveData[0].y * sin( elapsedTime * waveData[0].x + + undulatePos.x * waveDir[0].x + + undulatePos.y * waveDir[0].y ); + undulateAmt += waveData[1].y * sin( elapsedTime * waveData[1].x + + undulatePos.x * waveDir[1].x + + undulatePos.y * waveDir[1].y ); + undulateAmt += waveData[2].y * sin( elapsedTime * waveData[2].x + + undulatePos.x * waveDir[2].x + + undulatePos.y * waveDir[2].y ); + + float undulateFade = 1; + + // Scale down wave magnitude amount based on distance from the camera. + float dist = distance( IN.position.xyz, eyePos ); + dist = clamp( dist, 1.0, undulateMaxDist ); + undulateFade *= ( 1 - dist / undulateMaxDist ); + + // Also scale down wave magnitude if the camera is very very close. + undulateFade *= saturate( ( distance( IN.position.xyz, eyePos ) - 0.5 ) / 10.0 ); + + undulateAmt *= undulateFade; + + OUT.rippleTexCoord2.w = undulateAmt / ( waveData[0].y + waveData[1].y + waveData[2].y ); + OUT.rippleTexCoord2.w = saturate( OUT.rippleTexCoord2.w - 0.2 ) / 0.8; + + // Apply wave undulation to the vertex. + OUT.posPostWave = IN.position; + OUT.posPostWave.xyz += IN.normal.xyz * undulateAmt; + + // Convert to screen + OUT.posPostWave = mul( modelview, OUT.posPostWave ); + + // Setup the OUT position symantic variable + OUT.hpos = OUT.posPostWave; + //OUT.hpos.z = lerp( OUT.hpos.z, OUT.hpos.w, IN.horizonFactor.x ); + + // if ( IN.horizonFactor.x > 0 ) + // { + // float3 awayVec = normalize( OUT.objPos.xyz - eyePos ); + // OUT.objPos.xy += awayVec.xy * 1000.0; + // } + + // Save world space camera dist/depth of the outgoing pixel + OUT.rippleTexCoord2.z = OUT.hpos.z; + + // Convert to reflection texture space + OUT.posPostWave = mul( texGen, OUT.posPostWave ); + + float2 txPos = undulatePos; + if ( IN.horizonFactor.x ) + txPos = normalize( txPos ) * 50000.0; + + // set up tex coordinates for the 3 interacting normal maps + OUT.rippleTexCoord01.xy = txPos * rippleTexScale[0]; + OUT.rippleTexCoord01.xy += rippleDir[0] * elapsedTime * rippleSpeed.x; + + float2x2 texMat; + texMat[0][0] = rippleMat[0].x; + texMat[0][1] = rippleMat[0].y; + texMat[1][0] = rippleMat[0].z; + texMat[1][1] = rippleMat[0].w; + OUT.rippleTexCoord01.xy = mul( texMat, OUT.rippleTexCoord01.xy ); + + OUT.rippleTexCoord01.zw = txPos * rippleTexScale[1]; + OUT.rippleTexCoord01.zw += rippleDir[1] * elapsedTime * rippleSpeed.y; + + texMat[0][0] = rippleMat[1].x; + texMat[0][1] = rippleMat[1].y; + texMat[1][0] = rippleMat[1].z; + texMat[1][1] = rippleMat[1].w; + OUT.rippleTexCoord01.zw = mul( texMat, OUT.rippleTexCoord01.zw ); + + OUT.rippleTexCoord2.xy = txPos * rippleTexScale[2]; + OUT.rippleTexCoord2.xy += rippleDir[2] * elapsedTime * rippleSpeed.z; + + texMat[0][0] = rippleMat[2].x; + texMat[0][1] = rippleMat[2].y; + texMat[1][0] = rippleMat[2].z; + texMat[1][1] = rippleMat[2].w; + OUT.rippleTexCoord2.xy = mul( texMat, OUT.rippleTexCoord2.xy ); + + OUT.foamTexCoords.xy = txPos * foamTexScale.xy + foamDir.xy * foamSpeed.x * elapsedTime; + OUT.foamTexCoords.zw = txPos * foamTexScale.zw + foamDir.zw * foamSpeed.y * elapsedTime; + + + float3 binormal = float3( 1, 0, 0 ); + float3 tangent = float3( 0, 1, 0 ); + float3 normal; + for ( int i = 0; i < 3; i++ ) + { + binormal.z += undulateFade * waveDir[i].x * waveData[i].y * cos( waveDir[i].x * undulatePos.x + waveDir[i].y * undulatePos.y + elapsedTime * waveData[i].x ); + tangent.z += undulateFade * waveDir[i].y * waveData[i].y * cos( waveDir[i].x * undulatePos.x + waveDir[i].y * undulatePos.y + elapsedTime * waveData[i].x ); + } + + binormal = binormal; + tangent = tangent; + normal = cross( binormal, tangent ); + + float3x3 worldToTangent; + worldToTangent[0] = binormal; + worldToTangent[1] = tangent; + worldToTangent[2] = normal; + + OUT.tangentMat = worldToTangent; + + return OUT; +} + diff --git a/Templates/Empty/game/shaders/common/wavesP.hlsl b/Templates/Empty/game/shaders/common/wavesP.hlsl new file mode 100644 index 000000000..265842f1f --- /dev/null +++ b/Templates/Empty/game/shaders/common/wavesP.hlsl @@ -0,0 +1,86 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#define IN_HLSL +#include "shdrConsts.h" + +//----------------------------------------------------------------------------- +// Data +//----------------------------------------------------------------------------- +struct v2f +{ + float4 HPOS : POSITION; + float2 TEX0 : TEXCOORD0; + float4 tangentToCube0 : TEXCOORD1; + float4 tangentToCube1 : TEXCOORD2; + float4 tangentToCube2 : TEXCOORD3; + float4 lightVec : TEXCOORD4; + float3 pixPos : TEXCOORD5; + float3 eyePos : TEXCOORD6; +}; + + + +struct Fragout +{ + float4 col : COLOR0; +}; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Fragout main(v2f IN, + uniform sampler2D diffMap : register(S0), + uniform sampler2D bumpMap : register(S2), + uniform samplerCUBE cubeMap : register(S1), + uniform float4 specularColor : register(PC_MAT_SPECCOLOR), + uniform float specularPower : register(PC_MAT_SPECPOWER), + uniform float4 ambient : register(PC_AMBIENT_COLOR), + uniform float accumTime : register(PC_ACCUM_TIME) +) +{ + Fragout OUT; + + float2 texOffset; + float sinOffset1 = sin( accumTime * 1.5 + IN.TEX0.y * 6.28319 * 3.0 ) * 0.03; + float sinOffset2 = sin( accumTime * 3.0 + IN.TEX0.y * 6.28319 ) * 0.04; + + texOffset.x = IN.TEX0.x + sinOffset1 + sinOffset2; + texOffset.y = IN.TEX0.y + cos( accumTime * 3.0 + IN.TEX0.x * 6.28319 * 2.0 ) * 0.05; + + + float4 bumpNorm = tex2D( bumpMap, texOffset ) * 2.0 - 1.0; + float4 diffuse = tex2D( diffMap, texOffset ); + + OUT.col = diffuse * (saturate( dot( IN.lightVec, bumpNorm.xyz ) ) + ambient); + + float3 eyeVec = normalize(IN.eyePos - IN.pixPos); + float3 halfAng = normalize(eyeVec + IN.lightVec.xyz); + float specular = saturate( dot(bumpNorm, halfAng) ) * IN.lightVec.w; + specular = pow(abs(specular), specularPower); + OUT.col += specularColor * specular; + + + + return OUT; +} + diff --git a/Templates/Empty/game/shaders/common/wavesV.hlsl b/Templates/Empty/game/shaders/common/wavesV.hlsl new file mode 100644 index 000000000..6580daa5b --- /dev/null +++ b/Templates/Empty/game/shaders/common/wavesV.hlsl @@ -0,0 +1,91 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#define IN_HLSL +#include "shdrConsts.h" +#include "hlslStructs.h" + +//----------------------------------------------------------------------------- +// Constants +//----------------------------------------------------------------------------- + +struct Conn +{ + float4 HPOS : POSITION; + float2 TEX0 : TEXCOORD0; + float4 tangentToCube0 : TEXCOORD1; + float4 tangentToCube1 : TEXCOORD2; + float4 tangentToCube2 : TEXCOORD3; + float4 outLightVec : TEXCOORD4; + float3 pos : TEXCOORD5; + float3 outEyePos : TEXCOORD6; + +}; + + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Conn main( VertexIn_PNTTTB In, + uniform float4x4 modelview : register(VC_WORLD_PROJ), + uniform float3x3 cubeTrans : register(VC_CUBE_TRANS), + uniform float3 cubeEyePos : register(VC_CUBE_EYE_POS), + uniform float3 inLightVec : register(VC_LIGHT_DIR1), + uniform float3 eyePos : register(VC_EYE_POS) +) +{ + Conn Out; + + Out.HPOS = mul(modelview, In.pos); + Out.TEX0 = In.uv0; + + + float3x3 objToTangentSpace; + objToTangentSpace[0] = In.T; + objToTangentSpace[1] = In.B; + objToTangentSpace[2] = In.normal; + + + Out.tangentToCube0.xyz = mul( objToTangentSpace, cubeTrans[0].xyz ); + Out.tangentToCube1.xyz = mul( objToTangentSpace, cubeTrans[1].xyz ); + Out.tangentToCube2.xyz = mul( objToTangentSpace, cubeTrans[2].xyz ); + + float3 pos = mul( cubeTrans, In.pos ).xyz; + float3 eye = cubeEyePos - pos; + normalize( eye ); + + Out.tangentToCube0.w = eye.x; + Out.tangentToCube1.w = eye.y; + Out.tangentToCube2.w = eye.z; + + Out.outLightVec.xyz = -inLightVec; + Out.outLightVec.xyz = mul(objToTangentSpace, Out.outLightVec); + Out.pos = mul(objToTangentSpace, In.pos.xyz / 100.0); + Out.outEyePos.xyz = mul(objToTangentSpace, eyePos.xyz / 100.0); + Out.outLightVec.w = step( 0.0, dot( -inLightVec, In.normal ) ); + + + return Out; +} + + diff --git a/Templates/Empty/game/shaders/common/wind.hlsl b/Templates/Empty/game/shaders/common/wind.hlsl new file mode 100644 index 000000000..b3fee7721 --- /dev/null +++ b/Templates/Empty/game/shaders/common/wind.hlsl @@ -0,0 +1,101 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// +// A tip of the hat.... +// +// The following wind effects were derived from the GPU Gems +// 3 chapter "Vegetation Procedural Animation and Shading in Crysis" +// by Tiago Sousa of Crytek. +// + +float4 smoothCurve( float4 x ) +{ + return x * x * ( 3.0 - 2.0 * x ); +} + +float4 triangleWave( float4 x ) +{ + return abs( frac( x + 0.5 ) * 2.0 - 1.0 ); +} + +float4 smoothTriangleWave( float4 x ) +{ + return smoothCurve( triangleWave( x ) ); +} + +float3 windTrunkBending( float3 vPos, float2 vWind, float fBendFactor ) +{ + // Smooth the bending factor and increase + // the near by height limit. + fBendFactor += 1.0; + fBendFactor *= fBendFactor; + fBendFactor = fBendFactor * fBendFactor - fBendFactor; + + // Displace the vert. + float3 vNewPos = vPos; + vNewPos.xy += vWind * fBendFactor; + + // Limit the length which makes the bend more + // spherical and prevents stretching. + float fLength = length( vPos ); + vPos = normalize( vNewPos ) * fLength; + + return vPos; +} + +float3 windBranchBending( float3 vPos, + float3 vNormal, + + float fTime, + float fWindSpeed, + + float fBranchPhase, + float fBranchAmp, + float fBranchAtten, + + float fDetailPhase, + float fDetailAmp, + float fDetailFreq, + + float fEdgeAtten ) +{ + float fVertPhase = dot( vPos, fDetailPhase + fBranchPhase ); + + float2 vWavesIn = fTime + float2( fVertPhase, fBranchPhase ); + + float4 vWaves = ( frac( vWavesIn.xxyy * + float4( 1.975, 0.793, 0.375, 0.193 ) ) * + 2.0 - 1.0 ) * fWindSpeed * fDetailFreq; + + vWaves = smoothTriangleWave( vWaves ); + + float2 vWavesSum = vWaves.xz + vWaves.yw; + + // We want the branches to bend both up and down. + vWavesSum.y = 1 - ( vWavesSum.y * 2 ); + + vPos += vWavesSum.xxy * float3( fEdgeAtten * fDetailAmp * vNormal.xy, + fBranchAtten * fBranchAmp ); + + return vPos; +} diff --git a/Templates/Empty/game/shaders/procedural/.gitignore b/Templates/Empty/game/shaders/procedural/.gitignore new file mode 100644 index 000000000..1bc0e838a --- /dev/null +++ b/Templates/Empty/game/shaders/procedural/.gitignore @@ -0,0 +1 @@ +# Keep directory in git repo diff --git a/Templates/Empty/game/tools/base/canvas/baseCanvas.ed.cs b/Templates/Empty/game/tools/base/canvas/baseCanvas.ed.cs new file mode 100644 index 000000000..4689d0ae5 --- /dev/null +++ b/Templates/Empty/game/tools/base/canvas/baseCanvas.ed.cs @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- +function BaseEditorCanvas::onAdd( %this ) +{ + %this.createMenuBar(); + + %panel = new GuiPanel() { internalName = "DocumentContainer"; }; + %this.setContent( %panel ); + + %xOffset = 20; + %yOffset = 20; + + for( %i =0; %i<10; %i++ ) + { + %window = new GuiWindowCtrl() + { + extent = "200 100"; + position = %xOffset SPC %yOffset; + }; + %panel.add( %window ); + + %xOffset += 30; + %yOffset += 30; + + } +} + +function BaseEditorCanvas::onRemove( %this ) +{ + %this.destroyMenuBar(); +} + +function testBaseEditor() +{ + %baseEd = new GuiCanvas() { class="BaseEditorCanvas"; }; +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/base/main.cs b/Templates/Empty/game/tools/base/main.cs new file mode 100644 index 000000000..eab511eb6 --- /dev/null +++ b/Templates/Empty/game/tools/base/main.cs @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function initializeBase() +{ + echo(" % - Initializing Base Editor"); + + // Load Custom Editors + loadDirectory( expandFilename( "./canvas" ) ); + loadDirectory( expandFilename( "./menuBar" ) ); + loadDirectory( expandFilename( "./utils" ) ); +} + +function destroyBase() +{ +} diff --git a/Templates/Empty/game/tools/base/menuBar/baseMenu.ed.cs b/Templates/Empty/game/tools/base/menuBar/baseMenu.ed.cs new file mode 100644 index 000000000..f53606518 --- /dev/null +++ b/Templates/Empty/game/tools/base/menuBar/baseMenu.ed.cs @@ -0,0 +1,81 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// onAdd creates the base menu's and document controller +function BaseEditorCanvas::createMenuBar( %this ) +{ + if(isObject(%this.menuBar)) + return; + + // Menu bar + %this.menuBar = new MenuBar() + { + dynamicItemInsertPos = 3; + + // File Menu + new PopupMenu() + { + superClass = "MenuBuilder"; + class = "BaseEditorFileMenu"; + internalName = "FileMenu"; + + barTitle = "File"; + + item[0] = "New..." TAB "Ctrl N" TAB "[this].onNew();"; + item[1] = "Open..." TAB "Ctrl O" TAB "[this].onOpen();"; + item[2] = "-"; + item[3] = "Save" TAB "Ctrl S" TAB "[this].onSave();"; + item[4] = "Save As" TAB "Ctrl-Alt S" TAB "[this].onSaveAs();"; + item[5] = "Save All" TAB "Ctrl-Shift S" TAB "[this].onSaveAll();"; + item[6] = "-"; + item[7] = "Import..." TAB "Ctrl-Shift I" TAB "[this].onImport();"; + item[8] = "Export..." TAB "Ctrl-Shift E" TAB "[this].onExport();"; + item[9] = "-"; + item[10] = "Revert" TAB "Ctrl R" TAB "[this].onRevert();"; + item[11] = "-"; + item[12] = "Close" TAB "Ctrl W" TAB "[this].onClose();"; + }; + }; +} + +function BaseEditorCanvas::destroyMenuBar( %this ) +{ + if( isObject( %this.menuBar ) ) + %this.menuBar.delete(); +} + +function BaseEditorCanvas::onCreateMenu(%this) +{ + if( !isObject( %this.menuBar ) ) + %this.createMenuBar(); + + %this.menuBar.attachToCanvas( %this, 0 ); +} + +function BaseEditorCanvas::onDestroyMenu(%this) +{ + if( isObject( %this.menuBar ) ) + { + %this.destroyMenuBar(); + %this.menuBar.removeFromCanvas( %this ); + } +} diff --git a/Templates/Empty/game/tools/base/menuBar/fileMenu.ed.cs b/Templates/Empty/game/tools/base/menuBar/fileMenu.ed.cs new file mode 100644 index 000000000..1ab685e4a --- /dev/null +++ b/Templates/Empty/game/tools/base/menuBar/fileMenu.ed.cs @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// +// +// +function BaseEditorFileMenu::onNew( %this ) +{ +} +function BaseEditorFileMenu::onOpen( %this ) +{ +} +function BaseEditorFileMenu::onSave( %this ) +{ +} +function BaseEditorFileMenu::onSaveAs( %this ) +{ +} +function BaseEditorFileMenu::onSaveAll( %this ) +{ +} +function BaseEditorFileMenu::onRevert( %this ) +{ +} +function BaseEditorFileMenu::onClose( %this ) +{ +} +function BaseEditorFileMenu::onImport( %this ) +{ +} +function BaseEditorFileMenu::onExport( %this ) +{ +} diff --git a/Templates/Empty/game/tools/base/menuBar/menuBuilder.ed.cs b/Templates/Empty/game/tools/base/menuBar/menuBuilder.ed.cs new file mode 100644 index 000000000..0929c2464 --- /dev/null +++ b/Templates/Empty/game/tools/base/menuBar/menuBuilder.ed.cs @@ -0,0 +1,248 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Menu Builder Helper Class +//----------------------------------------------------------------------------- +/// @class MenuBuilder +/// @brief Create Dynamic Context and MenuBar Menus +/// +/// +/// Summary : The MenuBuilder script class exists merely as a helper for creating +/// popup menu's for use in torque editors. It is setup as a single +/// object with dynamic fields starting with item[0]..[n] that describe +/// how to create the menu in question. An example is below. +/// +/// isPopup : isPopup is a persistent field on PopupMenu console class which +/// when specified to true will allow you to perform .showPopup(x,y) +/// commands which allow popupmenu's to be used/reused as menubar menus +/// as well as context menus. +/// +/// barPosition : barPosition indicates which index on the menu bar (0 = leftmost) +/// to place this menu if it is attached. Use the attachToMenuBar() command +/// to attach a menu. +/// +/// barName : barName specifies the visible name of a menu item that is attached +/// to the global menubar. +/// +/// canvas : The GuiCanvas object the menu should be attached to. This defaults to +/// the global Canvas object if unspecified. +/// +/// Remarks : If you wish to use a menu as a context popup menu, isPopup must be +/// specified as true at the creation time of the menu. +/// +/// +/// @li @b item[n] (String) TAB (String) TAB (String) : A Menu Item Definition. +/// @code item[0] = "Open File..." TAB "Ctrl O" TAB "Something::OpenFile"; @endcode +/// +/// @li @b isPopup (bool) : If Specified the menu will be considered a popup menu and should be used via .showPopup() +/// @code isPopup = true; @endcode +/// +/// +/// Example : Creating a @b MenuBar Menu +/// @code +/// %%editMenu = new PopupMenu() +/// { +/// barPosition = 3; +/// barName = "View"; +/// superClass = "MenuBuilder"; +/// item[0] = "Undo" TAB "Ctrl Z" TAB "levelBuilderUndo(1);"; +/// item[1] = "Redo" TAB "Ctrl Y" TAB "levelBuilderRedo(1);"; +/// item[2] = "-"; +/// }; +/// +/// %%editMenu.attachToMenuBar( 1, "Edit" ); +/// +/// @endcode +/// +/// +/// Example : Creating a @b Context (Popup) Menu +/// @code +/// %%contextMenu = new PopupMenu() +/// { +/// superClass = MenuBuilder; +/// isPopup = true; +/// item[0] = "My Super Cool Item" TAB "Ctrl 2" TAB "echo(\"Clicked Super Cool Item\");"; +/// item[1] = "-"; +/// }; +/// +/// %%contextMenu.showPopup(); +/// @endcode +/// +/// +/// Example : Modifying a Menu +/// @code +/// %%editMenu = new PopupMenu() +/// { +/// item[0] = "Foo" TAB "Ctrl F" TAB "echo(\"clicked Foo\")"; +/// item[1] = "-"; +/// }; +/// %%editMenu.addItem( 2, "Bar" TAB "Ctrl B" TAB "echo(\"clicked Bar\")" ); +/// %%editMenu.removeItem( 0 ); +/// %%editMenu.addItem( 0, "Modified Foo" TAB "Ctrl F" TAB "echo(\"clicked modified Foo\")" ); +/// @endcode +/// +/// +/// @see PopupMenu +/// +//----------------------------------------------------------------------------- + +// Adds one item to the menu. +// if %item is skipped or "", we will use %item[#], which was set when the menu was created. +// if %item is provided, then we update %item[#]. +function MenuBuilder::addItem(%this, %pos, %item) +{ + if(%item $= "") + %item = %this.item[%pos]; + + if(%item !$= %this.item[%pos]) + %this.item[%pos] = %item; + + %name = getField(%item, 0); + %accel = getField(%item, 1); + %cmd = getField(%item, 2); + + // We replace the [this] token with our object ID + %cmd = strreplace( %cmd, "[this]", %this ); + %this.item[%pos] = setField( %item, 2, %cmd ); + + if(isObject(%accel)) + { + // If %accel is an object, we want to add a sub menu + %this.insertSubmenu(%pos, %name, %accel); + } + else + { + %this.insertItem(%pos, %name !$= "-" ? %name : "", %accel); + } +} + +function MenuBuilder::appendItem(%this, %item) +{ + %this.addItem(%this.getItemCount(), %item); +} + +function MenuBuilder::onAdd(%this) +{ + if(! isObject(%this.canvas)) + %this.canvas = Canvas; + + for(%i = 0;%this.item[%i] !$= "";%i++) + { + %this.addItem(%i); + } +} + +function MenuBuilder::onRemove(%this) +{ + %this.removeFromMenuBar(); +} + +////////////////////////////////////////////////////////////////////////// + +function MenuBuilder::onSelectItem(%this, %id, %text) +{ + %cmd = getField(%this.item[%id], 2); + if(%cmd !$= "") + { + eval( %cmd ); + return true; + } + return false; +} + +/// Sets a new name on an existing menu item. +function MenuBuilder::setItemName( %this, %id, %name ) +{ + %item = %this.item[%id]; + %accel = getField(%item, 1); + %this.setItem( %id, %name, %accel ); +} + +/// Sets a new command on an existing menu item. +function MenuBuilder::setItemCommand( %this, %id, %command ) +{ + %this.item[%id] = setField( %this.item[%id], 2, %command ); +} + +/// (SimID this) +/// Wraps the attachToMenuBar call so that it does not require knowledge of +/// barName or barIndex to be removed/attached. This makes the individual +/// MenuBuilder items very easy to add and remove dynamically from a bar. +/// +function MenuBuilder::attachToMenuBar( %this ) +{ + if( %this.barName $= "" ) + { + error("MenuBuilder::attachToMenuBar - Menu property 'barName' not specified."); + return false; + } + + if( %this.barPosition < 0 ) + { + error("MenuBuilder::attachToMenuBar - Menu " SPC %this.barName SPC "property 'barPosition' is invalid, must be zero or greater."); + return false; + } + + Parent::attachToMenuBar( %this, %this.canvas, %this.barPosition, %this.barName ); +} + +////////////////////////////////////////////////////////////////////////// + +// Callbacks from PopupMenu. These callbacks are now passed on to submenus +// in C++, which was previously not the case. Thus, no longer anything to +// do in these. I am keeping the callbacks in case they are needed later. + +function MenuBuilder::onAttachToMenuBar(%this, %canvas, %pos, %title) +{ +} + +function MenuBuilder::onRemoveFromMenuBar(%this, %canvas) +{ +} + +////////////////////////////////////////////////////////////////////////// + +/// Method called to setup default state for the menu. Expected to be overriden +/// on an individual menu basis. See the mission editor for an example. +function MenuBuilder::setupDefaultState(%this) +{ + for(%i = 0;%this.item[%i] !$= "";%i++) + { + %name = getField(%this.item[%i], 0); + %accel = getField(%this.item[%i], 1); + %cmd = getField(%this.item[%i], 2); + + // Pass on to sub menus + if(isObject(%accel)) + %accel.setupDefaultState(); + } +} + +/// Method called to easily enable or disable all items in a menu. +function MenuBuilder::enableAllItems(%this, %enable) +{ + for(%i = 0; %this.item[%i] !$= ""; %i++) + { + %this.enableItem(%i, %enable); + } +} diff --git a/Templates/Empty/game/tools/base/utils/inspector.ed.cs b/Templates/Empty/game/tools/base/utils/inspector.ed.cs new file mode 100644 index 000000000..9df8c7e98 --- /dev/null +++ b/Templates/Empty/game/tools/base/utils/inspector.ed.cs @@ -0,0 +1,289 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Functionality that allows all editor inspectors to share certain functionality. + + + +//--------------------------------------------------------------------------------------------- + +function EditorInspectorBase::onAdd( %this ) +{ + if( !isObject( EditorInspectorBaseDatablockFieldPopup ) ) + new PopupMenu( EditorInspectorBaseDatablockFieldPopup ) + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Edit Datablock" TAB "" TAB "DatablockEditorPlugin.openDatablock( %this.inspectorField.getData() );"; + Item[ 1 ] = "Jump to Definition in Torsion" TAB "" TAB "EditorOpenDeclarationInTorsion( %this.inspectorField.getData() );"; + item[ 2 ] = "Inspect Object" TAB "" TAB "inspectObject( %this.inspectorField.getData() );"; + item[ 3 ] = "-"; + item[ 4 ] = "Copy Value" TAB "" TAB "setClipboard( %this.inspectorField.getData() );"; + item[ 5 ] = "Paste Value" TAB "" TAB "%this.inspectorField.apply( getClipboard() );"; + item[ 6 ] = "Reset to Default" TAB "" TAB "%this.inspectorField.reset();"; + + inspectorField = -1; + }; + + if( !isObject( EditorInspectorBaseFieldPopup ) ) + new PopupMenu( EditorInspectorBaseFieldPopup ) + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Inspect Object" TAB "" TAB "inspectObject( %this.inspectorField.getData() );"; + Item[ 1 ] = "Jump to Definition in Torsion" TAB "" TAB "EditorOpenDeclarationInTorsion( %this.inspectorField.getData() );"; + item[ 2 ] = "-"; + item[ 3 ] = "Copy Value" TAB "" TAB "setClipboard( %this.inspectorField.getData() );"; + item[ 4 ] = "Paste Value" TAB "" TAB "%this.inspectorField.apply( getClipboard() );"; + item[ 5 ] = "Reset to Default" TAB "" TAB "%this.inspectorField.reset();"; + + inspectorField = -1; + }; + + if( !isObject( EditorInspectorBaseFileFieldPopup ) ) + new PopupMenu( EditorInspectorBaseFileFieldPopup ) + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Open File" TAB "" TAB "openFile( %this.filePath );"; + item[ 1 ] = "Open Folder" TAB "" TAB "openFolder( %this.folderPath );"; + item[ 2 ] = "-"; + item[ 3 ] = "Copy Value" TAB "" TAB "setClipboard( %this.inspectorField.getData() );"; + item[ 4 ] = "Paste Value" TAB "" TAB "%this.inspectorField.apply( getClipboard() );"; + item[ 5 ] = "Reset to Default" TAB "" TAB "%this.inspectorField.reset();"; + + inspectorField = -1; + folderPath = ""; + filePath = ""; + }; + + if( !isObject( EditorInspectorBaseShapeFieldPopup ) ) + new PopupMenu( EditorInspectorBaseShapeFieldPopup ) + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Edit Shape" TAB "" TAB "ShapeEditorPlugin.openShape( %this.inspectorField.getData() );"; + item[ 1 ] = "-"; + item[ 2 ] = "Open File" TAB "" TAB "openFile( %this.filePath );"; + item[ 3 ] = "Open Folder" TAB "" TAB "openFolder( %this.folderPath );"; + item[ 4 ] = "-"; + item[ 5 ] = "Copy Value" TAB "" TAB "setClipboard( %this.inspectorField.getData() );"; + item[ 6 ] = "Paste Value" TAB "" TAB "%this.inspectorField.apply( getClipboard() );"; + item[ 7 ] = "Reset to Default" TAB "" TAB "%this.inspectorField.reset();"; + + inspectorField = -1; + folderPath = ""; + filePath = ""; + }; + + if( !isObject( EditorInspectorBaseProfileFieldPopup ) ) + new PopupMenu( EditorInspectorBaseProfileFieldPopup ) + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Edit Profile" TAB "" TAB "if( !$InGuiEditor ) toggleGuiEditor( true ); GuiEditor.editProfile( %this.inspectorField.getData() );"; + item[ 1 ] = "Jump to Definition in Torsion" TAB "" TAB "EditorOpenDeclarationInTorsion( %this.inspectorField.getData() );"; + item[ 2 ] = "Inspect Object" TAB "" TAB "inspectObject( %this.inspectorField.getData() );"; + item[ 3 ] = "-"; + item[ 4 ] = "Copy Value" TAB "" TAB "setClipboard( %this.inspectorField.getData() );"; + item[ 5 ] = "Paste Value" TAB "" TAB "%this.inspectorField.apply( getClipboard() );"; + item[ 6 ] = "Reset to Default" TAB "" TAB "%this.inspectorField.reset();"; + + inspectorField = -1; + folderPath = ""; + filePath = ""; + }; +} + +//--------------------------------------------------------------------------------------------- + +function EditorInspectorBase::onFieldRightClick( %this, %field ) +{ + %obj = %this.getInspectObject(); + %fieldValue = %field.getData(); + + %inspectIndex = -1; + %openFileIndex = -1; + %openFolderIndex = -1; + + // Find out if this is a TypeFilename field referring to a shape file. + + %isShapeFilenameField = false; + if( %field.getInspectedFieldName() $= "shapeName" ) + { + %isShapeFilenameField = + %obj.isMemberOfClass( "PhysicsShape" ) || + %obj.isMemberOfClass( "TSStatic" ); + } + else if( %field.getInspectedFieldName() $= "shapeFile" ) + { + %isShapeFilenameField = + %obj.isMemberOfClass( "ShapeBaseData" ) || + %obj.isMemberOfClass( "ShapeBaseImageData" ) || + %obj.isMemberOfClass( "ForestItemData" ) || + %obj.isMemberOfClass( "WheeledVehicleTire" ) || + %obj.isMemberOfClass( "fxShapeReplicator" ) || + %obj.isMemberOfClass( "RenderShapeExample" ) || + %obj.isMemberOfClass( "DebrisData" ); + } + + // Select the popup. + + if( %isShapeFilenameField ) + { + %popup = EditorInspectorBaseShapeFieldPopup; + + %openFileIndex = 2; + %openFolderIndex = 3; + } + else if( EditorInspectorBase::isFileTypeField( %field ) ) + { + %popup = EditorInspectorBaseFileFieldPopup; + %openFileIndex = 0; + %openFolderIndex = 1; + } + else + { + switch$( %field.getClassName() ) + { + case "GuiInspectorCustomField": + if( %field.getInspectedFieldName() !$= "parentGroup" ) + return; + + case "GuiInspectorTypeGuiProfile": + + %popup = EditorInspectorBaseProfileFieldPopup; + + %popup.enableItem( 0, isObject( %fieldValue ) ); + %inspectIndex = 2; + %jumpToIndex = 1; + + case "GuiInspectorDatablockField" or + "GuiInspectorTypeSFXDescriptionName" or + "GuiInspectorTypeSFXEnvironmentName" or + "GuiInspectorTypeSFXTrackName" or + "GuiInspectorTypeSFXAmbienceName" or + "GuiInspectorTypeSFXSourceName": + + %popup = EditorInspectorBaseDatablockFieldPopup; + %popup.enableItem( 0, isObject( %fieldValue ) ); + %inspectIndex = 2; + %jumpToIndex = 1; + + default: + + %popup = EditorInspectorBaseFieldPopup; + %inspectIndex = 0; + %jumpToIndex = 1; + } + } + + if( %inspectIndex != -1 ) + { + %isObject = false; + if( EditorInspectorBase::isObjectTypeField( %field ) ) + %isObject = isObject( %fieldValue ); + + %popup.enableItem( %inspectIndex, %isObject ); + %popup.enableItem( %jumpToIndex, %isObject ); + } + + if( %openFileIndex != -1 || %openFolderIndex != -1 ) + { + %fullPath = EditorInspectorBase::getFullFilePath( %field ); + %popup.filePath = %fullPath; + %popup.folderPath = filePath( %fullPath ); + + if( %openFileIndex != -1 ) + %popup.enableItem( 0, isFile( %fullPath ) ); + + if( %openFolderIndex != -1 ) + %popup.enableItem( 1, isDirectory( %popup.folderPath ) ); + } + + %popup.inspectorField = %field; + %popup.showPopup( Canvas ); +} + +//--------------------------------------------------------------------------------------------- + +function EditorInspectorBase::isObjectTypeField( %field ) +{ + // Inspector field types that refer to objects. + + switch$( %field.getClassName() ) + { + case "GuiInspectorDatablockField" or + "GuiInspectorTypeSFXDescriptionName" or + "GuiInspectorTypeSFXEnvironmentName" or + "GuiInspectorTypeSFXTrackName" or + "GuiInspectorTypeSFXAmbienceName" or + "GuiInspectorTypeSFXSourceName" or + "GuiInspectorTypeGuiProfile": + return true; + } + + // Other console types that refer to objects. + + switch$( %field.getInspectedFieldType() ) + { + case "TypeSimObject" or + "TypeSimObjectName" or + "TypeMaterialName" or + "TypeCubemapName" or + "TypeGuiProfile": + return true; + } + + return false; +} + +//--------------------------------------------------------------------------------------------- + +function EditorInspectorBase::isFileTypeField( %field ) +{ + return %field.isMemberOfClass( "GuiInspectorTypeFileName" ); +} + +//--------------------------------------------------------------------------------------------- + +function EditorInspectorBase::getFullFilePath( %field ) +{ + %fileName = %field.getData(); + %inspector = %field.getInspector(); + %object = %inspector.getInspectObject(); + + if( %object.isMemberOfClass( "Material" ) ) + { + // Image filenames in materials are relative to the material's file. + + %objectPath = filePath( makeFullPath( %object.getFilename(), getMainDotCsDir() ) ); + return makeFullPath( %fileName, %objectPath ); + } + else + return makeFullPath( %fileName, getMainDotCsDir() ); +} diff --git a/Templates/Empty/game/tools/base/utils/objectNameValidation.ed.cs b/Templates/Empty/game/tools/base/utils/objectNameValidation.ed.cs new file mode 100644 index 000000000..ba74d0d36 --- /dev/null +++ b/Templates/Empty/game/tools/base/utils/objectNameValidation.ed.cs @@ -0,0 +1,59 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +function Editor::validateObjectName( %name, %mustHaveName ) +{ + if( %mustHaveName && %name $= "" ) + { + MessageBoxOK( "Missing Object Name", "No name given for object. Please enter a valid object name." ); + return false; + } + if( !isValidObjectName( %name ) ) + { + MessageBoxOK( "Invalid Object Name", "'" @ %name @ "' is not a valid object name." NL + "" NL + "Please choose a name that begins with a letter or underscore and is otherwise comprised " @ + "exclusively of letters, digits, and/or underscores." + ); + return false; + } + if( isObject( %name ) ) + { + %filename = %name.getFilename(); + if ( %filename $= "" ) + %filename = "an unknown file"; + + MessageBoxOK( "Invalid Object Name", "Object names must be unique, and there is an " @ + "existing " @ %name.getClassName() @ " object with the name '" @ %name @ "' (defined " @ + "in " @ %filename @ "). Please choose another name." ); + return false; + } + if( isClass( %name ) ) + { + MessageBoxOK( "Invalid Object Name", "'" @ %name @ "' is the name of an existing TorqueScript " @ + "class. Please choose another name." ); + return false; + } + + return true; +} diff --git a/Templates/Empty/game/tools/base/utils/swatchButtons.ed.cs b/Templates/Empty/game/tools/base/utils/swatchButtons.ed.cs new file mode 100644 index 000000000..528bf5e1e --- /dev/null +++ b/Templates/Empty/game/tools/base/utils/swatchButtons.ed.cs @@ -0,0 +1,99 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Common functionality for GuiSwatchButtonCtrls. +// +// Note that for the mouse-event related functionality, "useMouseEvents" must be set +// to true. + + +//--------------------------------------------------------------------------------------------- + +function GuiSwatchButtonCtrl::onMouseDragged( %this ) +{ + %payload = new GuiSwatchButtonCtrl(); + %payload.assignFieldsFrom( %this ); + %payload.position = "0 0 "; + %payload.dragSourceControl = %this; + + %xOffset = getWord( %payload.extent, 0 ) / 2; + %yOffset = getWord( %payload.extent, 1 ) / 2; + %cursorpos = Canvas.getCursorPos(); + %xPos = getWord( %cursorpos, 0 ) - %xOffset; + %yPos = getWord( %cursorpos, 1 ) - %yOffset; + + // Create the drag control. + + %ctrl = new GuiDragAndDropControl() + { + canSaveDynamicFields = "0"; + Profile = "GuiSolidDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = %xPos SPC %yPos; + extent = %payload.extent; + MinExtent = "4 4"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + deleteOnMouseUp = true; + class = "GuiDragAndDropControlType_ColorSwatch"; + }; + + %ctrl.add( %payload ); + + // Start drag. + + Canvas.getContent().add( %ctrl ); + %ctrl.startDragging( %xOffset, %yOffset ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiSwatchButtonCtrl::onControlDropped( %this, %payload, %position ) +{ + if( !%payload.parentGroup.isInNamespaceHierarchy( "GuiDragAndDropControlType_ColorSwatch" ) ) + return; + + // If dropped on same button whence we came from, + // do nothing. + + if( %payload.dragSourceControl == %this ) + return; + + // If a swatch button control is dropped onto this control, + // copy it's color. + + if( %payload.isMemberOfClass( "GuiSwatchButtonCtrl" ) ) + { + // If the swatch button is part of a color-type inspector field, + // remember the inspector field so we can later set the color + // through it. + + if( %this.parentGroup.isMemberOfClass( "GuiInspectorTypeColorI" ) ) + %this.parentGroup.apply( ColorFloatToInt( %payload.color ) ); + else if( %this.parentGroup.isMemberOfClass( "GuiInspectorTypeColorF" ) ) + %this.parentGroup.apply( %payload.color ); + else + %this.setColor( %payload.color ); + } +} diff --git a/Templates/Empty/game/tools/base/utils/treeViewFilterCtrls.ed.cs b/Templates/Empty/game/tools/base/utils/treeViewFilterCtrls.ed.cs new file mode 100644 index 000000000..a3e055bc6 --- /dev/null +++ b/Templates/Empty/game/tools/base/utils/treeViewFilterCtrls.ed.cs @@ -0,0 +1,74 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Common functions for filter text and clear button controls on tree views. +// The GuiTextEditCtrl having the filter text must have "treeView" dynamic field +// that has the ID of the associated GuiTreeViewCtrl. +// The button ctrl used to clear the text field must have a "textCtrl" dynamic field +// that has the ID of the associated filter GuiTextEditCtrl. + + +//--------------------------------------------------------------------------------------------- + +function GuiTreeViewFilterText::onWake( %this ) +{ + %filter = %this.treeView.getFilterText(); + if( %filter $= "" ) + %this.setText( "\c2Filter..." ); + else + %this.setText( %filter ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiTreeViewFilterText::onGainFirstResponder( %this ) +{ + %this.selectAllText(); +} + +//--------------------------------------------------------------------------------------------- + +// When Enter is pressed in the filter text control, pass along the text of the control +// as the treeview's filter. +function GuiTreeViewFilterText::onReturn( %this ) +{ + %text = %this.getText(); + if( %text $= "" ) + %this.reset(); + else + %this.treeView.setFilterText( %text ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiTreeViewFilterText::reset( %this ) +{ + %this.setText( "\c2Filter..." ); + %this.treeView.clearFilterText(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiTreeViewFilterClearButton::onClick( %this ) +{ + %this.textCtrl.reset(); +} diff --git a/Templates/Empty/game/tools/base/utils/undoActions.ed.cs b/Templates/Empty/game/tools/base/utils/undoActions.ed.cs new file mode 100644 index 000000000..3de6c2f1b --- /dev/null +++ b/Templates/Empty/game/tools/base/utils/undoActions.ed.cs @@ -0,0 +1,93 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Undo actions that are useful in multiple editors. + + +//============================================================================================= +// Undo reparenting. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function UndoActionReparentObjects::create( %treeView ) +{ + pushInstantGroup(); + %action = new UndoScriptAction() + { + class = "UndoActionReparentObjects"; + numObjects = 0; + treeView = %treeView; + }; + popInstantGroup(); + + return %action; +} + +//--------------------------------------------------------------------------------------------- + +function UndoActionReparentObjects::add( %this, %object, %oldParent, %newParent ) +{ + %index = %this.numObjects; + + %this.objects[ %index ] = %object; + %this.oldParents[ %index ] = %oldParent; + %this.newParents[ %index ] = %newParent; + + %this.numObjects = %this.numObjects + 1; +} + +//--------------------------------------------------------------------------------------------- + +function UndoActionReparentObjects::undo( %this ) +{ + %numObjects = %this.numObjects; + for( %i = 0; %i < %numObjects; %i ++ ) + { + %obj = %this.objects[ %i ]; + %group = %this.oldParents[ %i ]; + + if( isObject( %obj ) && isObject( %group ) ) + %obj.parentGroup = %group; + } + + if( isObject( %this.treeView ) ) + %this.treeView.update(); +} + +//--------------------------------------------------------------------------------------------- + +function UndoActionReparentObjects::redo( %this ) +{ + %numObjects = %this.numObjects; + for( %i = 0; %i < %numObjects; %i ++ ) + { + %obj = %this.objects[ %i ]; + %group = %this.newParents[ %i ]; + + if( isObject( %obj ) && isObject( %group ) ) + %obj.parentGroup = %group; + } + + if( isObject( %this.treeView ) ) + %this.treeView.update(); +} diff --git a/Templates/Empty/game/tools/classIcons/CreatorTree.png b/Templates/Empty/game/tools/classIcons/CreatorTree.png new file mode 100644 index 000000000..f916c304e Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/CreatorTree.png differ diff --git a/Templates/Empty/game/tools/classIcons/ForestBrushElement.png b/Templates/Empty/game/tools/classIcons/ForestBrushElement.png new file mode 100644 index 000000000..0fc969d30 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/ForestBrushElement.png differ diff --git a/Templates/Empty/game/tools/classIcons/GameTSCtrl.png b/Templates/Empty/game/tools/classIcons/GameTSCtrl.png new file mode 100644 index 000000000..f1801ffe0 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GameTSCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiAutoScrollCtrl.png b/Templates/Empty/game/tools/classIcons/GuiAutoScrollCtrl.png new file mode 100644 index 000000000..b8219f575 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiAutoScrollCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiBitmapBorderCtrl.png b/Templates/Empty/game/tools/classIcons/GuiBitmapBorderCtrl.png new file mode 100644 index 000000000..b6d8e52ac Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiBitmapBorderCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiBitmapButtonCtrl.png b/Templates/Empty/game/tools/classIcons/GuiBitmapButtonCtrl.png new file mode 100644 index 000000000..76cb12598 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiBitmapButtonCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiBitmapButtonTextCtrl.png b/Templates/Empty/game/tools/classIcons/GuiBitmapButtonTextCtrl.png new file mode 100644 index 000000000..eeee4adcf Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiBitmapButtonTextCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiBitmapCtrl.png b/Templates/Empty/game/tools/classIcons/GuiBitmapCtrl.png new file mode 100644 index 000000000..6f511189f Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiBitmapCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiBorderButtonCtrl.png b/Templates/Empty/game/tools/classIcons/GuiBorderButtonCtrl.png new file mode 100644 index 000000000..25044777f Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiBorderButtonCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiButtonCtrl.png b/Templates/Empty/game/tools/classIcons/GuiButtonCtrl.png new file mode 100644 index 000000000..cc15e745f Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiButtonCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiCheckBoxCtrl.png b/Templates/Empty/game/tools/classIcons/GuiCheckBoxCtrl.png new file mode 100644 index 000000000..8e608ba2d Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiCheckBoxCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiColorPickerCtrl.png b/Templates/Empty/game/tools/classIcons/GuiColorPickerCtrl.png new file mode 100644 index 000000000..cd9c6ca32 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiColorPickerCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiContainer.png b/Templates/Empty/game/tools/classIcons/GuiContainer.png new file mode 100644 index 000000000..e4838a4b4 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiContainer.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiControlArrayControl.png b/Templates/Empty/game/tools/classIcons/GuiControlArrayControl.png new file mode 100644 index 000000000..f7340fae4 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiControlArrayControl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiCrossHairHud.png b/Templates/Empty/game/tools/classIcons/GuiCrossHairHud.png new file mode 100644 index 000000000..65b06404a Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiCrossHairHud.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiDecoyCtrl.png b/Templates/Empty/game/tools/classIcons/GuiDecoyCtrl.png new file mode 100644 index 000000000..a092c1ee2 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiDecoyCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiDragAndDropControl.png b/Templates/Empty/game/tools/classIcons/GuiDragAndDropControl.png new file mode 100644 index 000000000..d55dd70f7 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiDragAndDropControl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiDynamicCtrlArrayControl.png b/Templates/Empty/game/tools/classIcons/GuiDynamicCtrlArrayControl.png new file mode 100644 index 000000000..a356634e8 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiDynamicCtrlArrayControl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiFadeInBitmapCtrl.png b/Templates/Empty/game/tools/classIcons/GuiFadeInBitmapCtrl.png new file mode 100644 index 000000000..60463c219 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiFadeInBitmapCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiFileTreeCtrl.png b/Templates/Empty/game/tools/classIcons/GuiFileTreeCtrl.png new file mode 100644 index 000000000..f916c304e Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiFileTreeCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiFilterCtrl.png b/Templates/Empty/game/tools/classIcons/GuiFilterCtrl.png new file mode 100644 index 000000000..b0ddc8a78 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiFilterCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiFormCtrl.png b/Templates/Empty/game/tools/classIcons/GuiFormCtrl.png new file mode 100644 index 000000000..6717fa7ac Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiFormCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiFrameSetCtrl.png b/Templates/Empty/game/tools/classIcons/GuiFrameSetCtrl.png new file mode 100644 index 000000000..633934138 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiFrameSetCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiGradientSwatchCtrl.png b/Templates/Empty/game/tools/classIcons/GuiGradientSwatchCtrl.png new file mode 100644 index 000000000..0b7d7c58b Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiGradientSwatchCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiGraphCtrl.png b/Templates/Empty/game/tools/classIcons/GuiGraphCtrl.png new file mode 100644 index 000000000..18dfdd8d5 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiGraphCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiHealthBarHud.png b/Templates/Empty/game/tools/classIcons/GuiHealthBarHud.png new file mode 100644 index 000000000..f661a431a Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiHealthBarHud.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiIconButtonCtrl.png b/Templates/Empty/game/tools/classIcons/GuiIconButtonCtrl.png new file mode 100644 index 000000000..752de83a4 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiIconButtonCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiListBoxCtrl.png b/Templates/Empty/game/tools/classIcons/GuiListBoxCtrl.png new file mode 100644 index 000000000..d6e5e064d Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiListBoxCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiMLTextCtrl.png b/Templates/Empty/game/tools/classIcons/GuiMLTextCtrl.png new file mode 100644 index 000000000..acb4ea577 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiMLTextCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiMLTextEditCtrl.png b/Templates/Empty/game/tools/classIcons/GuiMLTextEditCtrl.png new file mode 100644 index 000000000..0e1dea166 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiMLTextEditCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiMenuBar.png b/Templates/Empty/game/tools/classIcons/GuiMenuBar.png new file mode 100644 index 000000000..ef40a9834 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiMenuBar.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiObjectView.png b/Templates/Empty/game/tools/classIcons/GuiObjectView.png new file mode 100644 index 000000000..e6b832c9a Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiObjectView.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiPanel.png b/Templates/Empty/game/tools/classIcons/GuiPanel.png new file mode 100644 index 000000000..ea571796b Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiPanel.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiPopUpMenuCtrl.png b/Templates/Empty/game/tools/classIcons/GuiPopUpMenuCtrl.png new file mode 100644 index 000000000..c5ef727a2 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiPopUpMenuCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiPopUpMenuCtrlEx.png b/Templates/Empty/game/tools/classIcons/GuiPopUpMenuCtrlEx.png new file mode 100644 index 000000000..18a4aaf59 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiPopUpMenuCtrlEx.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiProgressBitmapCtrl.png b/Templates/Empty/game/tools/classIcons/GuiProgressBitmapCtrl.png new file mode 100644 index 000000000..a6be7a2ed Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiProgressBitmapCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiProgressCtrl.png b/Templates/Empty/game/tools/classIcons/GuiProgressCtrl.png new file mode 100644 index 000000000..5c07e2345 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiProgressCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiRadioCtrl.png b/Templates/Empty/game/tools/classIcons/GuiRadioCtrl.png new file mode 100644 index 000000000..80c839747 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiRadioCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiRectHandles.png b/Templates/Empty/game/tools/classIcons/GuiRectHandles.png new file mode 100644 index 000000000..11e5a06a9 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiRectHandles.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiRolloutCtrl.png b/Templates/Empty/game/tools/classIcons/GuiRolloutCtrl.png new file mode 100644 index 000000000..ed922abdb Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiRolloutCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiScrollCtrl.png b/Templates/Empty/game/tools/classIcons/GuiScrollCtrl.png new file mode 100644 index 000000000..64e9fe1bc Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiScrollCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiSplitContainer.png b/Templates/Empty/game/tools/classIcons/GuiSplitContainer.png new file mode 100644 index 000000000..752127aaf Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiSplitContainer.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiStackControl.png b/Templates/Empty/game/tools/classIcons/GuiStackControl.png new file mode 100644 index 000000000..b8d34ffa3 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiStackControl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiSwatchButtonCtrl.png b/Templates/Empty/game/tools/classIcons/GuiSwatchButtonCtrl.png new file mode 100644 index 000000000..0b7d7c58b Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiSwatchButtonCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiTabBookCtrl.png b/Templates/Empty/game/tools/classIcons/GuiTabBookCtrl.png new file mode 100644 index 000000000..41e09bd65 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiTabBookCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiTabPageCtrl.png b/Templates/Empty/game/tools/classIcons/GuiTabPageCtrl.png new file mode 100644 index 000000000..ac58cc276 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiTabPageCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiTextCtrl.png b/Templates/Empty/game/tools/classIcons/GuiTextCtrl.png new file mode 100644 index 000000000..b185f092d Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiTextCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiTextEditCtrl.png b/Templates/Empty/game/tools/classIcons/GuiTextEditCtrl.png new file mode 100644 index 000000000..114a30e5f Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiTextEditCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiTextEditSliderCtrl.png b/Templates/Empty/game/tools/classIcons/GuiTextEditSliderCtrl.png new file mode 100644 index 000000000..27844cf39 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiTextEditSliderCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiTextListCtrl.png b/Templates/Empty/game/tools/classIcons/GuiTextListCtrl.png new file mode 100644 index 000000000..5369870c0 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiTextListCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiTheoraCtrl.png b/Templates/Empty/game/tools/classIcons/GuiTheoraCtrl.png new file mode 100644 index 000000000..2cf955565 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiTheoraCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiTreeViewCtrl.png b/Templates/Empty/game/tools/classIcons/GuiTreeViewCtrl.png new file mode 100644 index 000000000..f916c304e Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiTreeViewCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiWindowCollapseCtrl.png b/Templates/Empty/game/tools/classIcons/GuiWindowCollapseCtrl.png new file mode 100644 index 000000000..09e99cdd1 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiWindowCollapseCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/GuiWindowCtrl.png b/Templates/Empty/game/tools/classIcons/GuiWindowCtrl.png new file mode 100644 index 000000000..09e99cdd1 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/GuiWindowCtrl.png differ diff --git a/Templates/Empty/game/tools/classIcons/PxCloth.png b/Templates/Empty/game/tools/classIcons/PxCloth.png new file mode 100644 index 000000000..5fa4a9ba4 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/PxCloth.png differ diff --git a/Templates/Empty/game/tools/classIcons/SimDataBlock.png b/Templates/Empty/game/tools/classIcons/SimDataBlock.png new file mode 100644 index 000000000..63655e1cb Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/SimDataBlock.png differ diff --git a/Templates/Empty/game/tools/classIcons/TSForestItemData.png b/Templates/Empty/game/tools/classIcons/TSForestItemData.png new file mode 100644 index 000000000..183c7e532 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/TSForestItemData.png differ diff --git a/Templates/Empty/game/tools/classIcons/basicClouds.png b/Templates/Empty/game/tools/classIcons/basicClouds.png new file mode 100644 index 000000000..f5c863f29 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/basicClouds.png differ diff --git a/Templates/Empty/game/tools/classIcons/camera.png b/Templates/Empty/game/tools/classIcons/camera.png new file mode 100644 index 000000000..0722c8515 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/camera.png differ diff --git a/Templates/Empty/game/tools/classIcons/cameraBookmark.png b/Templates/Empty/game/tools/classIcons/cameraBookmark.png new file mode 100644 index 000000000..0722c8515 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/cameraBookmark.png differ diff --git a/Templates/Empty/game/tools/classIcons/cameraSpawn.png b/Templates/Empty/game/tools/classIcons/cameraSpawn.png new file mode 100644 index 000000000..8a060a651 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/cameraSpawn.png differ diff --git a/Templates/Empty/game/tools/classIcons/cloudLayer.png b/Templates/Empty/game/tools/classIcons/cloudLayer.png new file mode 100644 index 000000000..0cde23bc0 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/cloudLayer.png differ diff --git a/Templates/Empty/game/tools/classIcons/convexShape.png b/Templates/Empty/game/tools/classIcons/convexShape.png new file mode 100644 index 000000000..bc9c749d4 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/convexShape.png differ diff --git a/Templates/Empty/game/tools/classIcons/decal.png b/Templates/Empty/game/tools/classIcons/decal.png new file mode 100644 index 000000000..ba792f986 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/decal.png differ diff --git a/Templates/Empty/game/tools/classIcons/decalNode.png b/Templates/Empty/game/tools/classIcons/decalNode.png new file mode 100644 index 000000000..f6684f185 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/decalNode.png differ diff --git a/Templates/Empty/game/tools/classIcons/decalRoad.png b/Templates/Empty/game/tools/classIcons/decalRoad.png new file mode 100644 index 000000000..cbe8aab12 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/decalRoad.png differ diff --git a/Templates/Empty/game/tools/classIcons/default.png b/Templates/Empty/game/tools/classIcons/default.png new file mode 100644 index 000000000..0519b5220 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/default.png differ diff --git a/Templates/Empty/game/tools/classIcons/forest.png b/Templates/Empty/game/tools/classIcons/forest.png new file mode 100644 index 000000000..014caf957 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/forest.png differ diff --git a/Templates/Empty/game/tools/classIcons/forestBrush.png b/Templates/Empty/game/tools/classIcons/forestBrush.png new file mode 100644 index 000000000..af9ab2520 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/forestBrush.png differ diff --git a/Templates/Empty/game/tools/classIcons/fxFoliageReplicator.png b/Templates/Empty/game/tools/classIcons/fxFoliageReplicator.png new file mode 100644 index 000000000..4dac38fc0 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/fxFoliageReplicator.png differ diff --git a/Templates/Empty/game/tools/classIcons/fxshapereplicator.png b/Templates/Empty/game/tools/classIcons/fxshapereplicator.png new file mode 100644 index 000000000..94d1c4b30 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/fxshapereplicator.png differ diff --git a/Templates/Empty/game/tools/classIcons/groundCover.png b/Templates/Empty/game/tools/classIcons/groundCover.png new file mode 100644 index 000000000..6d3ebecd3 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/groundCover.png differ diff --git a/Templates/Empty/game/tools/classIcons/groundPlane.png b/Templates/Empty/game/tools/classIcons/groundPlane.png new file mode 100644 index 000000000..96815a58f Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/groundPlane.png differ diff --git a/Templates/Empty/game/tools/classIcons/guiControl.png b/Templates/Empty/game/tools/classIcons/guiControl.png new file mode 100644 index 000000000..633934138 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/guiControl.png differ diff --git a/Templates/Empty/game/tools/classIcons/interiorInstance.png b/Templates/Empty/game/tools/classIcons/interiorInstance.png new file mode 100644 index 000000000..7c699f858 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/interiorInstance.png differ diff --git a/Templates/Empty/game/tools/classIcons/item.png b/Templates/Empty/game/tools/classIcons/item.png new file mode 100644 index 000000000..94c6222dc Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/item.png differ diff --git a/Templates/Empty/game/tools/classIcons/levelInfo.png b/Templates/Empty/game/tools/classIcons/levelInfo.png new file mode 100644 index 000000000..d7d757686 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/levelInfo.png differ diff --git a/Templates/Empty/game/tools/classIcons/lightning.png b/Templates/Empty/game/tools/classIcons/lightning.png new file mode 100644 index 000000000..baedee38d Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/lightning.png differ diff --git a/Templates/Empty/game/tools/classIcons/marker.png b/Templates/Empty/game/tools/classIcons/marker.png new file mode 100644 index 000000000..a93b82252 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/marker.png differ diff --git a/Templates/Empty/game/tools/classIcons/meshRoad.png b/Templates/Empty/game/tools/classIcons/meshRoad.png new file mode 100644 index 000000000..8f33e23f4 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/meshRoad.png differ diff --git a/Templates/Empty/game/tools/classIcons/missionArea.png b/Templates/Empty/game/tools/classIcons/missionArea.png new file mode 100644 index 000000000..91bb1e219 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/missionArea.png differ diff --git a/Templates/Empty/game/tools/classIcons/particleEffecterObject.png b/Templates/Empty/game/tools/classIcons/particleEffecterObject.png new file mode 100644 index 000000000..255a5a8a8 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/particleEffecterObject.png differ diff --git a/Templates/Empty/game/tools/classIcons/particleEmitter.png b/Templates/Empty/game/tools/classIcons/particleEmitter.png new file mode 100644 index 000000000..e5489fc70 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/particleEmitter.png differ diff --git a/Templates/Empty/game/tools/classIcons/particleEmitterNode.png b/Templates/Empty/game/tools/classIcons/particleEmitterNode.png new file mode 100644 index 000000000..351e4bd72 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/particleEmitterNode.png differ diff --git a/Templates/Empty/game/tools/classIcons/particleEmitterObject.png b/Templates/Empty/game/tools/classIcons/particleEmitterObject.png new file mode 100644 index 000000000..e5489fc70 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/particleEmitterObject.png differ diff --git a/Templates/Empty/game/tools/classIcons/particleSimulation.png b/Templates/Empty/game/tools/classIcons/particleSimulation.png new file mode 100644 index 000000000..95bcfef6b Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/particleSimulation.png differ diff --git a/Templates/Empty/game/tools/classIcons/path.png b/Templates/Empty/game/tools/classIcons/path.png new file mode 100644 index 000000000..945102557 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/path.png differ diff --git a/Templates/Empty/game/tools/classIcons/pathMarker.png b/Templates/Empty/game/tools/classIcons/pathMarker.png new file mode 100644 index 000000000..a93b82252 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/pathMarker.png differ diff --git a/Templates/Empty/game/tools/classIcons/physicalZone.png b/Templates/Empty/game/tools/classIcons/physicalZone.png new file mode 100644 index 000000000..023cb7dd0 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/physicalZone.png differ diff --git a/Templates/Empty/game/tools/classIcons/player.png b/Templates/Empty/game/tools/classIcons/player.png new file mode 100644 index 000000000..480dfce70 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/player.png differ diff --git a/Templates/Empty/game/tools/classIcons/pointLight.png b/Templates/Empty/game/tools/classIcons/pointLight.png new file mode 100644 index 000000000..bd47c6187 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/pointLight.png differ diff --git a/Templates/Empty/game/tools/classIcons/portal.png b/Templates/Empty/game/tools/classIcons/portal.png new file mode 100644 index 000000000..0dec3b0a5 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/portal.png differ diff --git a/Templates/Empty/game/tools/classIcons/precipitation.png b/Templates/Empty/game/tools/classIcons/precipitation.png new file mode 100644 index 000000000..8e2cc784c Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/precipitation.png differ diff --git a/Templates/Empty/game/tools/classIcons/prefab.png b/Templates/Empty/game/tools/classIcons/prefab.png new file mode 100644 index 000000000..6786bda75 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/prefab.png differ diff --git a/Templates/Empty/game/tools/classIcons/river.png b/Templates/Empty/game/tools/classIcons/river.png new file mode 100644 index 000000000..87d6d0d2d Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/river.png differ diff --git a/Templates/Empty/game/tools/classIcons/scatterSky.png b/Templates/Empty/game/tools/classIcons/scatterSky.png new file mode 100644 index 000000000..52257b0bc Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/scatterSky.png differ diff --git a/Templates/Empty/game/tools/classIcons/sceneobject.png b/Templates/Empty/game/tools/classIcons/sceneobject.png new file mode 100644 index 000000000..59079e3d7 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/sceneobject.png differ diff --git a/Templates/Empty/game/tools/classIcons/sfxEmitter.png b/Templates/Empty/game/tools/classIcons/sfxEmitter.png new file mode 100644 index 000000000..92f165e99 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/sfxEmitter.png differ diff --git a/Templates/Empty/game/tools/classIcons/simObject.png b/Templates/Empty/game/tools/classIcons/simObject.png new file mode 100644 index 000000000..5c143982f Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/simObject.png differ diff --git a/Templates/Empty/game/tools/classIcons/simSet.png b/Templates/Empty/game/tools/classIcons/simSet.png new file mode 100644 index 000000000..571a904d0 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/simSet.png differ diff --git a/Templates/Empty/game/tools/classIcons/skyBox.png b/Templates/Empty/game/tools/classIcons/skyBox.png new file mode 100644 index 000000000..cfe50f6c4 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/skyBox.png differ diff --git a/Templates/Empty/game/tools/classIcons/spawnsphere.png b/Templates/Empty/game/tools/classIcons/spawnsphere.png new file mode 100644 index 000000000..df46d9df5 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/spawnsphere.png differ diff --git a/Templates/Empty/game/tools/classIcons/spotLight.png b/Templates/Empty/game/tools/classIcons/spotLight.png new file mode 100644 index 000000000..c63369559 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/spotLight.png differ diff --git a/Templates/Empty/game/tools/classIcons/sun.png b/Templates/Empty/game/tools/classIcons/sun.png new file mode 100644 index 000000000..097526cac Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/sun.png differ diff --git a/Templates/Empty/game/tools/classIcons/terrainBlock.png b/Templates/Empty/game/tools/classIcons/terrainBlock.png new file mode 100644 index 000000000..db58bb863 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/terrainBlock.png differ diff --git a/Templates/Empty/game/tools/classIcons/timeofday.png b/Templates/Empty/game/tools/classIcons/timeofday.png new file mode 100644 index 000000000..e210a22da Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/timeofday.png differ diff --git a/Templates/Empty/game/tools/classIcons/trigger.png b/Templates/Empty/game/tools/classIcons/trigger.png new file mode 100644 index 000000000..c9f12040b Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/trigger.png differ diff --git a/Templates/Empty/game/tools/classIcons/tsStatic.png b/Templates/Empty/game/tools/classIcons/tsStatic.png new file mode 100644 index 000000000..e0b7e7f94 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/tsStatic.png differ diff --git a/Templates/Empty/game/tools/classIcons/volumeLight.png b/Templates/Empty/game/tools/classIcons/volumeLight.png new file mode 100644 index 000000000..114a7f2ab Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/volumeLight.png differ diff --git a/Templates/Empty/game/tools/classIcons/waterBlock.png b/Templates/Empty/game/tools/classIcons/waterBlock.png new file mode 100644 index 000000000..6b396fff5 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/waterBlock.png differ diff --git a/Templates/Empty/game/tools/classIcons/waterPlane.png b/Templates/Empty/game/tools/classIcons/waterPlane.png new file mode 100644 index 000000000..a2d28f854 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/waterPlane.png differ diff --git a/Templates/Empty/game/tools/classIcons/zone.png b/Templates/Empty/game/tools/classIcons/zone.png new file mode 100644 index 000000000..117e48ad0 Binary files /dev/null and b/Templates/Empty/game/tools/classIcons/zone.png differ diff --git a/Templates/Empty/game/tools/convexEditor/convexEditor.cs b/Templates/Empty/game/tools/convexEditor/convexEditor.cs new file mode 100644 index 000000000..859667bc1 --- /dev/null +++ b/Templates/Empty/game/tools/convexEditor/convexEditor.cs @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +singleton GuiControlProfile( ConvexEditorProfile ) +{ + canKeyFocus = true; + opaque = true; + fillColor = "192 192 192 192"; + category = "Editor"; +}; + +singleton GuiControlProfile (GuiDisabledTextEditProfile) +{ + opaque = false; + border = 0; + bitmap = "./textEdit"; + borderColor = "255 255 255 200"; + fontColor = "0 0 0"; + fontColorHL = "255 255 255"; + fontColorNA = "128 128 128"; + textOffset = "4 2"; + autoSizeWidth = false; + autoSizeHeight = false; + tab = false; + canKeyFocus = false; + category = "Editor"; +}; + +singleton GuiControlProfile (GuiSimpleBorderProfile) +{ + opaque = false; + border = 1; + category = "Editor"; +}; diff --git a/Templates/Empty/game/tools/convexEditor/convexEditorGui.cs b/Templates/Empty/game/tools/convexEditor/convexEditorGui.cs new file mode 100644 index 000000000..1cda5416c --- /dev/null +++ b/Templates/Empty/game/tools/convexEditor/convexEditorGui.cs @@ -0,0 +1,62 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function ConvexEditorGui::onWake( %this ) +{ +} + +function ConvexEditorGui::onSleep( %this ) +{ +} + +function ConvexEditorGui::createConvexBox( %this ) +{ + %obj = genericCreateObject( "ConvexShape" ); + %this.handleDeselect(); + %this.selectConvex( %obj ); + %this.dropSelectionAtScreenCenter(); +} + +function ConvexEditorGui::onSelectionChanged( %this, %shape, %face ) +{ + //echo( "onSelectionChanged: " @ %shape SPC %face ); + + ConvexEditorSplitFaceBtn.setActive( false ); + ConvexEditorSplitFaceBtn.ToolTip = "Split selected face [Disabled]" NL "Use Ctrl + Rotate instead for more control"; + ConvexEditorDeleteFaceBtn.setActive( false ); + ConvexEditorDeleteFaceBtn.ToolTip = "Delete selection [Disabled] (Delete)"; + + if ( !isObject( %shape ) ) + return; + + ConvexEditorDeleteFaceBtn.setActive( true ); + + if ( %face == -1 ) + ConvexEditorDeleteFaceBtn.ToolTip = "Delete selected ConvexShape (Delete)"; + else + { + ConvexEditorDeleteFaceBtn.ToolTip = "Delete selected Face (Delete)"; + + ConvexEditorSplitFaceBtn.ToolTip = "Split selected face" NL "Use Ctrl + Rotate instead for more control"; + ConvexEditorSplitFaceBtn.setActive( true ); + } +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/convexEditor/convexEditorGui.gui b/Templates/Empty/game/tools/convexEditor/convexEditorGui.gui new file mode 100644 index 000000000..c7a47c9e4 --- /dev/null +++ b/Templates/Empty/game/tools/convexEditor/convexEditorGui.gui @@ -0,0 +1,440 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiConvexEditorCtrl(ConvexEditorGui) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ConvexEditorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "None"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + cameraZRot = "0"; + forceFOV = "0"; + renderMissionArea = "0"; + missionAreaFillColor = "255 0 0 20"; + missionAreaFrameColor = "255 0 0 128"; + allowBorderMove = "0"; + borderMovePixelSize = "20"; + borderMoveSpeed = "0.1"; + consoleFrameColor = "255 0 0 255"; + consoleFillColor = "0 0 0 0"; + consoleSphereLevel = "1"; + consoleCircleSegments = "32"; + consoleLineWidth = "1"; + GizmoProfile = "GlobalGizmoProfile"; + DefaultWidth = "10"; + HoverSplineColor = "0 255 0 255"; + SelectedSplineColor = "255 0 255 255"; + HoverNodeColor = "255 255 255 255"; + + new GuiWindowCollapseCtrl(ConvexEditorTreeWindow) { + internalName = ""; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) - 1; + Extent = "210 167"; + MinExtent = "210 100"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "EditorGui.setEditor( WorldEditorInspectorPlugin );"; + EdgeSnap = "1"; + text = "ConvexShapes"; + + new GuiContainer(){ + profile = GuiDefaultProfile; + Position = "5 25"; + Extent = "200 120"; + Docking = "Client"; + Margin = "3 1 3 3 "; + HorizSizing = "width"; + VertSizing = "height"; + isContainer = "1"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "200 118"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiTreeViewCtrl(ConvexTreeView) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "193 21"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "0"; + showRoot = "1"; + internalNamesOnly = "0"; + }; + }; + }; + }; + new GuiWindowCollapseCtrl(ConvexEditorOptionsWindow) { + internalName = "Window"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) + getWord(ConvexEditorTreeWindow.extent, 1) - 2; + Extent = "210 530"; + MinExtent = "210 298"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "EditorGui.setEditor( WorldEditorPlugin );"; + EdgeSnap = "1"; + text = "Properties"; + + new GuiContainer(){ //Node Properties + isContainer = "1"; + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 24"; + Extent = "202 85"; + Docking = "Top"; + Margin = "3 3 3 3"; + + new GuiTextCtrl(){ + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 0"; + Extent = "86 18"; + text = "Node Properties"; + }; + + new GuiTextCtrl(){ + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 21"; + Extent = "46 18"; + text = "Position"; + }; + new GuiTextEditCtrl(){ + internalName = "position"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "57 21"; + Extent = "141 18"; + text = ""; + AltCommand = "ConvexEditorGui.editNodeDetails();"; + }; + new GuiTextCtrl(){ + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 42"; + Extent = "46 18"; + text = "Rotation"; + }; + new GuiTextEditCtrl(){ + internalName = "rotation"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "57 42"; + Extent = "141 18"; + text = ""; + AltCommand = "ConvexEditorGui.editNodeDetails();"; + }; + new GuiTextCtrl(){ + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 63"; + Extent = "46 18"; + text = "Width"; + }; + new GuiTextEditCtrl(){ + internalName = "width"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "57 63"; + Extent = "52 18"; + text = ""; + AltCommand = "ConvexEditorGui.editNodeDetails();"; + }; + new GuiTextCtrl(){ + Profile = "GuiTextRightProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "110 63"; + Extent = "32 18"; + text = "Depth"; + }; + new GuiTextEditCtrl(){ + internalName = "depth"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "146 63"; + Extent = "52 18"; + text = ""; + AltCommand = "ConvexEditorGui.editNodeDetails();"; + }; + }; + new GuiContainer(){ //Conve Road Properties + isContainer = "1"; + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 112"; + Extent = "202 31"; + Docking = "Top"; + Margin = "0 0 3 3"; + + new GuiTextCtrl(){ + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 0"; + Extent = "121 18"; + text = "ConvexShape Properties"; + }; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "4 129"; + Extent = "202 357"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "-14 41 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiInspector(ConvexInspector) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + name = "ConvexInspector"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "179 16"; + MinExtent = "16 16"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + dividerMargin = "5"; + }; + }; + new GuiMLTextCtrl(ConvexFieldInfoControl) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorFieldInfoMLTextProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "1 485"; + Extent = "202 42"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + }; + }; + new GuiWindowCollapseCtrl(ConvexEditorTipsWindow) { + CollapseGroup = "-1"; + CollapseGroupNum = "-1"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Tips"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiWindowCollapseProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + position = "6 483"; + Extent = "136 246"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Docking = "Client"; + Margin = "3 1 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "4 24"; + Extent = "128 218"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextListCtrl() { + columns = "0"; + fitParentWidth = "1"; + clipColumnText = "0"; + isContainer = "1"; + Profile = "GuiTextListProfile"; + HorizSizing = "width"; + VertSizing = "top"; + position = "1 1"; + Extent = "126 2"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "TextList"; + canSaveDynamicFields = "0"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/convexEditor/convexEditorSettingsTab.ed.gui b/Templates/Empty/game/tools/convexEditor/convexEditorSettingsTab.ed.gui new file mode 100644 index 000000000..c84657d06 --- /dev/null +++ b/Templates/Empty/game/tools/convexEditor/convexEditorSettingsTab.ed.gui @@ -0,0 +1,180 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ConvexEditorSettingsTab,EditorGuiGroup) { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiTabPageCtrl(EConvexEditorSettingsPage) { + fitBook = "1"; + text = "Convex Editor"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiSolidDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "208 400"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "208 400"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + extent = "208 210"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Defaults"; + Margin = "0 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Material:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "ConvexEditorPlugin.readSettings();"; + editorSettingsValue = "ConvexEditor/MaterialName"; + editorSettingsWrite = "ConvexEditorPlugin.writeSettings();"; + }; + }; + }; + }; + }; + }; + }; +}; \ No newline at end of file diff --git a/Templates/Empty/game/tools/convexEditor/convexEditorToolbar.ed.gui b/Templates/Empty/game/tools/convexEditor/convexEditorToolbar.ed.gui new file mode 100644 index 000000000..e32e159af --- /dev/null +++ b/Templates/Empty/game/tools/convexEditor/convexEditorToolbar.ed.gui @@ -0,0 +1,121 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(convexEditorToolbar, EditorGuiGroup) { + canSaveDynamicFields = "0"; + internalName = ""; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "305 0"; + Extent = "550" SPC getWord(EditorGuiToolbar.extent, 1); + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + canMove = "0"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + EdgeSnap = "0"; + text =""; + + new GuiContainer() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "menubarProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 32"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "15 7"; + extent = "86 16"; + minExtent = "8 8"; + visible = "1"; + text = "Sketch Tool"; + maxLength = "255"; + helpTag = "0"; + }; + new GuiBitmapCtrl() { + Profile = "GuiDefaultProfile"; + position = "94 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-h.png"; + }; + new GuiBitmapButtonCtrl(ConvexEditorCreateBoxBtn) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "100 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ConvexEditorGui.createConvexBox();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Create ConvexShape Box" NL "Use Alt + Click-Drag instead of this for more control of starting placement."; + hovertime = "1000"; + bitmap = "tools/convexEditor/images/convex-editor-btn"; + text = ""; + groupNum = "-1"; + buttonType = "pushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ConvexEditorSplitFaceBtn) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "134 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ConvexEditorGui.splitSelectedFace();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Split selected face" NL "Use Ctrl + Rotate instead for more control."; + hovertime = "1000"; + bitmap = "tools/convexEditor/images/split-face-btn"; + text = ""; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ConvexEditorDeleteFaceBtn) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "166 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ConvexEditorGui.handleDelete();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Delete selected face" NL "(Delete)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/delete-btn"; + text = ""; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; +}; diff --git a/Templates/Empty/game/tools/convexEditor/images/convex-editor-btn_d.png b/Templates/Empty/game/tools/convexEditor/images/convex-editor-btn_d.png new file mode 100644 index 000000000..2ea137fca Binary files /dev/null and b/Templates/Empty/game/tools/convexEditor/images/convex-editor-btn_d.png differ diff --git a/Templates/Empty/game/tools/convexEditor/images/convex-editor-btn_h.png b/Templates/Empty/game/tools/convexEditor/images/convex-editor-btn_h.png new file mode 100644 index 000000000..956fae3d8 Binary files /dev/null and b/Templates/Empty/game/tools/convexEditor/images/convex-editor-btn_h.png differ diff --git a/Templates/Empty/game/tools/convexEditor/images/convex-editor-btn_n.png b/Templates/Empty/game/tools/convexEditor/images/convex-editor-btn_n.png new file mode 100644 index 000000000..cdb2a4b6d Binary files /dev/null and b/Templates/Empty/game/tools/convexEditor/images/convex-editor-btn_n.png differ diff --git a/Templates/Empty/game/tools/convexEditor/images/split-face-btn_d.png b/Templates/Empty/game/tools/convexEditor/images/split-face-btn_d.png new file mode 100644 index 000000000..8d0ff5114 Binary files /dev/null and b/Templates/Empty/game/tools/convexEditor/images/split-face-btn_d.png differ diff --git a/Templates/Empty/game/tools/convexEditor/images/split-face-btn_h.png b/Templates/Empty/game/tools/convexEditor/images/split-face-btn_h.png new file mode 100644 index 000000000..c2d84b49d Binary files /dev/null and b/Templates/Empty/game/tools/convexEditor/images/split-face-btn_h.png differ diff --git a/Templates/Empty/game/tools/convexEditor/images/split-face-btn_i.png b/Templates/Empty/game/tools/convexEditor/images/split-face-btn_i.png new file mode 100644 index 000000000..c8719cc7d Binary files /dev/null and b/Templates/Empty/game/tools/convexEditor/images/split-face-btn_i.png differ diff --git a/Templates/Empty/game/tools/convexEditor/images/split-face-btn_n.png b/Templates/Empty/game/tools/convexEditor/images/split-face-btn_n.png new file mode 100644 index 000000000..100952571 Binary files /dev/null and b/Templates/Empty/game/tools/convexEditor/images/split-face-btn_n.png differ diff --git a/Templates/Empty/game/tools/convexEditor/main.cs b/Templates/Empty/game/tools/convexEditor/main.cs new file mode 100644 index 000000000..496140cd4 --- /dev/null +++ b/Templates/Empty/game/tools/convexEditor/main.cs @@ -0,0 +1,220 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function initializeConvexEditor() +{ + echo(" % - Initializing Sketch Tool"); + + exec( "./convexEditor.cs" ); + exec( "./convexEditorGui.gui" ); + exec( "./convexEditorToolbar.ed.gui" ); + exec( "./convexEditorGui.cs" ); + + ConvexEditorGui.setVisible( false ); + ConvexEditorOptionsWindow.setVisible( false ); + ConvexEditorTreeWindow.setVisible( false ); + ConvexEditorToolbar.setVisible( false ); + + EditorGui.add( ConvexEditorGui ); + EditorGui.add( ConvexEditorOptionsWindow ); + EditorGui.add( ConvexEditorTreeWindow ); + EditorGui.add( ConvexEditorToolbar ); + + new ScriptObject( ConvexEditorPlugin ) + { + superClass = "EditorPlugin"; + editorGui = ConvexEditorGui; + }; + + // Note that we use the WorldEditor's Toolbar. + + %map = new ActionMap(); + %map.bindCmd( keyboard, "1", "ConvexEditorNoneModeBtn.performClick();", "" ); // Select + %map.bindCmd( keyboard, "2", "ConvexEditorMoveModeBtn.performClick();", "" ); // Move + %map.bindCmd( keyboard, "3", "ConvexEditorRotateModeBtn.performClick();", "" );// Rotate + %map.bindCmd( keyboard, "4", "ConvexEditorScaleModeBtn.performClick();", "" ); // Scale + ConvexEditorPlugin.map = %map; + + ConvexEditorPlugin.initSettings(); +} + +function ConvexEditorPlugin::onWorldEditorStartup( %this ) +{ + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Sketch Tool", "", ConvexEditorPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "Sketch Tool (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "ConvexEditorPlugin", "ConvexEditorPalette", expandFilename("tools/convexEditor/images/convex-editor-btn"), %tooltip ); + + //connect editor windows + GuiWindowCtrl::attach( ConvexEditorOptionsWindow, ConvexEditorTreeWindow); + + // Allocate our special menu. + // It will be added/removed when this editor is activated/deactivated. + + if ( !isObject( ConvexActionsMenu ) ) + { + singleton PopupMenu( ConvexActionsMenu ) + { + superClass = "MenuBuilder"; + + barTitle = "Sketch"; + + Item[0] = "Hollow Selected Shape" TAB "" TAB "ConvexEditorGui.hollowSelection();"; + item[1] = "Recenter Selected Shape" TAB "" TAB "ConvexEditorGui.recenterSelection();"; + }; + } + + %this.popupMenu = ConvexActionsMenu; + + exec( "./convexEditorSettingsTab.ed.gui" ); + ESettingsWindow.addTabPage( EConvexEditorSettingsPage ); +} + +function ConvexEditorPlugin::onActivated( %this ) +{ + %this.readSettings(); + + EditorGui.bringToFront( ConvexEditorGui ); + ConvexEditorGui.setVisible( true ); + ConvexEditorToolbar.setVisible( true ); + ConvexEditorGui.makeFirstResponder( true ); + %this.map.push(); + + // Set the status bar here until all tool have been hooked up + EditorGuiStatusBar.setInfo( "Sketch Tool." ); + EditorGuiStatusBar.setSelection( "" ); + + // Add our menu. + EditorGui.menuBar.insert( ConvexActionsMenu, EditorGui.menuBar.dynamicItemInsertPos ); + + // Sync the pallete button state with the gizmo mode. + %mode = GlobalGizmoProfile.mode; + switch$ (%mode) + { + case "None": + ConvexEditorNoneModeBtn.performClick(); + case "Move": + ConvexEditorMoveModeBtn.performClick(); + case "Rotate": + ConvexEditorRotateModeBtn.performClick(); + case "Scale": + ConvexEditorScaleModeBtn.performClick(); + } + + Parent::onActivated( %this ); +} + +function ConvexEditorPlugin::onDeactivated( %this ) +{ + %this.writeSettings(); + + ConvexEditorGui.setVisible( false ); + ConvexEditorOptionsWindow.setVisible( false ); + ConvexEditorTreeWindow.setVisible( false ); + ConvexEditorToolbar.setVisible( false ); + %this.map.pop(); + + // Remove our menu. + EditorGui.menuBar.remove( ConvexActionsMenu ); + + Parent::onDeactivated( %this ); +} + +function ConvexEditorPlugin::onEditMenuSelect( %this, %editMenu ) +{ + %hasSelection = false; + + if ( ConvexEditorGui.hasSelection() ) + %hasSelection = true; + + %editMenu.enableItem( 3, false ); // Cut + %editMenu.enableItem( 4, false ); // Copy + %editMenu.enableItem( 5, false ); // Paste + %editMenu.enableItem( 6, %hasSelection ); // Delete + %editMenu.enableItem( 8, %hasSelection ); // Deselect +} + +function ConvexEditorPlugin::handleDelete( %this ) +{ + ConvexEditorGui.handleDelete(); +} + +function ConvexEditorPlugin::handleDeselect( %this ) +{ + ConvexEditorGui.handleDeselect(); +} + +function ConvexEditorPlugin::handleCut( %this ) +{ + //WorldEditorInspectorPlugin.handleCut(); +} + +function ConvexEditorPlugin::handleCopy( %this ) +{ + //WorldEditorInspectorPlugin.handleCopy(); +} + +function ConvexEditorPlugin::handlePaste( %this ) +{ + //WorldEditorInspectorPlugin.handlePaste(); +} + +function ConvexEditorPlugin::isDirty( %this ) +{ + return ConvexEditorGui.isDirty; +} + +function ConvexEditorPlugin::onSaveMission( %this, %missionFile ) +{ + if( ConvexEditorGui.isDirty ) + { + MissionGroup.save( %missionFile ); + ConvexEditorGui.isDirty = false; + } +} + +//----------------------------------------------------------------------------- +// Settings +//----------------------------------------------------------------------------- + +function ConvexEditorPlugin::initSettings( %this ) +{ + EditorSettings.beginGroup( "ConvexEditor", true ); + EditorSettings.setDefaultValue( "MaterialName", "Grid512_OrangeLines_Mat" ); + EditorSettings.endGroup(); +} + +function ConvexEditorPlugin::readSettings( %this ) +{ + EditorSettings.beginGroup( "ConvexEditor", true ); + ConvexEditorGui.materialName = EditorSettings.value("MaterialName"); + EditorSettings.endGroup(); +} + +function ConvexEditorPlugin::writeSettings( %this ) +{ + EditorSettings.beginGroup( "ConvexEditor", true ); + EditorSettings.setValue( "MaterialName", ConvexEditorGui.materialName ); + EditorSettings.endGroup(); +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/datablockEditor/DatablockEditorCreatePrompt.ed.gui b/Templates/Empty/game/tools/datablockEditor/DatablockEditorCreatePrompt.ed.gui new file mode 100644 index 000000000..06966e72f --- /dev/null +++ b/Templates/Empty/game/tools/datablockEditor/DatablockEditorCreatePrompt.ed.gui @@ -0,0 +1,224 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(DatablockEditorCreatePrompt,EditorGuiGroup) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiWindowCtrl() { + text = "Create New Datablock"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "0"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + closeCommand = "canvas.popDialog(DatablockEditorCreatePrompt);"; + edgeSnap = "0"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "389 252"; + extent = "207 167"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Your new datablock must have a name"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "7 26"; + extent = "190 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "Name"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "7 45"; + extent = "191 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "CreateDatablockName"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Create"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "7 137"; + extent = "122 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "DatablockEditorPlugin.createPromptNameCheck();"; + accelerator = "return"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "135 137"; + extent = "63 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "canvas.popDialog(DatablockEditorCreatePrompt);"; + accelerator = "escape"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Copy values from"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "7 66"; + extent = "100 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "7 87"; + extent = "191 19"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "CopySourceDropdown"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Client-Side Datablock"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "7 105"; + extent = "140 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "ClientSideCheckBox"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/datablockEditor/DatablockEditorInspectorWindow.ed.gui b/Templates/Empty/game/tools/datablockEditor/DatablockEditorInspectorWindow.ed.gui new file mode 100644 index 000000000..a9632ef21 --- /dev/null +++ b/Templates/Empty/game/tools/datablockEditor/DatablockEditorInspectorWindow.ed.gui @@ -0,0 +1,211 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl() { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiWindowCollapseCtrl(DatablockEditorInspectorWindow) { + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "DatablockEditorInspectorWindow.setVisible(false);"; + EdgeSnap = "1"; + text = "Datablock"; + Margin = "8 8 8 8"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) + getWord(DatablockEditorTreeWindow.extent, 1) - 2; + Extent = "210 373"; + MinExtent = "210 140"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "DatablockEditorInspectorWindow"; + canSaveDynamicFields = "0"; + + new GuiContainer() { + Docking = "Client"; + Margin = "22 41 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "4 41"; + Extent = "202 287"; + MinExtent = "64 64"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = true; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "202 287"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiInspector(DatablockEditorInspector) { + dividerMargin = "5"; + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + ChangeChildSizeToFit = "1"; + ChangeChildPosition = "1"; + isContainer = "1"; + Profile = "GuiInspectorProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "190 8"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + superClass = "EditorInspectorBase"; + }; + }; + }; + new GuiMLTextCtrl(DatablockFieldInfoControl) { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + isContainer = "0"; + Profile = "GuiInspectorFieldInfoMLTextProfile"; + HorizSizing = "width"; + VertSizing = "top"; + position = "1 328"; + Extent = "205 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "4 23"; + Extent = "159 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "DatablockFile"; + canSaveDynamicFields = "0"; + active = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/save-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "167 23"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "DatablockEditorPlugin.save();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Save Datablock (ALT S)"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/save-as"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "187 23"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "DatablockEditorPlugin.showSaveNewFileDialog();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Save Datablock to a New File"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + internalName = "saveAsButton"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/datablockEditor/DatablockEditorTreeWindow.ed.gui b/Templates/Empty/game/tools/datablockEditor/DatablockEditorTreeWindow.ed.gui new file mode 100644 index 000000000..760ae9fa4 --- /dev/null +++ b/Templates/Empty/game/tools/datablockEditor/DatablockEditorTreeWindow.ed.gui @@ -0,0 +1,311 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl() { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiWindowCollapseCtrl(DatablockEditorTreeWindow) { + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "DatablockInspectorTreeWindow.setVisible(false);"; + EdgeSnap = "1"; + text = "Datablock Library"; + Margin = "8 8 8 8"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) - 1; + Extent = "210 324"; + MinExtent = "210 140"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "DatablockEditorTreeWindow"; + canSaveDynamicFields = "0"; + + new GuiTabBookCtrl(DatablockEditorTreeTabBook) { + TabPosition = "Top"; + TabMargin = "0"; + MinTabWidth = "64"; + Docking = "Client"; + Margin = "3 2 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "4 25"; + Extent = "202 294"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "DatablockEditorTree"; + canSaveDynamicFields = "0"; + + new GuiTabPageCtrl() { + text = "Existing"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "EditorTabPage"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 19"; + Extent = "202 276"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextEditCtrl( DatablockEditorTreeFilter ) { + position = "2 4"; + extent = "180 18"; + profile = "GuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + class = "GuiTreeViewFilterText"; + treeView = DatablockEditorTree; + }; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/clear-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "185 5"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + class = "GuiTreeViewFilterClearButton"; + textCtrl = DatablockEditorTreeFilter; + }; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 25"; + Extent = "202 251"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTreeViewCtrl(DatablockEditorTree) { + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "0"; + MouseDragging = "0"; + MultipleSelections = "1"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "0"; + ClearAllOnSingleSelection = "1"; + showRoot = "1"; + internalNamesOnly = "0"; + objectNamesOnly = "0"; + compareToObjectID = "0"; + isContainer = "1"; + Profile = "GuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "198 21"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiTabPageCtrl(DatablockEditorCreator) { + text = "New"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "EditorTabPage"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 19"; + Extent = "202 276"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "DatablockEditorCreator"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "202 276"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTreeViewCtrl(DatablockEditorTypeTree) { + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "0"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "0"; + DragToItemAllowed = "0"; + ClearAllOnSingleSelection = "1"; + showRoot = "1"; + internalNamesOnly = "0"; + objectNamesOnly = "0"; + compareToObjectID = "1"; + isContainer = "1"; + Profile = "GuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "196 260"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + altCommand = "DatablockEditorPlugin.createDatablock();"; + }; + }; + }; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "190 26"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "DatablockEditorPlugin.deleteDatablock();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Delete Datablock"; + hovertime = "1000"; + internalName = "deleteSelection"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "core/art/gui/images/new"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "192 25"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + Command = "DatablockEditorPlugin.createDatablock();"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Create New Datablock"; + hovertime = "1000"; + internalName = "CreateSelection"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/datablockEditor/datablockEditor.cs b/Templates/Empty/game/tools/datablockEditor/datablockEditor.cs new file mode 100644 index 000000000..8eb47e085 --- /dev/null +++ b/Templates/Empty/game/tools/datablockEditor/datablockEditor.cs @@ -0,0 +1,885 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Main code for the Datablock Editor plugin. + + +$DATABLOCK_EDITOR_DEFAULT_FILENAME = "art/datablocks/managedDatablocks.cs"; + +//============================================================================================= +// Initialization. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::init( %this ) +{ + if( !DatablockEditorTree.getItemCount() ) + %this.populateTrees(); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::onWorldEditorStartup( %this ) +{ + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Datablock Editor", "", DatablockEditorPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "Datablock Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "DatablockEditorPlugin", "DatablockEditorPalette", expandFilename("tools/worldEditor/images/toolbar/datablock-editor"), %tooltip ); + + //connect editor windows + GuiWindowCtrl::Attach( DatablockEditorInspectorWindow, DatablockEditorTreeWindow); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::onActivated( %this ) +{ + EditorGui-->WorldEditorToolbar.setVisible(false); + EditorGui.bringToFront( DatablockEditorPlugin ); + + DatablockEditorTreeWindow.setVisible( true ); + DatablockEditorInspectorWindow.setVisible( true ); + DatablockEditorInspectorWindow.makeFirstResponder( true ); + + %this.map.push(); + + // Set the status bar here until all tool have been hooked up + EditorGuiStatusBar.setInfo( "Datablock editor." ); + + %numSelected = %this.getNumSelectedDatablocks(); + if( !%numSelected ) + EditorGuiStatusBar.setSelection( "" ); + else + EditorGuiStatusBar.setSelection( %numSelected @ " datablocks selected" ); + + %this.init(); + DatablockEditorPlugin.readSettings(); + + if( EWorldEditor.getSelectionSize() == 1 ) + %this.onObjectSelected( EWorldEditor.getSelectedObject( 0 ) ); + + Parent::onActivated( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::onDeactivated( %this ) +{ + DatablockEditorPlugin.writeSettings(); + + DatablockEditorInspectorWindow.setVisible( false ); + DatablockEditorTreeWindow.setVisible( false ); + %this.map.pop(); + + Parent::onDeactivated(%this); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::onExitMission( %this ) +{ + DatablockEditorTree.clear(); + DatablockEditorInspector.inspect( "" ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::openDatablock( %this, %datablock ) +{ + EditorGui.setEditor( DatablockEditorPlugin ); + %this.selectDatablock( %datablock ); + DatablockEditorTreeTabBook.selectedPage = 0; +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::setEditorFunction( %this ) +{ + return true; +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::onObjectSelected( %this, %object ) +{ + // Select datablock of object if this is a GameBase object. + + if( %object.isMemberOfClass( "GameBase" ) ) + %this.selectDatablock( %object.getDatablock() ); + else if( %object.isMemberOfClass( "SFXEmitter" ) && isObject( %object.track ) ) + %this.selectDatablock( %object.track ); + else if( %object.isMemberOfClass( "LightBase" ) && isObject( %object.animationType ) ) + %this.selectDatablock( %object.animationType ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::populateTrees(%this) +{ + // Populate datablock tree. + + if( %this.excludeClientOnlyDatablocks ) + %set = DataBlockGroup; + else + %set = DataBlockSet; + + DatablockEditorTree.clear(); + + foreach( %datablock in %set ) + { + %unlistedFound = false; + %id = %datablock.getId(); + + foreach( %obj in UnlistedDatablocks ) + if( %obj.getId() == %id ) + { + %unlistedFound = true; + break; + } + + if( %unlistedFound ) + continue; + + %this.addExistingItem( %datablock, true ); + } + + DatablockEditorTree.sort( 0, true, false, false ); + + // Populate datablock type tree. + + %classList = enumerateConsoleClasses( "SimDatablock" ); + DatablockEditorTypeTree.clear(); + + foreach$( %datablockClass in %classList ) + { + if( !%this.isExcludedDatablockType( %datablockClass ) + && DatablockEditorTypeTree.findItemByName( %datablockClass ) == 0 ) + DatablockEditorTypeTree.insertItem( 0, %datablockClass ); + } + + DatablockEditorTypeTree.sort( 0, false, false, false ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::addExistingItem( %this, %datablock, %dontSort ) +{ + %tree = DatablockEditorTree; + + // Look up class at root level. Create if needed. + + %class = %datablock.getClassName(); + %parentID = %tree.findItemByName( %class ); + if( %parentID == 0 ) + %parentID = %tree.insertItem( 0, %class ); + + // If the datablock is already there, don't + // do anything. + + if( %tree.findItemByValue( %datablock.getId() ) ) + return; + + // It doesn't exist so add it. + + %name = %datablock.getName(); + if( %this.PM.isDirty( %datablock ) ) + %name = %name @ " *"; + + %id = DatablockEditorTree.insertItem( %parentID, %name, %datablock.getId() ); + if( !%dontSort ) + DatablockEditorTree.sort( %parentID, false, false, false ); + + return %id; +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::isExcludedDatablockType( %this, %className ) +{ + switch$( %className ) + { + case "SimDatablock": + return true; + case "SFXTrack": // Abstract. + return true; + case "SFXFMODEvent": // Internally created. + return true; + case "SFXFMODEventGroup": // Internally created. + return true; + } + return false; +} + +//============================================================================================= +// Settings. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::initSettings( %this ) +{ + EditorSettings.beginGroup("DatablockEditor", true); + + EditorSettings.setDefaultValue("libraryTab", "0"); + + EditorSettings.endGroup(); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::readSettings( %this ) +{ + EditorSettings.beginGroup("DatablockEditor", true); + + DatablockEditorTreeTabBook.selectPage( EditorSettings.value( "libraryTab" ) ); + %db = EditorSettings.value( "selectedDatablock" ); + if( isObject( %db ) && %db.isMemberOfClass( "SimDatablock" ) ) + %this.selectDatablock( %db ); + + EditorSettings.endGroup(); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::writeSettings( %this ) +{ + EditorSettings.beginGroup( "DatablockEditor", true ); + + EditorSettings.setValue( "libraryTab", DatablockEditorTreeTabBook.getSelectedPage() ); + if( %this.getNumSelectedDatablocks() > 0 ) + EditorSettings.setValue( "selectedDatablock", %this.getSelectedDatablock().getName() ); + + EditorSettings.endGroup(); +} + +//============================================================================================= +// Persistence. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +/// Return true if there is any datablock with unsaved changes. +function DatablockEditorPlugin::isDirty( %this ) +{ + return %this.PM.hasDirty(); +} + +//--------------------------------------------------------------------------------------------- + +/// Return true if any of the currently selected datablocks has unsaved changes. +function DatablockEditorPlugin::selectedDatablockIsDirty( %this ) +{ + %tree = DatablockEditorTree; + + %count = %tree.getSelectedItemsCount(); + %selected = %tree.getSelectedItemList(); + + foreach$( %id in %selected ) + { + %db = %tree.getItemValue( %id ); + if( %this.PM.isDirty( %db ) ) + return true; + } + + return false; +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::syncDirtyState( %this ) +{ + %tree = DatablockEditorTree; + + %count = %tree.getSelectedItemsCount(); + %selected = %tree.getSelectedItemList(); + %haveDirty = false; + + foreach$( %id in %selected ) + { + %db = %tree.getItemValue( %id ); + if( %this.PM.isDirty( %db ) ) + { + %this.flagDatablockAsDirty( %db, true ); + %haveDirty = true; + } + else + %this.flagInspectorAsDirty( %db, false ); + } + + %this.flagInspectorAsDirty( %haveDirty ); +} + +//--------------------------------------------------------------------------------------------- + +/// +function DatablockEditorPlugin::flagInspectorAsDirty( %this, %dirty ) +{ + if( %dirty ) + DatablockEditorInspectorWindow.text = "Datablock *"; + else + DatablockEditorInspectorWindow.text = "Datablock"; +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::flagDatablockAsDirty(%this, %datablock, %dirty ) +{ + %tree = DatablockEditorTree; + + %id = %tree.findItemByValue( %datablock.getId() ); + if( %id == 0 ) + return; + + // Tag the item caption and sync the persistence manager. + + if( %dirty ) + { + DatablockEditorTree.editItem( %id, %datablock.getName() @ " *", %datablock.getId() ); + %this.PM.setDirty( %datablock ); + } + else + { + DatablockEditorTree.editItem( %id, %datablock.getName(), %datablock.getId() ); + %this.PM.removeDirty( %datablock ); + } + + // Sync the inspector dirty state. + + %this.flagInspectorAsDirty( %this.PM.hasDirty() ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::showSaveNewFileDialog(%this) +{ + %currentFile = %this.getSelectedDatablock().getFilename(); + getSaveFilename( "TorqueScript Files|*.cs|All Files|*.*", %this @ ".saveNewFileFinish", %currentFile, false ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::saveNewFileFinish( %this, %newFileName ) +{ + // Clear the first responder to capture any inspector changes + %ctrl = canvas.getFirstResponder(); + if( isObject(%ctrl) ) + %ctrl.clearFirstResponder(); + + %tree = DatablockEditorTree; + %count = %tree.getSelectedItemsCount(); + %selected = %tree.getSelectedItemList(); + + foreach$( %id in %selected ) + { + %db = %tree.getItemValue( %id ); + %db = %this.getSelectedDatablock(); + + // Remove from current file. + + %oldFileName = %db.getFileName(); + if( %oldFileName !$= "" ) + %this.PM.removeObjectFromFile( %db, %oldFileName ); + + // Save to new file. + + %this.PM.setDirty( %db, %newFileName ); + if( %this.PM.saveDirtyObject( %db ) ) + { + // Clear dirty state. + + %this.flagDatablockAsDirty( %db, false ); + } + } + + DatablockEditorInspectorWindow-->DatablockFile.setText( %newFileName ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::save( %this ) +{ + // Clear the first responder to capture any inspector changes + %ctrl = canvas.getFirstResponder(); + if( isObject(%ctrl) ) + %ctrl.clearFirstResponder(); + + %tree = DatablockEditorTree; + %count = %tree.getSelectedItemsCount(); + %selected = %tree.getSelectedItemList(); + + for( %i = 0; %i < %count; %i ++ ) + { + %id = getWord( %selected, %i ); + %db = %tree.getItemValue( %id ); + + if( %this.PM.isDirty( %db ) ) + { + %this.PM.saveDirtyObject( %db ); + %this.flagDatablockAsDirty( %db, false ); + } + } +} + +//============================================================================================= +// Selection. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::getNumSelectedDatablocks( %this ) +{ + return DatablockEditorTree.getSelectedItemsCount(); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::getSelectedDatablock( %this, %index ) +{ + %tree = DatablockEditorTree; + if( !%tree.getSelectedItemsCount() ) + return 0; + + if( !%index ) + %id = %tree.getSelectedItem(); + else + %id = getWord( %tree.getSelectedItemList(), %index ); + + return %tree.getItemValue( %id ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::resetSelectedDatablock( %this ) +{ + DatablockEditorTree.clearSelection(); + DatablockEditorInspector.inspect(0); + DatablockEditorInspectorWindow-->DatablockFile.setText(""); + + EditorGuiStatusBar.setSelection( "" ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::selectDatablockCheck( %this, %datablock ) +{ + if( %this.selectedDatablockIsDirty() ) + %this.showSaveDialog( %datablock ); + else + %this.selectDatablock( %datablock ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::selectDatablock( %this, %datablock, %add, %dontSyncTree ) +{ + if( %add ) + DatablockEditorInspector.addInspect( %datablock ); + else + DatablockEditorInspector.inspect( %datablock ); + + if( !%dontSyncTree ) + { + %id = DatablockEditorTree.findItemByValue( %datablock.getId() ); + + if( !%add ) + DatablockEditorTree.clearSelection(); + + DatablockEditorTree.selectItem( %id, true ); + DatablockEditorTree.scrollVisible( %id ); + } + + %this.syncDirtyState(); + + // Update the filename text field. + + %numSelected = %this.getNumSelectedDatablocks(); + %fileNameField = DatablockEditorInspectorWindow-->DatablockFile; + + if( %numSelected == 1 ) + { + %fileName = %datablock.getFilename(); + if( %fileName !$= "" ) + %fileNameField.setText( %fileName ); + else + %fileNameField.setText( $DATABLOCK_EDITOR_DEFAULT_FILENAME ); + } + else + { + %fileNameField.setText( "" ); + } + + EditorGuiStatusBar.setSelection( %this.getNumSelectedDatablocks() @ " Datablocks Selected" ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::unselectDatablock( %this, %datablock, %dontSyncTree ) +{ + DatablockEditorInspector.removeInspect( %datablock ); + + if( !%dontSyncTree ) + { + %id = DatablockEditorTree.findItemByValue( %datablock.getId() ); + DatablockEditorTree.selectItem( %id, false ); + } + + %this.syncDirtyState(); + + // If we have exactly one selected datablock remaining, re-enable + // the save-as button. + + %numSelected = %this.getNumSelectedDatablocks(); + if( %numSelected == 1 ) + { + DatablockEditorInspectorWindow-->saveAsButton.setActive( true ); + + %fileNameField = DatablockEditorInspectorWindow-->DatablockFile; + %fileNameField.setText( %this.getSelectedDatablock().getFilename() ); + %fileNameField.setActive( true ); + } + + EditorGuiStatusBar.setSelection( %this.getNumSelectedDatablocks() @ " Datablocks Selected" ); +} + +//============================================================================================= +// Creation and Deletion. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::deleteDatablock( %this ) +{ + %tree = DatablockEditorTree; + + // If we have more than single datablock selected, + // turn our undos into a compound undo. + + %numSelected = %tree.getSelectedItemsCount(); + if( %numSelected > 1 ) + Editor.getUndoManager().pushCompound( "Delete Multiple Datablocks" ); + + for( %i = 0; %i < %numSelected; %i ++ ) + { + %id = %tree.getSelectedItem( %i ); + %db = %tree.getItemValue( %id ); + + %fileName = %db.getFileName(); + + // Remove the datablock from the tree. + + DatablockEditorTree.removeItem( %id ); + + // Create undo. + + %action = %this.createUndo( ActionDeleteDatablock, "Delete Datablock" ); + %action.db = %db; + %action.dbName = %db.getName(); + %action.fname = %fileName; + + %this.submitUndo( %action ); + + // Kill the datablock in the file. + + if( %fileName !$= "" ) + %this.PM.removeObjectFromFile( %db ); + + UnlistedDatablocks.add( %db ); + + // Show some confirmation. + + if( %numSelected == 1 ) + MessageBoxOk( "Datablock Deleted", "The datablock (" @ %db.getName() @ ") has been removed from " @ + "it's file (" @ %db.getFilename() @ ") and upon restart will cease to exist" ); + } + + // Close compound, if we were deleting multiple datablocks. + + if( %numSelected > 1 ) + Editor.getUndoManager().popCompound(); + + // Show confirmation for multiple datablocks. + + if( %numSelected > 1 ) + MessageBoxOk( "Datablocks Deleted", "The datablocks have been deleted and upon restart will cease to exist." ); + + // Clear selection. + + DatablockEditorPlugin.resetSelectedDatablock(); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::createDatablock(%this) +{ + %class = DatablockEditorTypeTree.getItemText(DatablockEditorTypeTree.getSelectedItem()); + if( %class !$= "" ) + { + // Need to prompt for a name. + + DatablockEditorCreatePrompt-->CreateDatablockName.setText("Name"); + DatablockEditorCreatePrompt-->CreateDatablockName.selectAllText(); + + // Populate the copy source dropdown. + + %list = DatablockEditorCreatePrompt-->CopySourceDropdown; + %list.clear(); + %list.add( "", 0 ); + + %set = DataBlockSet; + %count = %set.getCount(); + for( %i = 0; %i < %count; %i ++ ) + { + %datablock = %set.getObject( %i ); + %datablockClass = %datablock.getClassName(); + + if( !isMemberOfClass( %datablockClass, %class ) ) + continue; + + %list.add( %datablock.getName(), %i + 1 ); + } + + // Set up state of client-side checkbox. + + %clientSideCheckBox = DatablockEditorCreatePrompt-->ClientSideCheckBox; + %canBeClientSide = DatablockEditorPlugin::canBeClientSideDatablock( %class ); + %clientSideCheckBox.setStateOn( %canBeClientSide ); + %clientSideCheckBox.setActive( %canBeClientSide ); + + // Show the dialog. + + canvas.pushDialog( DatablockEditorCreatePrompt, 0, true ); + } +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::createPromptNameCheck(%this) +{ + %name = DatablockEditorCreatePrompt-->CreateDatablockName.getText(); + if( !Editor::validateObjectName( %name, true ) ) + return; + + // Fetch the copy source and clear the list. + + %copySource = DatablockEditorCreatePrompt-->copySourceDropdown.getText(); + DatablockEditorCreatePrompt-->copySourceDropdown.clear(); + + // Remove the dialog and create the datablock. + + canvas.popDialog( DatablockEditorCreatePrompt ); + %this.createDatablockFinish( %name, %copySource ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::createDatablockFinish( %this, %name, %copySource ) +{ + %class = DatablockEditorTypeTree.getItemText(DatablockEditorTypeTree.getSelectedItem()); + if( %class !$= "" ) + { + %action = %this.createUndo( ActionCreateDatablock, "Create New Datablock" ); + + if( DatablockEditorCreatePrompt-->ClientSideCheckBox.isStateOn() ) + %dbType = "singleton "; + else + %dbType = "datablock "; + + if( %copySource !$= "" ) + %eval = %dbType @ %class @ "(" @ %name @ " : " @ %copySource @ ") { canSaveDynamicFields = \"1\"; };"; + else + %eval = %dbType @ %class @ "(" @ %name @ ") { canSaveDynamicFields = \"1\"; };"; + + %res = eval( %eval ); + + %action.db = %name.getId(); + %action.dbName = %name; + %action.fname = $DATABLOCK_EDITOR_DEFAULT_FILENAME; + + %this.submitUndo( %action ); + + %action.redo(); + } +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::canBeClientSideDatablock( %className ) +{ + switch$( %className ) + { + case "SFXProfile" or + "SFXPlayList" or + "SFXAmbience" or + "SFXEnvironment" or + "SFXState" or + "SFXDescription" or + "SFXFMODProject": + return true; + + default: + return false; + } +} + +//============================================================================================= +// Events. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorInspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ) +{ + // Same work to do as for the regular WorldEditor Inspector. + Inspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ); + + DatablockEditorPlugin.flagDatablockAsDirty( %object, true ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorInspector::onFieldSelected( %this, %fieldName, %fieldTypeStr, %fieldDoc ) +{ + DatablockFieldInfoControl.setText( "" @ %fieldName @ " (" @ %fieldTypeStr @ ") " NL "" @ %fieldDoc ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorInspector::onBeginCompoundEdit( %this ) +{ + Editor.getUndoManager().pushCompound( "Multiple Field Edit" ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorInspector::onEndCompoundEdit( %this, %discard ) +{ + Editor.getUndoManager().popCompound( %discard ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorInspector::onClear( %this ) +{ + DatablockFieldInfoControl.setText( "" ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorTree::onDeleteSelection( %this ) +{ + %this.undoDeleteList = ""; +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorTree::onDeleteObject( %this, %object ) +{ + // Append it to our list. + %this.undoDeleteList = %this.undoDeleteList TAB %object; + + // We're gonna delete this ourselves in the + // completion callback. + return true; +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorTree::onObjectDeleteCompleted( %this ) +{ + //MEDeleteUndoAction::submit( %this.undoDeleteList ); + + // Let the world editor know to + // clear its selection. + //EWorldEditor.clearSelection(); + //EWorldEditor.isDirty = true; +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorTree::onClearSelected(%this) +{ + DatablockEditorInspector.inspect( 0 ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorTree::onAddSelection( %this, %id ) +{ + %obj = %this.getItemValue( %id ); + + if( !isObject( %obj ) ) + %this.selectItem( %id, false ); + else + DatablockEditorPlugin.selectDatablock( %obj, true, true ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorTree::onRemoveSelection( %this, %id ) +{ + %obj = %this.getItemValue( %id ); + if( isObject( %obj ) ) + DatablockEditorPlugin.unselectDatablock( %obj, true ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorTree::onRightMouseUp( %this, %id, %mousePos ) +{ + %datablock = %this.getItemValue( %id ); + if( !isObject( %datablock ) ) + return; + + if( !isObject( DatablockEditorTreePopup ) ) + new PopupMenu( DatablockEditorTreePopup ) + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Delete" TAB "" TAB "DatablockEditorPlugin.selectDatablock( %this.datablockObject ); DatablockEditorPlugin.deleteDatablock( %this.datablockObject );"; + item[ 1 ] = "Jump to Definition in Torsion" TAB "" TAB "EditorOpenDeclarationInTorsion( %this.datablockObject );"; + + datablockObject = ""; + }; + + DatablockEditorTreePopup.datablockObject = %datablock; + DatablockEditorTreePopup.showPopup( Canvas ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorTreeTabBook::onTabSelected(%this, %text, %id) +{ + switch(%id) + { + case 0: + DatablockEditorTreeWindow-->DeleteSelection.visible = true; + DatablockEditorTreeWindow-->CreateSelection.visible = false; + + case 1: + DatablockEditorTreeWindow-->DeleteSelection.visible = false; + DatablockEditorTreeWindow-->CreateSelection.visible = true; + } +} diff --git a/Templates/Empty/game/tools/datablockEditor/datablockEditorUndo.cs b/Templates/Empty/game/tools/datablockEditor/datablockEditorUndo.cs new file mode 100644 index 000000000..f9a8d30b4 --- /dev/null +++ b/Templates/Empty/game/tools/datablockEditor/datablockEditorUndo.cs @@ -0,0 +1,159 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::createUndo( %this, %class, %desc ) +{ + pushInstantGroup(); + %action = new UndoScriptAction() + { + class = %class; + superClass = BaseDatablockEdAction; + actionName = %desc; + editor = DatablockEditorPlugin; + treeview = DatablockEditorTree; + inspector = DatablockEditorInspector; + }; + popInstantGroup(); + return %action; +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::submitUndo( %this, %action ) +{ + %action.addToManager( Editor.getUndoManager() ); +} + +//============================================================================================= +// BaseDatablockEdAction. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function BaseDatablockEdAction::redo( %this ) +{ +} + +//--------------------------------------------------------------------------------------------- + +function BaseDatablockEdAction::undo( %this ) +{ +} + +//============================================================================================= +// ActionCreateDatablock. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionCreateDatablock::redo( %this ) +{ + %db = %this.db; + + %db.name = %this.dbName; + + %this.editor.PM.setDirty( %db, %this.fname ); + %this.editor.addExistingItem( %db ); + %this.editor.selectDatablock( %db ); + %this.editor.flagInspectorAsDirty( true ); + + UnlistedDatablocks.remove( %id ); +} + +//--------------------------------------------------------------------------------------------- + +function ActionCreateDatablock::undo( %this ) +{ + %db = %this.db; + + %itemId = %this.treeview.findItemByName( %db.name ); + if( !%itemId ) + %itemId = %this.treeview.findItemByName( %db.name @ " *" ); + + %this.treeview.removeItem( %itemId ); + %this.editor.resetSelectedDatablock(); + %this.editor.PM.removeDirty( %db ); + + %this.dbName = %db.name; + %db.name = ""; + + UnlistedDatablocks.add( %this.db ); +} + +//============================================================================================= +// ActionDeleteDatablock. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionDeleteDatablock::redo( %this ) +{ + %db = %this.db; + + %itemId = %this.treeview.findItemByName( %db.name ); + if( !%itemId ) + %itemId = %this.treeview.findItemByName( %db.name @ " *" ); + + // Remove from tree and file. + + %this.treeview.removeItem( %db ); + %this.editor.resetSelectedDatablock(); + if( %db.getFileName() !$= "" ) + %this.editor.PM.removeObjectFromFile( %db ); + + // Unassign name. + + %this.dbName = %db.name; + %db.name = ""; + + // Add to unlisted. + + UnlistedDatablocks.add( %db ); +} + +//--------------------------------------------------------------------------------------------- + +function ActionDeleteDatablock::undo( %this ) +{ + %db = %this.db; + + // Restore name. + + %db.name = %this.dbName; + + // Add to tree and select. + + %this.editor.addExistingItem( %db, true ); + %this.editor.selectDatablock( %db ); + + // Mark as dirty. + + %this.editor.PM.setDirty( %db, %this.fname ); + %this.editor.syncDirtyState(); + + // Remove from unlisted. + + UnlistedDatablocks.remove( %id ); +} diff --git a/Templates/Empty/game/tools/datablockEditor/main.cs b/Templates/Empty/game/tools/datablockEditor/main.cs new file mode 100644 index 000000000..e7626a8b3 --- /dev/null +++ b/Templates/Empty/game/tools/datablockEditor/main.cs @@ -0,0 +1,66 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +//--------------------------------------------------------------------------------------------- + +function initializeDatablockEditor() +{ + echo( " - Initializing Datablock Editor" ); + + exec("./datablockEditor.cs"); + exec("./datablockEditorUndo.cs"); + exec("./DatablockEditorTreeWindow.ed.gui"); + exec("./DatablockEditorInspectorWindow.ed.gui"); + exec("./DatablockEditorCreatePrompt.ed.gui"); + + // Add ourselves to EditorGui, where all the other tools reside + DatablockEditorInspectorWindow.setVisible( false ); + DatablockEditorTreeWindow.setVisible( false ); + + EditorGui.add( DatablockEditorInspectorWindow ); + EditorGui.add( DatablockEditorTreeWindow ); + + new ScriptObject( DatablockEditorPlugin ) + { + superClass = "WorldEditorPlugin"; + editorGui = EWorldEditor; + }; + + new SimSet( UnlistedDatablocks ); + + // create our persistence manager + DatablockEditorPlugin.PM = new PersistenceManager(); + + %map = new ActionMap(); + %map.bindCmd( keyboard, "backspace", "DatablockEditorPlugin.onDeleteKey();", "" ); + %map.bindCmd( keyboard, "delete", "DatablockEditorPlugin.onDeleteKey();", "" ); + DatablockEditorPlugin.map = %map; + + DatablockEditorPlugin.initSettings(); +} + +//--------------------------------------------------------------------------------------------- + +function destroyDatablockEditor() +{ +} diff --git a/Templates/Empty/game/tools/debugger/gui/breakConditionDlg.ed.gui b/Templates/Empty/game/tools/debugger/gui/breakConditionDlg.ed.gui new file mode 100644 index 000000000..ee7f5a4be --- /dev/null +++ b/Templates/Empty/game/tools/debugger/gui/breakConditionDlg.ed.gui @@ -0,0 +1,145 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(DebuggerBreakConditionDlg, EditorGuiGroup) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + + new GuiWindowCtrl() { + profile = "GuiWindowProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "220 146"; + extent = "200 188"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Set the break condition"; + resizeWidth = "True"; + resizeHeight = "True"; + canMove = "False"; + canClose = "False"; + canMinimize = "False"; + canMaximize = "False"; + minSize = "50 50"; + + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 28"; + extent = "121 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Enter the break condition:"; + }; + new GuiTextEditCtrl(BreakCondition) { + profile = "GuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 44"; + extent = "160 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + altCommand = "DbgBreakConditionSet();"; + helpTag = "0"; + historySize = "0"; + }; + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 68"; + extent = "57 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Pass Count:"; + }; + new GuiTextEditCtrl(BreakPassCount) { + profile = "GuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 84"; + extent = "160 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + historySize = "0"; + returnTab = "true"; + }; + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 108"; + extent = "27 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Clear:"; + }; + new GuiTextEditCtrl(BreakClear) { + profile = "GuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 124"; + extent = "160 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + historySize = "0"; + returnTab = "true"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "56 156"; + extent = "40 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "DbgBreakConditionSet();"; + helpTag = "0"; + text = "Set"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "104 156"; + extent = "40 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "Canvas.popDialog(DebuggerBreakConditionDlg);"; + helpTag = "0"; + text = "Cancel"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/debugger/gui/connectDlg.ed.gui b/Templates/Empty/game/tools/debugger/gui/connectDlg.ed.gui new file mode 100644 index 000000000..1c1fcbc25 --- /dev/null +++ b/Templates/Empty/game/tools/debugger/gui/connectDlg.ed.gui @@ -0,0 +1,148 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(DebuggerConnectDlg, EditorGuiGroup) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + + new GuiWindowCtrl() { + profile = "GuiWindowProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "220 146"; + extent = "200 188"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Connect to server:"; + resizeWidth = "True"; + resizeHeight = "True"; + canMove = "False"; + canClose = "False"; + canMinimize = "False"; + canMaximize = "False"; + minSize = "50 50"; + + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 28"; + extent = "55 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "IP Address:"; + }; + new GuiTextEditCtrl(DebuggerConnectAddress) { + profile = "GuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 44"; + extent = "160 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + variable = "$pref::DBGConnectAddress"; + helpTag = "0"; + historySize = "0"; + returnTab = "true"; + }; + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 68"; + extent = "21 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Port:"; + }; + new GuiTextEditCtrl(DebuggerConnectPort) { + profile = "GuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 84"; + extent = "160 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + variable = "$pref::DBGConnectPort"; + helpTag = "0"; + historySize = "0"; + returnTab = "true"; + }; + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 108"; + extent = "52 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Password:"; + }; + new GuiTextEditCtrl(DebuggerConnectPassword) { + profile = "GuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 124"; + extent = "160 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + variable = "$pref::DBGConnectPassword"; + helpTag = "0"; + historySize = "0"; + returnTab = "true"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "56 156"; + extent = "40 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "DbgConnect();"; + helpTag = "0"; + text = "Open"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "104 156"; + extent = "40 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "Canvas.popDialog(DebuggerConnectDlg);"; + helpTag = "0"; + text = "Cancel"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/debugger/gui/debugger.ed.gui b/Templates/Empty/game/tools/debugger/gui/debugger.ed.gui new file mode 100644 index 000000000..03a03803e --- /dev/null +++ b/Templates/Empty/game/tools/debugger/gui/debugger.ed.gui @@ -0,0 +1,583 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(DebuggerGui, EditorGuiGroup) { + profile = "GuiWindowProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "8 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "Canvas.pushDialog(DebuggerConnectDlg, 80);"; + helpTag = "0"; + text = "Connect"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "72 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "Canvas.pushDialog(OpenFileDialog, 80);"; + helpTag = "0"; + text = "File"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "72 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "dbgStepIn();"; + accelerator = "f7"; + helpTag = "0"; + text = "Step In"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "136 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "dbgStepOver();"; + accelerator = "f8"; + helpTag = "0"; + text = "Step Over"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "200 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "dbgStepOut();"; + accelerator = "f6"; + helpTag = "0"; + text = "Step Out"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "264 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "dbgContinue();"; + accelerator = "f9"; + helpTag = "0"; + text = "Run"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "328 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "Canvas.pushDialog(DebuggerFindDlg, 80);"; + helpTag = "0"; + text = "Find"; + }; + new GuiTextCtrl(DebuggerCursorWatch) { + profile = "GuiTextProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "398 4"; + extent = "126 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = ""; + justify = "left"; + }; + new GuiTextCtrl(DebuggerStatus) { + profile = "GuiTextProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "532 4"; + extent = "100 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "NOT CONNECTED"; + justify = "right"; + }; + new GuiFrameSetCtrl(DebuggerRootFrame) { + profile = "GuiContentProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 24"; + extent = "640 456"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + columns = "0 486"; + rows = "0"; + borderWidth = "4"; + borderEnable = "dynamic"; + borderMovable = "dynamic"; + + new GuiFrameSetCtrl(DebuggerLeftFrame) { + profile = "GuiContentProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "482 456"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + columns = "0"; + rows = "0 350"; + borderWidth = "4"; + borderEnable = "dynamic"; + borderMovable = "dynamic"; + + new GuiControl() { + profile = "GuiDefaultProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "482 346"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "True"; + modal = "True"; + helpTag = "0"; + + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "8 4"; + extent = "47 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Open File:"; + }; + new GuiPopUpMenuCtrl(DebuggerFilePopup) { + profile = "GuiPopUpMenuProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "64 4"; + extent = "160 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "True"; + modal = "True"; + helpTag = "0"; + maxPopupHeight = "200"; + }; + new GuiScrollCtrl() { + profile = "GuiScrollProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 24"; + extent = "482 321"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + willFirstRespond = "True"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "false"; + lockVertScroll = "false"; + constantThumbHeight = "False"; + + new DbgFileView(DebuggerFileView) { + profile = "GuiTextArrayProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 -433"; + extent = "509 3904"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + }; + }; + }; + new GuiControl() { + profile = "GuiWindowProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 350"; + extent = "482 106"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "8 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "Canvas.pushDialog(DebuggerWatchDlg, 80);"; + helpTag = "0"; + text = "Add"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "72 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "Canvas.pushDialog(DebuggerEditWatchDlg, 80);"; + helpTag = "0"; + text = "Edit"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "136 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "DbgDeleteSelectedWatch();"; + helpTag = "0"; + text = "Delete"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "200 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "DebuggerWatchView.clear();"; + helpTag = "0"; + text = "Clear"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "264 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "DbgRefreshWatches();"; + helpTag = "0"; + text = "Refresh"; + }; + new GuiScrollCtrl() { + profile = "GuiScrollProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 24"; + extent = "481 80"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + willFirstRespond = "True"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "false"; + lockVertScroll = "false"; + constantThumbHeight = "False"; + + new GuiTextListCtrl(DebuggerWatchView) { + profile = "GuiTextListProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 8"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + enumerate = "False"; + resizeCell = "True"; + columns = "0 200"; + }; + }; + }; + }; + new GuiFrameSetCtrl(DebuggerRightFrame) { + profile = "GuiContentProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "486 0"; + extent = "154 456"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + columns = "0"; + rows = "0 150 350"; + borderWidth = "4"; + borderEnable = "dynamic"; + borderMovable = "dynamic"; + + new GuiScrollCtrl() { + profile = "GuiScrollProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "154 146"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + willFirstRespond = "True"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "false"; + lockVertScroll = "false"; + constantThumbHeight = "False"; + + new GuiTextListCtrl(DebuggerCallStack) { + profile = "GuiTextListProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 8"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + enumerate = "False"; + resizeCell = "True"; + columns = "-1 -1 0"; + }; + }; + new GuiControl() { + profile = "GuiWindowProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 150"; + extent = "154 196"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "Canvas.pushDialog(DebuggerBreakConditionDlg, 80);"; + helpTag = "0"; + text = "Condition"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "68 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "DbgDeleteSelectedBreak();"; + helpTag = "0"; + text = "Delete"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "132 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "DebuggerBreakPoints.clearBreaks();"; + helpTag = "0"; + text = "Clear"; + }; + new GuiScrollCtrl() { + profile = "GuiScrollProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 24"; + extent = "153 171"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + willFirstRespond = "True"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "false"; + lockVertScroll = "false"; + constantThumbHeight = "False"; + + new GuiTextListCtrl(DebuggerBreakPoints) { + profile = "GuiTextListProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "182 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + enumerate = "False"; + resizeCell = "True"; + columns = "16 56 156"; + }; + }; + }; + new GuiControl() { + profile = "GuiWindowProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 350"; + extent = "154 106"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + + new GuiScrollCtrl() { + profile = "GuiScrollProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "153 80"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + willFirstRespond = "True"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "false"; + lockVertScroll = "false"; + constantThumbHeight = "False"; + + new GuiTextListCtrl(DebuggerConsoleView) { + profile = "GuiTextListProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "62 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + enumerate = "False"; + resizeCell = "True"; + columns = "0"; + }; + }; + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "15 83"; + extent = "9 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "%"; + }; + new GuiTextEditCtrl(DbgConsoleEntry) { + profile = "GuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "top"; + position = "29 83"; + extent = "120 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + altCommand = "DbgConsoleEntryReturn();"; + helpTag = "0"; + historySize = "32"; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/debugger/gui/editWatchDlg.ed.gui b/Templates/Empty/game/tools/debugger/gui/editWatchDlg.ed.gui new file mode 100644 index 000000000..f7df9abf1 --- /dev/null +++ b/Templates/Empty/game/tools/debugger/gui/editWatchDlg.ed.gui @@ -0,0 +1,93 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(DebuggerEditWatchDlg, EditorGuiGroup) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + + new GuiWindowCtrl() { + profile = "GuiWindowProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "220 180"; + extent = "200 108"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Edit a Variable"; + resizeWidth = "True"; + resizeHeight = "True"; + canMove = "False"; + canClose = "False"; + canMinimize = "False"; + canMaximize = "False"; + minSize = "50 50"; + + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 28"; + extent = "99 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Enter the new value:"; + }; + new GuiTextEditCtrl(EditWatchDialogValue) { + profile = "GuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 44"; + extent = "160 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + altCommand = "DbgWatchDialogEdit();"; + helpTag = "0"; + historySize = "0"; + fontHL = "14 253 Arial"; + font = "14 244 Arial"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "56 80"; + extent = "40 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "DbgWatchDialogEdit();"; + helpTag = "0"; + text = "Edit"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "104 80"; + extent = "40 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "Canvas.popDialog(DebuggerEditWatchDlg);"; + helpTag = "0"; + text = "Cancel"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/debugger/gui/findDlg.ed.gui b/Templates/Empty/game/tools/debugger/gui/findDlg.ed.gui new file mode 100644 index 000000000..d60b832a8 --- /dev/null +++ b/Templates/Empty/game/tools/debugger/gui/findDlg.ed.gui @@ -0,0 +1,93 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(DebuggerFindDlg, EditorGuiGroup) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + + new GuiWindowCtrl() { + profile = "GuiWindowProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "220 180"; + extent = "200 108"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "File Search"; + resizeWidth = "True"; + resizeHeight = "True"; + canMove = "False"; + canClose = "False"; + canMinimize = "False"; + canMaximize = "False"; + minSize = "50 50"; + + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 28"; + extent = "99 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Search for:"; + }; + new GuiTextEditCtrl(DebuggerFindStringText) { + profile = "GuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 44"; + extent = "160 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + altCommand = "DbgFileViewFind();"; + helpTag = "0"; + historySize = "0"; + fontHL = "14 253 Arial"; + font = "14 244 Arial"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "56 80"; + extent = "40 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "DbgFileViewFind();"; + helpTag = "0"; + text = "Find"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "104 80"; + extent = "40 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "Canvas.popDialog(DebuggerFindDlg);"; + helpTag = "0"; + text = "Cancel"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/debugger/gui/watchDlg.ed.gui b/Templates/Empty/game/tools/debugger/gui/watchDlg.ed.gui new file mode 100644 index 000000000..7ce14b233 --- /dev/null +++ b/Templates/Empty/game/tools/debugger/gui/watchDlg.ed.gui @@ -0,0 +1,92 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(DebuggerWatchDlg, EditorGuiGroup) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + + new GuiWindowCtrl() { + profile = "GuiWindowProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "220 180"; + extent = "200 108"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Add a Watch Expression:"; + resizeWidth = "True"; + resizeHeight = "True"; + canMove = "False"; + canClose = "False"; + canMinimize = "False"; + canMaximize = "False"; + minSize = "50 50"; + opaque = "true"; + + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 28"; + extent = "88 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Enter the Variable:"; + }; + new GuiTextEditCtrl(WatchDialogExpression) { + profile = "GuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 44"; + extent = "160 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + altCommand = "DbgWatchDialogAdd();"; + helpTag = "0"; + historySize = "0"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "56 80"; + extent = "40 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "DbgWatchDialogAdd();"; + helpTag = "0"; + text = "Add"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "104 80"; + extent = "40 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "Canvas.popDialog(DebuggerWatchDlg);"; + helpTag = "0"; + text = "Cancel"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/debugger/main.cs b/Templates/Empty/game/tools/debugger/main.cs new file mode 100644 index 000000000..8fad76509 --- /dev/null +++ b/Templates/Empty/game/tools/debugger/main.cs @@ -0,0 +1,68 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//--------------------------------------------------------------------------------------------- +// TCP Debugger +// To use the debugger, first call "dbgSetParameters(port, password);" from one instance of +// your game. Then, in another instance (either on the same system, or a different one) call +// "startDebugger();". Then use the gui to connect to the first instance with the port and +// password you first passed to dbgSetParameters. +//--------------------------------------------------------------------------------------------- + +function initializeDebugger() +{ + echo(" % - Initializing Debugger"); + + // Load the scripts. + exec("./Scripts/debugger.ed.cs"); + + // And the guis. + exec("./Gui/breakConditionDlg.ed.gui"); + exec("./Gui/connectDlg.ed.gui"); + exec("./Gui/editWatchDlg.ed.gui"); + exec("./Gui/findDlg.ed.gui"); + exec("./Gui/debugger.ed.gui"); + exec("./Gui/watchDlg.ed.gui"); +} + +function destroyDebugger() +{ + if (isObject(TCPDebugger)) + TCPDebugger.delete(); +} + +function startDebugger() +{ + // Clean up first. + destroyDebugger(); + + // Create a TCP object named TCPDebugger. + new TCPObject(TCPDebugger); + + // Used to get unique IDs for breakpoints and watch expressions. + $DbgBreakId = 0; + $DbgWatchSeq = 1; + + // Set up the GUI. + DebuggerConsoleView.setActive(false); + Canvas.pushDialog(DebuggerGui); +} diff --git a/Templates/Empty/game/tools/debugger/scripts/debugger.ed.cs b/Templates/Empty/game/tools/debugger/scripts/debugger.ed.cs new file mode 100644 index 000000000..408de29eb --- /dev/null +++ b/Templates/Empty/game/tools/debugger/scripts/debugger.ed.cs @@ -0,0 +1,508 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//--------------------------------------------------------------------------------------------- +// onLine is invoked whenever the TCP object receives a line from the server. Treat the first +// word as a "command" and dispatch to an appropriate handler. +//--------------------------------------------------------------------------------------------- +function TCPDebugger::onLine(%this, %line) +{ + echo("Got line=>" @ %line); + %cmd = firstWord(%line); + %rest = restWords(%line); + + if (%cmd $= "PASS") { + %this.handlePass(%rest); + } + else if(%cmd $= "COUT") { + %this.handleLineOut(%rest); + } + else if(%cmd $= "FILELISTOUT") { + %this.handleFileList(%rest); + } + else if(%cmd $= "BREAKLISTOUT") { + %this.handleBreakList(%rest); + } + else if(%cmd $= "BREAK") { + %this.handleBreak(%rest); + } + else if(%cmd $= "RUNNING") { + %this.handleRunning(); + } + else if(%cmd $= "EVALOUT") { + %this.handleEvalOut(%rest); + } + else { + %this.handleError(%line); + } +} + +// Handler for PASS response. +function TCPDebugger::handlePass(%this, %message) +{ + if (%message $= "WrongPass") { + DebuggerConsoleView.print("Disconnected - wrong password."); + %this.disconnect(); + } + else if(%message $= "Connected.") { + DebuggerConsoleView.print("Connected."); + DebuggerStatus.setValue("CONNECTED"); + %this.send("FILELIST\r\n"); + } +} + +// Handler for COUT response. +function TCPDebugger::handleLineOut(%this, %line) +{ + DebuggerConsoleView.print(%line); +} + +// Handler for FILELISTOUT response. +function TCPDebugger::handleFileList(%this, %line) +{ + DebuggerFilePopup.clear(); + %word = 0; + while ((%file = getWord(%line, %word)) !$= "") { + %word++; + DebuggerFilePopup.add(%file, %word); + } +} + +// Handler for BREAKLISTOUT response. +function TCPDebugger::handleBreakList(%this, %line) +{ + %file = getWord(%line, 0); + if (%file != $DebuggerFile) { + return; + } + %pairs = getWord(%line, 1); + %curLine = 1; + DebuggerFileView.clearBreakPositions(); + + // Set the possible break positions. + for (%i = 0; %i < %pairs; %i++) { + %skip = getWord(%line, %i * 2 + 2); + %breaks = getWord(%line, %i * 2 + 3); + %curLine += %skip; + for (%j = 0; %j < %breaks; %j++) { + DebuggerFileView.setBreakPosition(%curLine); + %curLine++; + } + } + + // Now set the actual break points. + for (%i = 0; %i < DebuggerBreakPoints.rowCount(); %i++) { + %breakText = DebuggerBreakPoints.getRowText(%i); + %breakLine = getField(%breakText, 0); + %breakFile = getField(%breakText, 1); + if (%breakFile == $DebuggerFile) { + DebuggerFileView.setBreak(%breakLine); + } + } +} + +// Handler for BREAK response. +function TCPDebugger::handleBreak(%this, %line) +{ + DebuggerStatus.setValue("BREAK"); + + // Query all the watches. + for (%i = 0; %i < DebuggerWatchView.rowCount(); %i++) { + %id = DebuggerWatchView.getRowId(%i); + %row = DebuggerWatchView.getRowTextById(%id); + %expr = getField(%row, 0); + %this.send("EVAL " @ %id @ " 0 " @ %expr @ "\r\n"); + } + + // Update the call stack window. + DebuggerCallStack.clear(); + + %file = getWord(%line, 0); + %lineNumber = getWord(%line, 1); + %funcName = getWord(%line, 2); + + DbgOpenFile(%file, %lineNumber, true); + + %nextWord = 3; + %rowId = 0; + %id = 0; + while(1) { + DebuggerCallStack.setRowById(%id, %file @ "\t" @ %lineNumber @ "\t" @ %funcName); + %id++; + %file = getWord(%line, %nextWord); + %lineNumber = getWord(%line, %nextWord + 1); + %funcName = getWord(%line, %nextWord + 2); + %nextWord += 3; + if (%file $= "") { + break; + } + } +} + +// Handler for RUNNING response. +function TCPDebugger::handleRunning(%this) +{ + DebuggerFileView.setCurrentLine(-1, true); + DebuggerCallStack.clear(); + DebuggerStatus.setValue("RUNNING..."); +} + +// Handler for EVALOUT response. +function TCPDebugger::handleEvalOut(%this, %line) +{ + %id = firstWord(%line); + %value = restWords(%line); + + // See if it's the cursor watch, or from the watch window. + if (%id < 0) { + DebuggerCursorWatch.setText(DebuggerCursorWatch.expr SPC "=" SPC %value); + } + else { + %row = DebuggerWatchView.getRowTextById(%id); + if (%row $= "") { + return; + } + %expr = getField(%row, 0); + DebuggerWatchView.setRowById(%id, %expr @ "\t" @ %value); + } +} + +// Handler for unrecognized response. +function TCPDebugger::handleError(%this, %line) +{ + DebuggerConsoleView.print("ERROR - bogus message: " @ %line); +} + +// Print a line of response from the server. +function DebuggerConsoleView::print(%this, %line) +{ + %row = %this.addRow(0, %line); + %this.scrollVisible(%row); +} + +// When entry in file list selected, open the file. +function DebuggerFilePopup::onSelect(%this, %id, %text) +{ + DbgOpenFile(%text, 0, false); +} + +// When entry on call stack selected, open the file and go to the line. +function DebuggerCallStack::onAction(%this) +{ + %id = %this.getSelectedId(); + if (%id == -1) { + return; + } + %text = %this.getRowTextById(%id); + %file = getField(%text, 0); + %line = getField(%text, 1); + + DbgOpenFile(%file, %line, %id == 0); +} + +// Add a breakpoint at the selected spot, if it doesn't already exist. +function DebuggerBreakPoints::addBreak(%this, %file, %line, %clear, %passct, %expr) +{ + // columns 0 = line, 1 = file, 2 = expr + %textLine = %line @ "\t" @ %file @ "\t" @ %expr @ "\t" @ %passct @ "\t" @ %clear; + %selId = %this.getSelectedId(); + %selText = %this.getRowTextById(%selId); + if ((getField(%selText, 0) $= %line) && (getField(%selText, 1) $= %file)) { + %this.setRowById(%selId, %textLine); + } + else { + %this.addRow($DbgBreakId, %textLine); + $DbgBreakId++; + } +} + +// Remove the selected breakpoint. +function DebuggerBreakPoints::removeBreak(%this, %file, %line) +{ + for (%i = 0; %i < %this.rowCount(); %i++) { + %id = %this.getRowId(%i); + %text = %this.getRowTextById(%id); + if ((getField(%text, 0) $= %line) && (getField(%text, 1) $= %file)) { + %this.removeRowById(%id); + return; + } + } +} + +// Remove all breakpoints. +function DebuggerBreakPoints::clearBreaks(%this) +{ + while (%this.rowCount()) { + %id = %this.getRowId(0); + %text = %this.getRowTextById(%id); + %file = getField(%text, 1); + %line = getField(%text, 0); + DbgRemoveBreakPoint(%file, %line); + } +} + +// Go to file & line for the selected breakpoint. +function DebuggerBreakPoints::onAction(%this) +{ + %id = %this.getSelectedId(); + if (%id == -1) { + return; + } + %text = %this.getRowTextById(%id); + %line = getField(%text, 0); + %file = getField(%text, 1); + + DbgOpenFile(%file, %line, false); +} + +// Handle breakpoint removal executed from the file-view GUI. +function DebuggerFileView::onRemoveBreakPoint(%this, %line) +{ + %file = $DebuggerFile; + DbgRemoveBreakPoint(%file, %line); +} + +// Handle breakpoint addition executed from the file-view GUI. +function DebuggerFileView::onSetBreakPoint(%this, %line) +{ + %file = $DebuggerFile; + DbgSetBreakPoint(%file, %line, 0, 0, true); +} + +//--------------------------------------------------------------------------------------------- +// Various support functions. +//--------------------------------------------------------------------------------------------- + +// Add a watch expression. +function DbgWatchDialogAdd() +{ + %expr = WatchDialogExpression.getValue(); + if (%expr !$= "") { + DebuggerWatchView.setRowById($DbgWatchSeq, %expr @"\t(unknown)"); + TCPDebugger.send("EVAL " @ $DbgWatchSeq @ " 0 " @ %expr @ "\r\n"); + $DbgWatchSeq++; + } + Canvas.popDialog(DebuggerWatchDlg); +} + +// Edit a watch expression. +function DbgWatchDialogEdit() +{ + %newValue = EditWatchDialogValue.getValue(); + %id = DebuggerWatchView.getSelectedId(); + if (%id >= 0) { + %row = DebuggerWatchView.getRowTextById(%id); + %expr = getField(%row, 0); + if (%newValue $= "") { + %assignment = %expr @ " = \"\""; + } + else { + %assignment = %expr @ " = " @ %newValue; + } + TCPDebugger.send("EVAL " @ %id @ " 0 " @ %assignment @ "\r\n"); + } + Canvas.popDialog(DebuggerEditWatchDlg); +} + +// Set/change the singular "cursor watch" expression. +function DbgSetCursorWatch(%expr) +{ + DebuggerCursorWatch.expr = %expr; + if (DebuggerCursorWatch.expr $= "") { + DebuggerCursorWatch.setText(""); + } + else { + TCPDebugger.send("EVAL -1 0 " @ DebuggerCursorWatch.expr @ "\r\n"); + } +} + +// Connect to the server with the given addr/port/password. +function DbgConnect() +{ + %address = DebuggerConnectAddress.getValue(); + %port = DebuggerConnectPort.getValue(); + %password = DebuggerConnectPassword.getValue(); + + if ((%address !$= "" ) && (%port !$= "" ) && (%password !$= "" )) { + TCPDebugger.connect(%address @ ":" @ %port); + TCPDebugger.schedule(5000, send, %password @ "\r\n"); + TCPDebugger.password = %password; + } + + Canvas.popDialog(DebuggerConnectDlg); +} + +// Put a condition on a breakpoint. +function DbgBreakConditionSet() +{ + // Read the condition. + %condition = BreakCondition.getValue(); + %passct = BreakPassCount.getValue(); + %clear = BreakClear.getValue(); + if (%condition $= "") { + %condition = "true"; + } + if (%passct $= "") { + %passct = "0"; + } + if (%clear $= "") { + %clear = "false"; + } + + // Set the condition. + %id = DebuggerBreakPoints.getSelectedId(); + if (%id != -1) { + %bkp = DebuggerBreakPoints.getRowTextById(%id); + DbgSetBreakPoint(getField(%bkp, 1), getField(%bkp, 0), %clear, %passct, %condition); + } + + Canvas.popDialog(DebuggerBreakConditionDlg); +} + +// Open a file, go to the indicated line, and optionally select the line. +function DbgOpenFile(%file, %line, %selectLine) +{ + if (%file !$= "") { + // Open the file in the file view. + if (DebuggerFileView.open(%file)) { + // Go to the line. + DebuggerFileView.setCurrentLine(%line, %selectLine); + // Get the breakpoints for this file. + if (%file !$= $DebuggerFile) { + TCPDebugger.send("BREAKLIST " @ %file @ "\r\n"); + $DebuggerFile = %file; + } + } + } +} + +// Search in the fileview GUI. +function DbgFileViewFind() +{ + %searchString = DebuggerFindStringText.getValue(); + DebuggerFileView.findString(%searchString); + + Canvas.popDialog(DebuggerFindDlg); +} + +// Set a breakpoint, optionally with condition. +function DbgSetBreakPoint(%file, %line, %clear, %passct, %expr) +{ + if (!%clear) { + if (%file == $DebuggerFile) { + DebuggerFileView.setBreak(%line); + } + } + DebuggerBreakPoints.addBreak(%file, %line, %clear, %passct, %expr); + TCPDebugger.send("BRKSET " @ %file @ " " @ %line @ " " @ %clear @ " " @ %passct @ " " @ %expr @ "\r\n"); +} + +// Remove a breakpoint. +function DbgRemoveBreakPoint(%file, %line) +{ + if (%file == $DebuggerFile) { + DebuggerFileView.removeBreak(%line); + } + TCPDebugger.send("BRKCLR " @ %file @ " " @ %line @ "\r\n"); + DebuggerBreakPoints.removeBreak(%file, %line); +} + +// Remove whatever breakpoint is selected in the breakpoints GUI. +function DbgDeleteSelectedBreak() +{ + %selectedBreak = DebuggerBreakPoints.getSelectedId(); + %rowNum = DebuggerBreakPoints.getRowNumById(%selectedWatch); + if (%rowNum >= 0) { + %breakText = DebuggerBreakPoints.getRowText(%rowNum); + %breakLine = getField(%breakText, 0); + %breakFile = getField(%breakText, 1); + DbgRemoveBreakPoint(%breakFile, %breakLine); + } +} + +// Send an expression to the server for evaluation. +function DbgConsoleEntryReturn() +{ + %msg = DbgConsoleEntry.getValue(); + if (%msg !$= "") { + DebuggerConsoleView.print("%" @ %msg); + if (DebuggerStatus.getValue() $= "NOT CONNECTED") { + DebuggerConsoleView.print("*** Not connected."); + } + else if (DebuggerStatus.getValue() $= "BREAK") { + DebuggerConsoleView.print("*** Target is in BREAK mode."); + } + else { + TCPDebugger.send("CEVAL " @ %msg @ "\r\n"); + } + } + DbgConsoleEntry.setValue(""); +} + +// Print a line from the server. +function DbgConsolePrint(%status) +{ + DebuggerConsoleView.print(%status); +} + +// Delete the currently selected watch expression. +function DbgDeleteSelectedWatch() +{ + %selectedWatch = DebuggerWatchView.getSelectedId(); + %rowNum = DebuggerWatchView.getRowNumById(%selectedWatch); + DebuggerWatchView.removeRow(%rowNum); +} + +// Evaluate all the watch expressions. +function DbgRefreshWatches() +{ + for (%i = 0; %i < DebuggerWatchView.rowCount(); %i++) { + %id = DebuggerWatchView.getRowId(%i); + %row = DebuggerWatchView.getRowTextById(%id); + %expr = getField(%row, 0); + TCPDebugger.send("EVAL " @ %id @ " 0 " @ %expr @ "\r\n"); + } +} + +//--------------------------------------------------------------------------------------------- +// Incremental execution functions +// These just send commands to the server. +//--------------------------------------------------------------------------------------------- +function dbgStepIn() +{ + TCPDebugger.send("STEPIN\r\n"); +} + +function dbgStepOut() +{ + TCPDebugger.send("STEPOUT\r\n"); +} + +function dbgStepOver() +{ + TCPDebugger.send("STEPOVER\r\n"); +} + +function dbgContinue() +{ + TCPDebugger.send("CONTINUE\r\n"); +} diff --git a/Templates/Empty/game/tools/decalEditor/add-decal_d.png b/Templates/Empty/game/tools/decalEditor/add-decal_d.png new file mode 100644 index 000000000..5e45b78ce Binary files /dev/null and b/Templates/Empty/game/tools/decalEditor/add-decal_d.png differ diff --git a/Templates/Empty/game/tools/decalEditor/add-decal_h.png b/Templates/Empty/game/tools/decalEditor/add-decal_h.png new file mode 100644 index 000000000..4fd3f4e28 Binary files /dev/null and b/Templates/Empty/game/tools/decalEditor/add-decal_h.png differ diff --git a/Templates/Empty/game/tools/decalEditor/add-decal_n.png b/Templates/Empty/game/tools/decalEditor/add-decal_n.png new file mode 100644 index 000000000..7aa1ad2c9 Binary files /dev/null and b/Templates/Empty/game/tools/decalEditor/add-decal_n.png differ diff --git a/Templates/Empty/game/tools/decalEditor/decal-editor_d.png b/Templates/Empty/game/tools/decalEditor/decal-editor_d.png new file mode 100644 index 000000000..78fdcd6c3 Binary files /dev/null and b/Templates/Empty/game/tools/decalEditor/decal-editor_d.png differ diff --git a/Templates/Empty/game/tools/decalEditor/decal-editor_h.png b/Templates/Empty/game/tools/decalEditor/decal-editor_h.png new file mode 100644 index 000000000..f83cbe4a9 Binary files /dev/null and b/Templates/Empty/game/tools/decalEditor/decal-editor_h.png differ diff --git a/Templates/Empty/game/tools/decalEditor/decal-editor_n.png b/Templates/Empty/game/tools/decalEditor/decal-editor_n.png new file mode 100644 index 000000000..b94023007 Binary files /dev/null and b/Templates/Empty/game/tools/decalEditor/decal-editor_n.png differ diff --git a/Templates/Empty/game/tools/decalEditor/decalEditor.cs b/Templates/Empty/game/tools/decalEditor/decalEditor.cs new file mode 100644 index 000000000..b861d8694 --- /dev/null +++ b/Templates/Empty/game/tools/decalEditor/decalEditor.cs @@ -0,0 +1,33 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +/* +function doUtil() +{ + for ( %i = 0; %i < DecalDataSet.getCount(); %i++ ) + { + %obj = DecalDataSet.getObject(%i); + %obj.internalName = %obj.getName(); + DecalPMan.setDirty( %obj ); + } +} +*/ \ No newline at end of file diff --git a/Templates/Empty/game/tools/decalEditor/decalEditorActions.cs b/Templates/Empty/game/tools/decalEditor/decalEditorActions.cs new file mode 100644 index 000000000..b65fb3000 --- /dev/null +++ b/Templates/Empty/game/tools/decalEditor/decalEditorActions.cs @@ -0,0 +1,122 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function DecalEditorGui::createAction(%this, %class, %desc) +{ + pushInstantGroup(); + %action = new UndoScriptAction() + { + class = %class; + superClass = BaseDecalEdAction; + actionName = %desc; + tree = DecalEditorTreeView; + }; + popInstantGroup(); + return %action; +} + +function DecalEditorGui::doAction(%this, %action) +{ + if (%action.doit()) + %action.addToManager(Editor.getUndoManager()); +} + +function BaseDecalEdAction::redo(%this) +{ + // Default redo action is the same as the doit action + %this.doit(); +} + +function BaseDecalEdAction::undo(%this) +{ +} + +//------------------------------------------------------------------------------ +// Edit node +function DecalEditorGui::doEditNodeDetails(%this, %instanceId, %transformData, %gizmo) +{ + %action = %this.createAction(ActionEditNodeDetails, "Edit Decal Transform"); + %action.instanceId = %instanceId; + %action.newTransformData = %transformData; + + if( %gizmo ) + %action.oldTransformData = %this.gizmoDetails; + else + %action.oldTransformData = %this.getDecalTransform(%instanceId); + + %this.doAction(%action); +} + +function ActionEditNodeDetails::doit(%this) +{ + %count = getWordCount(%this.newTransformData); + if(%this.instanceId !$= "" && %count == 7) + { + DecalEditorGui.editDecalDetails( %this.instanceId, %this.newTransformData ); + DecalEditorGui.syncNodeDetails(); + DecalEditorGui.selectDecal( %this.instanceId ); + return true; + } + return false; +} + +function ActionEditNodeDetails::undo(%this) +{ + %count = getWordCount(%this.oldTransformData); + if(%this.instanceId !$= "" && %count == 7) + { + DecalEditorGui.editDecalDetails( %this.instanceId, %this.oldTransformData ); + DecalEditorGui.syncNodeDetails(); + DecalEditorGui.selectDecal( %this.instanceId ); + } +} + +//------------------------------------------------------------------------------ +// Delete Decal Datablocks + +// This functionality solely depends on the undo/redo datablock callbacks in +// source. + +function DecalEditorGui::redoDeleteDecalDatablock( %this, %datablock ) +{ + // Remove the object from file and place a filter + if( %datablock.getFilename() !$= "" ) + { + DecalPMan.removeDirty( %datablock ); + DecalPMan.removeObjectFromFile( %datablock ); + } + + DecalDataList.addFilteredItem( %datablock ); +} + +function DecalEditorGui::undoDeleteDecalDatablock( %this, %datablock ) +{ + // Replace the object in file and remove the filter + %filename = %datablock.getFilename(); + if( %datablock.getFilename() !$= "" ) + { + DecalPMan.setDirty( %datablock, %filename ); + DecalPMan.saveDirty(); + } + + DecalDataList.removeFilteredItem( %datablock ); +} diff --git a/Templates/Empty/game/tools/decalEditor/decalEditorGui.cs b/Templates/Empty/game/tools/decalEditor/decalEditorGui.cs new file mode 100644 index 000000000..cfcd3b7b9 --- /dev/null +++ b/Templates/Empty/game/tools/decalEditor/decalEditorGui.cs @@ -0,0 +1,343 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function DecalEditorGui::onWake( %this ) +{ +} + +function DecalEditorGui::onSelectInstance( %this, %decalId, %lookupName ) +{ + if( DecalEditorGui.selDecalInstanceId == %decalId ) + return; + // Lets remember the new Id + DecalEditorGui.selDecalInstanceId = %decalId; + DecalEditorTreeView.clearSelection(); + + %name = %decalId SPC %lookupName; + %item = DecalEditorTreeView.findItemByName( %name ); + DecalEditorTreeView.selectItem( %item ); + DecalEditorGui.syncNodeDetails(); +} + +function DecalEditorGui::onCreateInstance( %this, %decalId, %lookupName ) +{ + // Lets remember the new Id + DecalEditorGui.selDecalInstanceId = %decalId; + + // Add the new instance to the node tree + DecalEditorTreeView.addNodeTree( %decalId, %lookupName ); + DecalEditorTreeView.clearSelection(); + + %name = %decalId SPC %lookupName; + %item = DecalEditorTreeView.findItemByName( %name ); + DecalEditorTreeView.selectItem( %item ); + DecalEditorGui.syncNodeDetails(); +} + +function DecalEditorGui::onDeleteInstance( %this, %decalId, %lookupName ) +{ + if( %decalId == DecalEditorGui.selDecalInstanceId ) + DecalEditorGui.selDecalInstanceId = -1; + + %id = DecalEditorTreeView.findItemByName( %decalId SPC %lookupName ); + DecalEditorTreeView.removeItem(%id); +} + +function DecalEditorGui::editNodeDetails( %this ) +{ + %decalId = DecalEditorGui.selDecalInstanceId; + if( %decalId == -1 ) + return; + + %nodeDetails = DecalEditorDetailContainer-->nodePosition.getText(); + %nodeDetails = %nodeDetails @ " " @ DecalEditorDetailContainer-->nodeTangent.getText(); + %nodeDetails = %nodeDetails @ " " @ DecalEditorDetailContainer-->nodeSize.getText(); + + if( getWordCount(%nodeDetails) == 7 ) + DecalEditorGui.doEditNodeDetails( %decalId, %nodeDetails, false ); + +} + +// Stores the information when the gizmo is first used +function DecalEditorGui::prepGizmoTransform( %this, %decalId, %nodeDetails ) +{ + DecalEditorGui.gizmoDetails = %nodeDetails; +} + +// Activated in onMouseUp while gizmo is dirty +function DecalEditorGui::completeGizmoTransform( %this, %decalId, %nodeDetails ) +{ + DecalEditorGui.doEditNodeDetails( %decalId, %nodeDetails, true ); +} + +function DecalEditorGui::onSleep( %this ) +{ +} + +function DecalEditorGui::syncNodeDetails( %this ) +{ + %decalId = DecalEditorGui.selDecalInstanceId; + if( %decalId == -1 ) + return; + + %lookupName = DecalEditorGui.getDecalLookupName( %decalId ); + DecalEditorGui.updateInstancePreview( %lookupName.material ); + + DecalEditorDetailContainer-->instanceId.setText(%decalId @ " " @ %lookupName); + %transformData = DecalEditorGui.getDecalTransform(%decalId); + DecalEditorDetailContainer-->nodePosition.setText(getWords(%transformData, 0, 2)); + DecalEditorDetailContainer-->nodeTangent.setText(getWords(%transformData, 3, 5)); + DecalEditorDetailContainer-->nodeSize.setText(getWord(%transformData, 6)); +} + +function DecalEditorGui::paletteSync( %this, %mode ) +{ + %evalShortcut = "ToolsPaletteArray-->" @ %mode @ ".setStateOn(1);"; + eval(%evalShortcut); +} + +function DecalDataList::onSelect( %this, %id, %text ) +{ + %obj = %this.getItemObject( %id ); + DecalEditorGui.currentDecalData = %obj; + + %itemNum = DecalDataList.getSelectedItem(); + if ( %itemNum == -1 ) + return; + + %data = DecalDataList.getItemObject( %itemNum ); + + // Update the materialEditorList + $Tools::materialEditorList = %data.getId(); + + //Canvas.pushDialog( DecalEditDlg ); + DecalInspector.inspect( %data ); + DecalEditorGui.updateDecalPreview( %data.material ); +} + +function RetargetDecalButton::onClick( %this ) +{ + %id = DecalDataList.getSelectedItem(); + %datablock = DecalDataList.getItemText(%id ); + + if( !isObject(%datablock) ) + { + MessageBoxOK("Error", "A valid Decal Template must be selected."); + return; + } + + // This is the first place IODropdown is used. The # in the function passed replaced with the output + // of the preset menu. + + IODropdown("Retarget Decal Instances", + "Retarget DecalInstances from " @ %datablock.getName() @ " over to....", + "decalDataSet", + "DecalEditorGui.retargetDecalDatablock(" @ %datablock.getName() @ ", #);", + ""); + DecalEditorGui.rebuildInstanceTree(); +} + +function NewDecalButton::onClick( %this ) +{ + %name = getUniqueName( "NewDecalData" ); + + %str = "datablock DecalData( " @ %name @ " ) { Material = \"WarningMaterial\"; };"; + eval( %str ); + + DecalPMan.setDirty( %name, $decalDataFile ); + + if ( strchr(LibraryTabControl.text, "*") $= "" ) + LibraryTabControl.text = LibraryTabControl.text @ "*"; + + DecalDataList.doMirror(); + %id = DecalDataList.findItemText( %name ); + DecalDataList.setSelected( %id, true ); + + Canvas.pushDialog( DecalEditDlg ); + DecalInspector.inspect( %name ); +} + +function DeleteDecalButton::onClick( %this ) +{ + + if( DecalEditorTabBook.getSelectedPage() == 0 ) // library + { + %id = DecalDataList.getSelectedItem(); + %datablock = DecalDataList.getItemText(%id ); + + MessageBoxYesNoCancel("Delete Decal Datablock?", + "Are you sure you want to delete

" @ %datablock @ "

Datablock deletion won't take affect until the engine is quit.", + "DecalEditorGui.deleteSelectedDecalDatablock();", + "", + "" ); + } + else // instances + { + DecalEditorGui.deleteSelectedDecal(); + } +} + +// Intended for gui use. The undo/redo functionality for deletion of datablocks +// will enable itself automatically after using this function. +function DecalEditorGui::deleteSelectedDecalDatablock() +{ + %id = DecalDataList.getSelectedItem(); + %datablock = DecalDataList.getItemText(%id ); + + DecalEditorGui.deleteDecalDatablock( %datablock ); + + if( %datablock.getFilename() !$= "" ) + { + DecalPMan.removeDirty( %datablock ); + DecalPMan.removeObjectFromFile( %datablock ); + } + + DecalDataList.addFilteredItem( %datablock ); +} + +function DecalEditorTabBook::onTabSelected( %this, %text, %idx ) +{ + if( %idx == 0) + { + DecalPreviewWindow.text = "Template Properties"; + DecalEditorLibraryProperties.setVisible(true); + DecalEditorTemplateProperties.setVisible(false); + RetargetDecalButton.setVisible( true ); + SaveDecalsButton.setVisible( true ); + NewDecalButton.setVisible( true ); + DeleteDecalButton.tabSelected = %idx; + } + else + { + DecalPreviewWindow.text = "Instance Properties"; + RetargetDecalButton.setVisible( false ); + NewDecalButton.setVisible( false ); + SaveDecalsButton.setVisible( false ); + DeleteDecalButton.tabSelected = %idx; + DecalEditorLibraryProperties.setVisible(false); + DecalEditorTemplateProperties.setVisible(true); + } +} + +function DecalEditorTreeView::onDefineIcons() +{ + %icons = "core/art/gui/images/treeview/default:" @ + "tools/classIcons/decal:" @ + "tools/classIcons/decalNode:"; + + DecalEditorTreeView.buildIconTable( %icons ); +} + +function DecalEditorTreeView::onSelect(%this, %id) +{ + %instanceTag = getWord( DecalEditorTreeView.getItemText(%id), 1 ); + if( !isObject( %instanceTag ) ) + return; + + if( %instanceTag.getClassName() !$= "DecalData" ) + return; + + // Grab the id from the tree view + %decalId = getWord( DecalEditorTreeView.getItemText(%id), 0 ); + + if( DecalEditorGui.selDecalInstanceId == %decalId ) + return; + + // Set the curent decalinstances id + DecalEditorGui.selDecalInstanceId = %decalId; + + DecalEditorGui.selectDecal(%decalId); + DecalEditorGui.syncNodeDetails(%id); +} + +// Creating per node in the instance tree +function DecalEditorTreeView::addNodeTree(%this, %nodeName, %parentName) +{ + // If my template isnt there...put it there + if ( %this.findItemByName(%parentName) == 0 ) + { + %rootId = %this.findItemByName(""); + %this.insertItem( %rootId, %parentName, 0, "", 1, 1); + } + + %nodeName = %nodeName SPC %parentName; + %parentId = %this.findItemByName(%parentName); + %id = %this.insertItem(%parentId, %nodeName, 0, "", 2); +} + +function DecalInspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ) +{ + if( %fieldName $= "Material" ) + DecalEditorGui.updateDecalPreview( %newValue ); + + // Same work to do as for the regular WorldEditor Inspector. + Inspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ); + + if (%oldValue != %newValue || %oldValue !$= %newValue) + %this.setDirty(%object); +} + +function DecalInspector::setDirty( %this, %object ) +{ + DecalPMan.setDirty( %object ); + + if ( strchr(LibraryTabControl.text, "*") $= "" ) + LibraryTabControl.text = LibraryTabControl.text @ "*"; +} + +function DecalInspector::removeDirty() +{ + if ( strchr(LibraryTabControl.text, "*") !$= "" ) + LibraryTabControl.text = stripChars(LibraryTabControl.text, "*"); +} + +function DecalEditorGui::updateDecalPreview( %this, %material ) +{ + if( isObject( %material ) ) + DecalPreviewWindow-->decalPreview.setBitmap( MaterialEditorGui.searchForTexture( %material.getId(), %material.diffuseMap[0]) ); + else + DecalPreviewWindow-->decalPreview.setBitmap("tools/materialeditor/gui/unknownImage"); +} + +function DecalEditorGui::updateInstancePreview( %this, %material ) +{ + if( isObject( %material ) ) + DecalPreviewWindow-->instancePreview.setBitmap( MaterialEditorGui.searchForTexture( %material.getId(), %material.diffuseMap[0]) ); + else + DecalPreviewWindow-->instancePreview.setBitmap("tools/materialeditor/gui/unknownImage"); +} + +function DecalEditorGui::rebuildInstanceTree( %this ) +{ + // Initialize the instance tree when the tab is selected + DecalEditorTreeView.removeItem(0); + %rootId = DecalEditorTreeView.insertItem(0, "", 0, ""); + %count = DecalEditorGui.getDecalCount(); + for (%i = 0; %i < %count; %i++) + { + %name = DecalEditorGui.getDecalLookupName(%i); + if( %name $= "invalid" ) + continue; + + DecalEditorTreeView.addNodeTree(%i, %name); + } +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/decalEditor/decalEditorGui.gui b/Templates/Empty/game/tools/decalEditor/decalEditorGui.gui new file mode 100644 index 000000000..ec2c5baa1 --- /dev/null +++ b/Templates/Empty/game/tools/decalEditor/decalEditorGui.gui @@ -0,0 +1,831 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiDecalEditorCtrl(DecalEditorGui) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "WorldEditorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + cameraZRot = "0"; + forceFOV = "0"; + renderMissionArea = "0"; + missionAreaFillColor = "255 0 0 20"; + missionAreaFrameColor = "255 0 0 128"; + allowBorderMove = "0"; + borderMovePixelSize = "20"; + borderMoveSpeed = "0.1"; + consoleFrameColor = "255 0 0 255"; + consoleFillColor = "255 0 0 120"; + consoleSphereLevel = "1"; + consoleCircleSegments = "32"; + consoleLineWidth = "1"; + GizmoProfile = "GlobalGizmoProfile"; + currentDecalID = "175"; + Docking = "None"; + + new GuiWindowCollapseCtrl(DecalEditorWindow) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 SPC getWord(EditorGuiToolbar.extent, 1) -1; + Extent = "210 600"; + MinExtent = "210 100"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "2 2 2 2"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "EditorGui.setEditor( WorldEditorInspectorPlugin );"; + EdgeSnap = "1"; + text = "Decal Editor"; + + new GuiTabBookCtrl(DecalEditorTabBook) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "202 502"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "3 1 3 3"; + Docking = "client"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + TabPosition = "Top"; + TabMargin = "0"; + MinTabWidth = "64"; + + new GuiTabPageCtrl(LibraryTabControl) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "EditorTabPage"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "202 483"; + Docking = "client"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "-1 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Library"; + maxLength = "1024"; + + new GuiContainer() { + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 483"; + Margin = "0 0 0 0"; + Docking = "client"; + MinExtent = "0 8"; + Profile = "GuiInspectorProfile"; + + new GuiBitmapBorderCtrl() { + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 483"; + MinExtent = "0 -500"; + Profile = "GuiTabBorderProfile"; + }; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 483"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiDefaultProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiListBoxCtrl(DecalDataList) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiListBoxProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "474 48"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + AllowMultipleSelections = "0"; + fitParentWidth = "0"; + mirrorSet = "DecalDataSet"; + }; + }; + }; + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + internalName = "instanceTab"; + Enabled = "1"; + isContainer = "1"; + Profile = "EditorTabPage"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "202 483"; + Docking = "client"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "-1 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Instances"; + maxLength = "1024"; + + new GuiContainer() { + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 483"; + Margin = "0 0 0 0"; + Docking = "client"; + MinExtent = "0 8"; + Profile = "GuiInspectorProfile"; + + new GuiBitmapBorderCtrl() { + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 483"; + MinExtent = "0 -500"; + Profile = "GuiTabBorderProfile"; + }; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 483"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "None"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiTreeViewCtrl(DecalEditorTreeView) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "200 100"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "0"; + showRoot = "0"; + internalNamesOnly = "0"; + }; + }; + }; + }; + // Save Button + new GuiBitmapButtonCtrl(SaveDecalsButton) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "137 26"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "DecalPMan.saveDirty(); DecalInspector::removeDirty();"; + hovertime = "1000"; + groupNum = "-1"; + text =""; + tooltip = "Save All"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/save-icon"; + }; + + new GuiBitmapButtonCtrl(RetargetDecalButton) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "157 26"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Retarget missing decals to an existing decal datablock"; + bitmap = "tools/gui/images/retarget-btn"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(NewDecalButton) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "177 26"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Create New Decal Template"; + bitmap = "core/art/gui/images/new"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(DeleteDecalButton) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "190 26"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = ""; + tooltip = "Delete Selected Decal Template"; + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + tabSelected = "0"; + }; + }; + + + new GuiWindowCollapseCtrl(DecalPreviewWindow) { + canSaveDynamicFields = "0"; + internalName = ""; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 SPC getWord(EditorGuiToolbar.extent, 1) + getWord(DecalEditorWindow.extent, 1) - 2; + Extent = "210 335"; + MinExtent = "210 335"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + Docking = "None"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "152 235"; + closeCommand = "EPainter.parentGroup.setVisible(false);"; + EdgeSnap = "1"; + text = "Decal Properties"; + + new GuiScrollCtrl(DecalEditorTemplateProperties){ + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + VertSizing = "bottom"; + HorizSizing = "width"; + Position = "4 24"; + Extent = "202 259"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + willFirstRespond = "1"; + Docking = "client"; + Margin = "3 1 3 3"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = true; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "189 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "208 0"; + Caption = "Decal Instance Preview"; + Margin = "0 0 0 -3"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "-1 0"; + Extent = "202 187"; + Docking = "none"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + internalName = "instancePreview"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "center"; + VertSizing = "height"; + Position = "0 0"; + Extent = "188 186"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + wrap = "0"; + bitmap= "tools/materialeditor/gui/unknownImage"; + }; + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "center"; + VertSizing = "height"; + Position = "0 0"; + Extent = "188 186"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/terrainpainter/terrain-painter-border-large"; + wrap = "0"; + }; + }; + }; + }; + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "202 0"; + Caption = "Decal Instance Properties"; + Margin = "0 0 0 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(DecalEditorDetailContainer){ + Position = "0 202"; + Extent = "202 79"; + HorizSizing = "width"; + VertSizing = "bottom"; + isContainer = "1"; + + new GuiTextCtrl(){ + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "3 2"; + Extent = "47 16"; + text = "Instance"; + }; + new GuiTextCtrl(){ // instance Name + Profile = "GuiTextProfile"; + internalName = "instanceId"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "54 2"; + Extent = "128 18"; + text = ""; + }; + new GuiTextCtrl(){ + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "3 21"; + Extent = "47 16"; + text = "Translate"; + }; + new GuiTextEditCtrl(){ // instance translate + Profile = "GuiTextEditProfile"; + internalName = "nodePosition"; + HorizSizing = "width"; + VertSizing = "bottom"; + AltCommand = "DecalEditorGui.editNodeDetails();"; + Position = "54 20"; + Extent = "128 18"; + text = ""; + }; + new GuiTextCtrl(){ + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "3 41"; + Extent = "47 16"; + text = "Tangent"; + }; + new GuiTextEditCtrl(){ // instance rotation + Profile = "GuiTextEditProfile"; + internalName = "nodeTangent"; + HorizSizing = "width"; + VertSizing = "bottom"; + AltCommand = "DecalEditorGui.editNodeDetails();"; + Position = "54 40"; + Extent = "128 18"; + text = ""; + }; + new GuiTextCtrl(){ + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "3 61"; + Extent = "47 16"; + text = "Size"; + }; + new GuiTextEditCtrl(){ // instance scale + Profile = "GuiTextEditProfile"; + internalName = "nodeSize"; + HorizSizing = "width"; + VertSizing = "bottom"; + AltCommand = "DecalEditorGui.editNodeDetails();"; + Position = "54 60"; + Extent = "128 18"; + text = ""; + }; + }; + }; + }; + }; + }; + + new GuiScrollCtrl(DecalEditorLibraryProperties) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + VertSizing = "bottom"; + HorizSizing = "width"; + Position = "4 24"; + Extent = "202 259"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + willFirstRespond = "1"; + Docking = "client"; + Margin = "3 1 3 3"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = true; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "187 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "208 0"; + Caption = "Decal Template Preview"; + Margin = "0 0 0 -3"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "-1 0"; + Extent = "202 187"; + Docking = "none"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + internalName = "decalPreview"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "center"; + VertSizing = "height"; + Position = "0 0"; + Extent = "188 186"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + wrap = "0"; + bitmap= "tools/materialeditor/gui/unknownImage"; + }; + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "center"; + VertSizing = "height"; + Position = "0 0"; + Extent = "188 186"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/terrainpainter/terrain-painter-border-large"; + wrap = "0"; + }; + }; + }; + }; + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "202 0"; + Caption = "Decal Template Properties"; + Margin = "0 0 0 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiInspector(DecalInspector) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "200 257"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + dividerMargin = "5"; + groupFilters = "+General,+SimBase,+Decal,+Rendering,+Texturing"; + + }; + }; + }; + }; + //---------------------------------- + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/decalEditor/main.cs b/Templates/Empty/game/tools/decalEditor/main.cs new file mode 100644 index 000000000..06dd96f81 --- /dev/null +++ b/Templates/Empty/game/tools/decalEditor/main.cs @@ -0,0 +1,199 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function initializeDecalEditor() +{ + echo(" % - Initializing Decal Editor"); + + $decalDataFile = "art/decals/managedDecalData.cs"; + + exec( "./decalEditor.cs" ); + exec( "./decalEditorGui.gui" ); + exec( "./decalEditorGui.cs" ); + exec( "./decalEditorActions.cs" ); + + // Add ourselves to EditorGui, where all the other tools reside + DecalEditorGui.setVisible( false ); + DecalPreviewWindow.setVisible( false ); + DecalEditorWindow.setVisible( false ); + EditorGui.add( DecalEditorGui ); + EditorGui.add( DecalEditorWindow ); + EditorGui.add( DecalPreviewWindow ); + DecalEditorTabBook.selectPage( 0 ); + + new ScriptObject( DecalEditorPlugin ) + { + superClass = "EditorPlugin"; + editorGui = DecalEditorGui; + }; + + %map = new ActionMap(); + %map.bindCmd( keyboard, "5", "EDecalEditorAddDecalBtn.performClick();", "" ); + %map.bindCmd( keyboard, "1", "EDecalEditorSelectDecalBtn.performClick();", "" ); + %map.bindCmd( keyboard, "2", "EDecalEditorMoveDecalBtn.performClick();", "" ); + %map.bindCmd( keyboard, "3", "EDecalEditorRotateDecalBtn.performClick();", "" ); + %map.bindCmd( keyboard, "4", "EDecalEditorScaleDecalBtn.performClick();", "" ); + + DecalEditorPlugin.map = %map; + + new PersistenceManager( DecalPMan ); + +} + +function destroyDecalEditor() +{ +} + +// JCF: helper for during development +function reinitDecalEditor() +{ + exec( "./main.cs" ); + exec( "./decalEditor.cs" ); + exec( "./decalEditorGui.cs" ); +} + +function DecalEditorPlugin::onWorldEditorStartup( %this ) +{ + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Decal Editor", "", DecalEditorPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "Decal Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "DecalEditorPlugin", "DecalEditorPalette", expandFilename("tools/decalEditor/decal-editor"), %tooltip ); + + //connect editor windows + GuiWindowCtrl::attach( DecalPreviewWindow, DecalEditorWindow ); + + //set initial palette setting + %this.paletteSelection = "AddDecalMode"; +} + +function DecalEditorPlugin::onActivated( %this ) +{ + EditorGui.bringToFront( DecalEditorGui ); + DecalEditorGui.setVisible( true ); + DecalEditorGui.makeFirstResponder( true ); + DecalPreviewWindow.setVisible( true ); + DecalEditorWindow.setVisible( true ); + + %this.map.push(); + + //WORKAROUND: due to the gizmo mode being stored on its profile (which may be shared), + // we may end up with a mismatch between the editor mode and gizmo mode here. + // Reset mode explicitly here to work around this. + DecalEditorGui.setMode( DecalEditorGui.getMode() ); + + // Set the current palette selection + DecalEditorGui.paletteSync( %this.paletteSelection ); + + // Store this on a dynamic field + // in order to restore whatever setting + // the user had before. + %this.prevGizmoAlignment = GlobalGizmoProfile.alignment; + + // The DecalEditor always uses Object alignment. + GlobalGizmoProfile.alignment = "Object"; + + DecalEditorGui.rebuildInstanceTree(); + + // These could perhaps be the node details like the shape editor + //ShapeEdPropWindow.syncNodeDetails(-1); + + Parent::onActivated(%this); +} + +function DecalEditorPlugin::onDeactivated( %this ) +{ + DecalEditorGui.setVisible(false); + DecalPreviewWindow.setVisible( false ); + DecalEditorWindow.setVisible( false ); + + %this.map.pop(); + + // Remember last palette selection + %this.paletteSelection = DecalEditorGui.getMode(); + + // Restore the previous Gizmo + // alignment settings. + GlobalGizmoProfile.alignment = %this.prevGizmoAlignment; + + Parent::onDeactivated(%this); +} + +function DecalEditorPlugin::isDirty( %this ) +{ + %dirty = DecalPMan.hasDirty(); + + %dirty |= decalManagerDirty(); + + return %dirty; +} + +function DecalEditorPlugin::onSaveMission( %this, %file ) +{ + DecalPMan.saveDirty(); + decalManagerSave( %file @ ".decals" ); +} + +function DecalEditorPlugin::onEditMenuSelect( %this, %editMenu ) +{ + %hasSelection = false; + + if ( DecalEditorGui.getSelectionCount() > 0 ) + %hasSelection = true; + + %editMenu.enableItem( 3, false ); // Cut + %editMenu.enableItem( 4, false ); // Copy + %editMenu.enableItem( 5, false ); // Paste + %editMenu.enableItem( 6, %hasSelection ); // Delete + %editMenu.enableItem( 8, false ); // Deselect + + // NOTE: If you want to implement Cut, Copy, Paste, or Deselect + // for this editor simply enable the menu items when it is appropriate + // and fill in the method stubs below. +} + +function DecalEditorPlugin::handleDelete( %this ) +{ + DecalEditorGui.deleteSelectedDecal(); +} + +function DecalEditorPlugin::handleDeselect( %this ) +{ +} + +function DecalEditorPlugin::handleCut( %this ) +{ +} + +function DecalEditorPlugin::handleCopy( %this ) +{ +} + +function DecalEditorPlugin::handlePaste( %this ) +{ +} + +function DecalEditorPlugin::handleEscape( %this ) +{ +} + diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/button.png b/Templates/Empty/game/tools/editorClasses/gui/images/button.png new file mode 100644 index 000000000..e255cb911 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/button.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/button_left.png b/Templates/Empty/game/tools/editorClasses/gui/images/button_left.png new file mode 100644 index 000000000..3f7238fbf Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/button_left.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/button_middle.png b/Templates/Empty/game/tools/editorClasses/gui/images/button_middle.png new file mode 100644 index 000000000..263e4bcc2 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/button_middle.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/button_right.png b/Templates/Empty/game/tools/editorClasses/gui/images/button_right.png new file mode 100644 index 000000000..40ff128f1 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/button_right.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/button_toolbar.png b/Templates/Empty/game/tools/editorClasses/gui/images/button_toolbar.png new file mode 100644 index 000000000..3de3b1519 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/button_toolbar.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/dropDown.png b/Templates/Empty/game/tools/editorClasses/gui/images/dropDown.png new file mode 100644 index 000000000..795b0e575 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/dropDown.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/form.png b/Templates/Empty/game/tools/editorClasses/gui/images/form.png new file mode 100644 index 000000000..cc0d39841 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/form.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/formMenu.png b/Templates/Empty/game/tools/editorClasses/gui/images/formMenu.png new file mode 100644 index 000000000..110adef3e Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/formMenu.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/iconAccept.png b/Templates/Empty/game/tools/editorClasses/gui/images/iconAccept.png new file mode 100644 index 000000000..a24d6052d Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/iconAccept.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/iconCancel.png b/Templates/Empty/game/tools/editorClasses/gui/images/iconCancel.png new file mode 100644 index 000000000..744df795a Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/iconCancel.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/iconInformation.png b/Templates/Empty/game/tools/editorClasses/gui/images/iconInformation.png new file mode 100644 index 000000000..a7e472232 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/iconInformation.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/iconNext.png b/Templates/Empty/game/tools/editorClasses/gui/images/iconNext.png new file mode 100644 index 000000000..42eb8363b Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/iconNext.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/iconPrevious.png b/Templates/Empty/game/tools/editorClasses/gui/images/iconPrevious.png new file mode 100644 index 000000000..6f197a442 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/iconPrevious.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/iconRSSNews.png b/Templates/Empty/game/tools/editorClasses/gui/images/iconRSSNews.png new file mode 100644 index 000000000..feee9c056 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/iconRSSNews.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/iconSave.png b/Templates/Empty/game/tools/editorClasses/gui/images/iconSave.png new file mode 100644 index 000000000..50e70bd70 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/iconSave.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/panel_button.png b/Templates/Empty/game/tools/editorClasses/gui/images/panel_button.png new file mode 100644 index 000000000..6b945688a Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/panel_button.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/panel_dark.png b/Templates/Empty/game/tools/editorClasses/gui/images/panel_dark.png new file mode 100644 index 000000000..8ba559c7b Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/panel_dark.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/panel_light.png b/Templates/Empty/game/tools/editorClasses/gui/images/panel_light.png new file mode 100644 index 000000000..87372edab Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/panel_light.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/panel_medium.png b/Templates/Empty/game/tools/editorClasses/gui/images/panel_medium.png new file mode 100644 index 000000000..23e63ebe6 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/panel_medium.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/rollout.png b/Templates/Empty/game/tools/editorClasses/gui/images/rollout.png new file mode 100644 index 000000000..082051e86 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/rollout.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/rollout_dark.png b/Templates/Empty/game/tools/editorClasses/gui/images/rollout_dark.png new file mode 100644 index 000000000..0af73e3b4 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/rollout_dark.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/rollout_plusminus_header.png b/Templates/Empty/game/tools/editorClasses/gui/images/rollout_plusminus_header.png new file mode 100644 index 000000000..899491473 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/rollout_plusminus_header.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/rollout_plusminus_transparent.png b/Templates/Empty/game/tools/editorClasses/gui/images/rollout_plusminus_transparent.png new file mode 100644 index 000000000..312e30455 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/rollout_plusminus_transparent.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/rollout_thin.png b/Templates/Empty/game/tools/editorClasses/gui/images/rollout_thin.png new file mode 100644 index 000000000..6c4903668 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/rollout_thin.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/rollout_thin_light.png b/Templates/Empty/game/tools/editorClasses/gui/images/rollout_thin_light.png new file mode 100644 index 000000000..37a86b845 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/rollout_thin_light.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/scroll.png b/Templates/Empty/game/tools/editorClasses/gui/images/scroll.png new file mode 100644 index 000000000..252200f93 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/scroll.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/slider.png b/Templates/Empty/game/tools/editorClasses/gui/images/slider.png new file mode 100644 index 000000000..d13b9372d Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/slider.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/start/background.jpg b/Templates/Empty/game/tools/editorClasses/gui/images/start/background.jpg new file mode 100644 index 000000000..5fee24333 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/start/background.jpg differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/start/create.png b/Templates/Empty/game/tools/editorClasses/gui/images/start/create.png new file mode 100644 index 000000000..c3f868412 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/start/create.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/start/create_d.png b/Templates/Empty/game/tools/editorClasses/gui/images/start/create_d.png new file mode 100644 index 000000000..35156129c Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/start/create_d.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/start/create_h.png b/Templates/Empty/game/tools/editorClasses/gui/images/start/create_h.png new file mode 100644 index 000000000..d8c0ccd5c Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/start/create_h.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/start/create_i.png b/Templates/Empty/game/tools/editorClasses/gui/images/start/create_i.png new file mode 100644 index 000000000..5c21094d9 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/start/create_i.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/start/import.png b/Templates/Empty/game/tools/editorClasses/gui/images/start/import.png new file mode 100644 index 000000000..b1f2448de Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/start/import.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/start/import_d.png b/Templates/Empty/game/tools/editorClasses/gui/images/start/import_d.png new file mode 100644 index 000000000..4b30cd1b5 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/start/import_d.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/start/import_h.png b/Templates/Empty/game/tools/editorClasses/gui/images/start/import_h.png new file mode 100644 index 000000000..a5396d101 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/start/import_h.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/start/import_i.png b/Templates/Empty/game/tools/editorClasses/gui/images/start/import_i.png new file mode 100644 index 000000000..fae4e774a Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/start/import_i.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/start/navPanel.png b/Templates/Empty/game/tools/editorClasses/gui/images/start/navPanel.png new file mode 100644 index 000000000..2d1493b59 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/start/navPanel.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/start/open.png b/Templates/Empty/game/tools/editorClasses/gui/images/start/open.png new file mode 100644 index 000000000..1af53606b Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/start/open.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/start/open_d.png b/Templates/Empty/game/tools/editorClasses/gui/images/start/open_d.png new file mode 100644 index 000000000..d83907bfd Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/start/open_d.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/start/open_h.png b/Templates/Empty/game/tools/editorClasses/gui/images/start/open_h.png new file mode 100644 index 000000000..13938ae28 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/start/open_h.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/start/open_i.png b/Templates/Empty/game/tools/editorClasses/gui/images/start/open_i.png new file mode 100644 index 000000000..1775c78e9 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/start/open_i.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/start/splash.png b/Templates/Empty/game/tools/editorClasses/gui/images/start/splash.png new file mode 100644 index 000000000..b988c35c3 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/start/splash.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/start/topBarLeft.png b/Templates/Empty/game/tools/editorClasses/gui/images/start/topBarLeft.png new file mode 100644 index 000000000..206b6b0c6 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/start/topBarLeft.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/start/topBarMiddle.png b/Templates/Empty/game/tools/editorClasses/gui/images/start/topBarMiddle.png new file mode 100644 index 000000000..c5332c092 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/start/topBarMiddle.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/start/topBarRight.png b/Templates/Empty/game/tools/editorClasses/gui/images/start/topBarRight.png new file mode 100644 index 000000000..4ea1bc2a5 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/start/topBarRight.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/tabBook.png b/Templates/Empty/game/tools/editorClasses/gui/images/tabBook.png new file mode 100644 index 000000000..c931238ce Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/tabBook.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/textEdit.png b/Templates/Empty/game/tools/editorClasses/gui/images/textEdit.png new file mode 100644 index 000000000..1b601b2d6 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/textEdit.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/toolWindow.png b/Templates/Empty/game/tools/editorClasses/gui/images/toolWindow.png new file mode 100644 index 000000000..5b3b89188 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/toolWindow.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/toolbar.png b/Templates/Empty/game/tools/editorClasses/gui/images/toolbar.png new file mode 100644 index 000000000..1a2dde5f2 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/toolbar.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/treeView.png b/Templates/Empty/game/tools/editorClasses/gui/images/treeView.png new file mode 100644 index 000000000..ae42402f1 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/treeView.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/images/window.png b/Templates/Empty/game/tools/editorClasses/gui/images/window.png new file mode 100644 index 000000000..a6db64820 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/images/window.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/panels/editor-menubar.png b/Templates/Empty/game/tools/editorClasses/gui/panels/editor-menubar.png new file mode 100644 index 000000000..247aabcea Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/panels/editor-menubar.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/panels/icon-dropdownbar.png b/Templates/Empty/game/tools/editorClasses/gui/panels/icon-dropdownbar.png new file mode 100644 index 000000000..bbde0016d Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/panels/icon-dropdownbar.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/panels/inspector-style-rollout-dark.png b/Templates/Empty/game/tools/editorClasses/gui/panels/inspector-style-rollout-dark.png new file mode 100644 index 000000000..e62442ed8 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/panels/inspector-style-rollout-dark.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/panels/inspector-style-rollout-list.png b/Templates/Empty/game/tools/editorClasses/gui/panels/inspector-style-rollout-list.png new file mode 100644 index 000000000..c97c2af67 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/panels/inspector-style-rollout-list.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/panels/inspector-style-rollout-noheader.png b/Templates/Empty/game/tools/editorClasses/gui/panels/inspector-style-rollout-noheader.png new file mode 100644 index 000000000..f78dd71f4 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/panels/inspector-style-rollout-noheader.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/panels/inspector-style-rollout.png b/Templates/Empty/game/tools/editorClasses/gui/panels/inspector-style-rollout.png new file mode 100644 index 000000000..39d35e326 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/panels/inspector-style-rollout.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/panels/inspector-style-rollout_inner.png b/Templates/Empty/game/tools/editorClasses/gui/panels/inspector-style-rollout_inner.png new file mode 100644 index 000000000..a472dff4f Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/panels/inspector-style-rollout_inner.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/panels/menu-fullborder.png b/Templates/Empty/game/tools/editorClasses/gui/panels/menu-fullborder.png new file mode 100644 index 000000000..f85b7dc11 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/panels/menu-fullborder.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/panels/menubar.png b/Templates/Empty/game/tools/editorClasses/gui/panels/menubar.png new file mode 100644 index 000000000..353451a27 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/panels/menubar.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/panels/navPanel.png b/Templates/Empty/game/tools/editorClasses/gui/panels/navPanel.png new file mode 100644 index 000000000..f1098d895 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/panels/navPanel.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/panels/navPanelProfiles.ed.cs b/Templates/Empty/game/tools/editorClasses/gui/panels/navPanelProfiles.ed.cs new file mode 100644 index 000000000..ca03e2b60 --- /dev/null +++ b/Templates/Empty/game/tools/editorClasses/gui/panels/navPanelProfiles.ed.cs @@ -0,0 +1,111 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +singleton GuiControlProfile (NavPanelProfile) +{ + opaque = false; + border = -2; + category = "Editor"; +}; + + +singleton GuiControlProfile (NavPanel : NavPanelProfile) +{ + bitmap = "./navPanel"; + category = "Editor"; +}; + +singleton GuiControlProfile (NavPanelBlue : NavPanelProfile) +{ + bitmap = "./navPanel_blue"; + category = "Editor"; +}; + +singleton GuiControlProfile (NavPanelGreen : NavPanelProfile) +{ + bitmap = "./navPanel_green"; + category = "Editor"; +}; + +singleton GuiControlProfile (NavPanelRed : NavPanelProfile) +{ + bitmap = "./navPanel_red"; + category = "Editor"; +}; + +singleton GuiControlProfile (NavPanelWhite : NavPanelProfile) +{ + bitmap = "./navPanel_white"; + category = "Editor"; +}; + +singleton GuiControlProfile (NavPanelYellow : NavPanelProfile) +{ + bitmap = "./navPanel_yellow"; + category = "Editor"; +}; +singleton GuiControlProfile (menubarProfile : NavPanelProfile) +{ + bitmap = "./menubar"; + category = "Editor"; +}; +singleton GuiControlProfile (editorMenubarProfile : NavPanelProfile) +{ + bitmap = "./editor-menubar"; + category = "Editor"; +}; +singleton GuiControlProfile (editorMenu_wBorderProfile : NavPanelProfile) +{ + bitmap = "./menu-fullborder"; + category = "Editor"; +}; +singleton GuiControlProfile (inspectorStyleRolloutProfile : NavPanelProfile) +{ + bitmap = "./inspector-style-rollout"; + category = "Editor"; +}; +singleton GuiControlProfile (inspectorStyleRolloutListProfile : NavPanelProfile) +{ + bitmap = "./inspector-style-rollout-list"; + category = "Editor"; +}; +singleton GuiControlProfile (inspectorStyleRolloutDarkProfile : NavPanelProfile) +{ + bitmap = "./inspector-style-rollout-dark"; + category = "Editor"; +}; +singleton GuiControlProfile (inspectorStyleRolloutInnerProfile : NavPanelProfile) +{ + bitmap = "./inspector-style-rollout_inner"; + category = "Editor"; +}; +singleton GuiControlProfile (inspectorStyleRolloutNoHeaderProfile : NavPanelProfile) +{ + bitmap = "./inspector-style-rollout-noheader"; + category = "Editor"; +}; +singleton GuiControlProfile (IconDropdownProfile : NavPanelProfile) +{ + bitmap = "./icon-dropdownbar"; + category = "Editor"; +}; diff --git a/Templates/Empty/game/tools/editorClasses/gui/panels/navPanel_blue.png b/Templates/Empty/game/tools/editorClasses/gui/panels/navPanel_blue.png new file mode 100644 index 000000000..435e607fa Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/panels/navPanel_blue.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/panels/navPanel_green.png b/Templates/Empty/game/tools/editorClasses/gui/panels/navPanel_green.png new file mode 100644 index 000000000..30324742d Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/panels/navPanel_green.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/panels/navPanel_red.png b/Templates/Empty/game/tools/editorClasses/gui/panels/navPanel_red.png new file mode 100644 index 000000000..5cf1b0968 Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/panels/navPanel_red.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/panels/navPanel_white.png b/Templates/Empty/game/tools/editorClasses/gui/panels/navPanel_white.png new file mode 100644 index 000000000..bcbeac17a Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/panels/navPanel_white.png differ diff --git a/Templates/Empty/game/tools/editorClasses/gui/panels/navPanel_yellow.png b/Templates/Empty/game/tools/editorClasses/gui/panels/navPanel_yellow.png new file mode 100644 index 000000000..269d15abd Binary files /dev/null and b/Templates/Empty/game/tools/editorClasses/gui/panels/navPanel_yellow.png differ diff --git a/Templates/Empty/game/tools/editorClasses/main.cs b/Templates/Empty/game/tools/editorClasses/main.cs new file mode 100644 index 000000000..7ebad5d4c --- /dev/null +++ b/Templates/Empty/game/tools/editorClasses/main.cs @@ -0,0 +1,86 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function initializeEditorClasses() +{ + echo(" % - Initializing Tools Base"); + + + $EditorClassesGroup = "EditorClassesCleanup"; + if( !isObject( $EditorClassesGroup ) ) + new SimGroup( $EditorClassesGroup ); + + + //----------------------------------------------------------------------------- + // Load Editor Profiles + //----------------------------------------------------------------------------- + + exec("./scripts/fileLoader.ed.cs"); + + loadDirectory( expandFilename("./gui/panels") ); + + + //----------------------------------------------------------------------------- + // Setup Preferences Manager + //----------------------------------------------------------------------------- + + exec("./scripts/preferencesManager.ed.cs"); + initPreferencesManager(); + + //----------------------------------------------------------------------------- + // Load Form Managers + //----------------------------------------------------------------------------- + + exec("./scripts/guiFormLibraryManager.ed.cs"); + exec("./scripts/guiFormContentManager.ed.cs"); + exec("./scripts/guiFormReferenceManager.ed.cs"); + exec("./scripts/guiFormLayoutManager.ed.cs"); + exec("./scripts/guiFormMessageManager.ed.cs"); + exec("./scripts/expandos.ed.cs"); + exec("./scripts/utility.ed.cs"); + setupBaseExpandos(); + + // User Display + exec("./scripts/contextPopup.ed.cs"); + + // Project Support + exec("./scripts/projects/projectEvents.ed.cs"); + exec("./scripts/projects/projectInternalInterface.ed.cs"); + + // Input + exec("./scripts/input/inputEvents.ed.cs"); + exec("./scripts/input/dragDropEvents.ed.cs"); + exec("./scripts/input/applicationEvents.ed.cs"); + + // Form Class + exec("./scripts/guiFormClass.ed.cs"); + exec("./scripts/guiClasses/guiThumbnailPopup.ed.cs"); + exec("./scripts/guiClasses/guiThumbnail.ed.cs"); + exec("./scripts/RSSNews/RSSFeedScript.ed.cs"); + + loadDirectory( expandFilename("./scripts/core") ); + loadDirectory( expandFilename("./scripts/platform") ); +} + +function destroyEditorClasses() +{ +} diff --git a/Templates/Empty/game/tools/editorClasses/scripts/RSSNews/RSSFeedScript.ed.cs b/Templates/Empty/game/tools/editorClasses/scripts/RSSNews/RSSFeedScript.ed.cs new file mode 100644 index 000000000..b61109efb --- /dev/null +++ b/Templates/Empty/game/tools/editorClasses/scripts/RSSNews/RSSFeedScript.ed.cs @@ -0,0 +1,155 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// RSS ticker configuration: +$RSSFeed::serverName = "feeds.garagegames.com"; +$RSSFeed::serverPort = 80; +$RSSFeed::serverURL = "/product/tgea"; +$RSSFeed::userAgent = "TorqueGameEngineAdvances/1.1"; +$RSSFeed::maxNewHeadlines = 10; + +// Load up the helper objects +exec( "./RSSStructs.ed.cs" ); + +function RSSFeedObject::onConnected(%this) +{ + //echo("RSS Feed"); + //echo(" - Requesting RSS data at URL: " @ $RSSFeed::serverURL ); + + // Reset some useful state information. + $RSSFeed::lineCount = 0; + $RSSFeed::requestResults = ""; + + // Load the cache here... + $RSSFeed::rssCache = 0; + + // Request our RSS. + %this.send("GET " @ $RSSFeed::serverURL @ " HTTP/1.0\nHost: " @ $RSSFeed::serverName @ "\nUser-Agent: " @ $RSSFeed::userAgent @ "\n\r\n\r\n"); +} + +function RSSFeedObject::onLine(%this, %line) +{ + // Collate info. + $RSSFeed::lineCount++; + $RSSFeed::requestResults = $RSSFeed::requestResults @ %line; +} + +function RSSFeedObject::getTagContents(%this, %string, %tag, %startChar) +{ + // This function occasionally makes Torque hard crash. It doesn't + // seem to do it anymore but be careful! + + // Ok, get thing between <%tag> and after char # + // %startChar in the passed string. + + %startTag = "<" @ %tag @ ">"; + %endTag = ""; + + %startTagOffset = strpos(%string, %startTag, %startChar); + + // Compensate for presence of start tag. + %startOffset = %startTagOffset + strlen(%startTag); + + // Ok, now look for end tag. + %endTagOffset = strpos(%string, %endTag, %startOffset - 1); + + // If we didn't find it, bail. + if(%endTagOffset < 0) + return ""; + + // Evil hack - store last found item in a global. + %this.lastOffset = %endTagOffset; + + // And get & return the substring between the tags. + %result = getSubStr(%string, %startOffset, %endTagOffset - %startOffset); + + // Do a little mojo to deal with " and some other htmlentities. + %result = strreplace(%result, """, "\""); + %result = strreplace(%result, "&", "&"); + + return %result; +} + +function RSSFeedObject::onDisconnect(%this) +{ + // Create collection and load cache. + %ret = constructRSSHeadlineCollection(); + %ret.loadFromFile( "RSSCache.cs" ); + + // Ok, we have a full buffer now, hopefully. Let's process it. + //echo(" - Got " @ $RSSFeed::lineCount @ " lines."); + + // We want the feed title and the first three headlines + links. + + // Feed title - get the first occurence in the string. + %title = %this.getTagContents($RSSFeed::requestResults, "title", 0); + %titleLink = %this.getTagContents($RSSFeed::requestResults, "link", 0); + + //echo(" - Feed title: '" @ %title @ "'"); + //echo(" - Feed link: '" @ %titleLink @ "'"); + + %newItems = ""; + + // Ok, get the first headlines, if any... + for( %i = 0; %i < $RSSFeed::maxNewHeadlines; %i++ ) + { + %headline[%i] = %this.getTagContents($RSSFeed::requestResults, "title", %this.lastOffset); + %headlineLink[%i] = %this.getTagContents($RSSFeed::requestResults, "link", %this.lastOffset); + + // Skip the content - it's not going to do anything but confuse us. + %garbage = %this.getTagContents($RSSFeed::requestResults, "content:encoded", %this.lastOffset); + %isNew = %ret.addHeadline( constructRSSHeadline( %headline[%i], %headlineLink[%i] ) ); + + if( %isNew ) + { + %newItems = true; + //echo(" - Headline #" @ %i @ " : '" @ %headline[%i] @ "'"); + //echo(" - Headline Link #" @ %i @ " : '" @ %headlineLink[%i] @ "'"); + } + } + + if( %this._callback !$= "" ) + { + %params = %ret; + + if( %newItems ) + %params = %params @ ", \"" @ %newItems @ "\""; + + eval( %this._callback @ "(" @ %params @ ");" ); + } + + %ret.writeToFile( "RSSCache.cs", false ); +} + +function RSSUpdate::initialize( %callback ) +{ + new TCPObject(RSSFeedObject); + RSSFeedObject._callback = %callback; + + RSSFeedObject.connect( $RSSFeed::serverName @ ":" @ $RSSFeed::serverPort ); +} + +function RSSUpdate::destroy() +{ + if(isObject(RSSFeedObject)) + RSSFeedObject.delete(); +} diff --git a/Templates/Empty/game/tools/editorClasses/scripts/RSSNews/RSSStructs.ed.cs b/Templates/Empty/game/tools/editorClasses/scripts/RSSNews/RSSStructs.ed.cs new file mode 100644 index 000000000..dbb55af72 --- /dev/null +++ b/Templates/Empty/game/tools/editorClasses/scripts/RSSNews/RSSStructs.ed.cs @@ -0,0 +1,153 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// RSS Feed integration structures +// I apologize in advance if this RSS reader is too restrictive with regard +// to tags/enclosures. I may revisit it at some point to add support + +//------------------------------------------------------------------------------ +// RSS Headline Item +//------------------------------------------------------------------------------ +function constructRSSHeadline( %headline, %link ) +{ + %ret = new ScriptObject() + { + class = "RSSHeadline"; + _headline = %headline; + _link = %link; + }; + + return %ret; +} + +function RSSHeadline::getHeadline( %this ) +{ + return %this._headline; +} + +function RSSHeadline::getLink( %this ) +{ + return %this._link; +} + +function RSSHeadline::sameAs( %this, %headline ) +{ + return ( strcmp( %this.toString(), %headline.toString() ) == 0 ); +} + +function RSSHeadline::toString( %this ) +{ + return %this.getHeadline() @ " ( " @ %this.getLink() @ " ) "; +} + +//------------------------------------------------------------------------------ + +function constructRSSHeadlineCollection() +{ + %ret = new ScriptObject() + { + class = "RSSHeadlineCollection"; + }; + + // Create sim group for it + %ret._simGroup = new SimGroup(); + + return %ret; +} + +function RSSHeadlineCollection::getObject( %this, %index ) +{ + %ret = %this._simGroup.getObject( %index ); + + if( !isObject( %ret ) ) + { + warn( "No such index in headline collection." ); + return -1; + } + + return %ret; +} + +function RSSHeadlineCollection::getCount( %this ) +{ + return %this._simGroup.getCount(); +} + +function RSSHeadlineCollection::addHeadline( %this, %headline, %skipReorder ) +{ + for( %i = 0; %i < %this.getCount(); %i++ ) + { + %obj = %this.getObject( %i ); + + if( %obj.sameAs( %headline ) ) + { + //echo( "cache hit headline: " @ %headline.toString() ); + return false; + } + } + + %this._simGroup.add( %headline ); + + if( !%skipReorder ) + %this._simGroup.bringToFront( %headline ); + + //echo( "adding headline: " @ %headline.toString() ); + + return true; +} + +function RSSHeadlineCollection::writeToFile( %this, %file ) +{ + $rssHeadlineCollection::count = %this.getCount(); + + for( %i = 0; %i < %this.getCount(); %i++ ) + { + %hdl = %this.getObject( %i ); + $rssHeadlineCollection::headline[%i] = %hdl.getHeadline(); + $rssHeadlineCollection::link[%i] = %hdl.getLink(); + } + + export( "$rssHeadlineCollection::*", %file, false ); +} + +function RSSHeadlineCollection::loadFromFile( %this, %file ) +{ + %this._simGroup.clear(); + + $rssHeadlineCollection::count = 0; + + %file = getPrefsPath(%file); + if (isFile(%file) || isFile(%file @ ".dso")) + exec( %file ); + + for( %i = 0; %i < $rssHeadlineCollection::count; %i++ ) + { + //echo( "[LD: " @ %i @ "] Headline: " @ $rssHeadlineCollection::headline[%i] ); + //echo( "[LD: " @ %i @ "] Link: " @ $rssHeadlineCollection::link[%i] ); + + %hdl = constructRSSHeadline( $rssHeadlineCollection::headline[%i], + $rssHeadlineCollection::link[%i] ); + + // This does negate the cache check, but that is ok -pw + %this.addHeadline( %hdl, true ); + } +} diff --git a/Templates/Empty/game/tools/editorClasses/scripts/contextPopup.ed.cs b/Templates/Empty/game/tools/editorClasses/scripts/contextPopup.ed.cs new file mode 100644 index 000000000..303e0f603 --- /dev/null +++ b/Templates/Empty/game/tools/editorClasses/scripts/contextPopup.ed.cs @@ -0,0 +1,210 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +/// @class ContextPopup +/// @brief Create a Popup Dialog that closes itself when signaled by an event. +/// +/// ContextPopup is a support class that offers a simple way of displaying +/// reusable context sensitive GuiControl popups. These dialogs are created +/// and shown to the user when the <b>show</b> method is used. +/// +/// Once a Popup is shown it will be dismissed if it meets one of a few +/// criteria. +/// +/// 1. A user clicks anywhere outside the bounds of the GuiControl, specified by +/// the 'dialog' field on the object. +/// 2. Time Passes of (n)Milliseconds, specifed by the 'timeout' field on +/// the object. +/// +/// For example, if you wished to create a context dialog with a dialog you held in +/// a local variable named %myDialog you would create a new script object as such. +/// +/// +/// @code +/// %MyContextPopup = new ScriptObject() +/// { +/// class = ContextPopup; +/// superClass= MyCallbackNamespace; // Only Necessary when you want to perform logic pre/post showing +/// dialog = %%myDialog.getID(); +/// delay = 500; // Pop the Popup after 500 Milliseconds +/// }; +/// @endcode +/// +/// Now, if you wanted to show the dialog %%myDialog and have it dismissed when anything in the +/// background is clicked, simply call the following. +/// +/// +/// @code +/// %MyContextPopup.show( %positionX, %positionY ); +/// @endcode +/// +/// If you need to know more than show the dialog and hide it when clicked or time passes, ContextPopup +/// Provides callback methods that you may override for doing intermediate processing on a dialog +/// that is to be shown or is being hidden. For example, in the above script we created a Context Dialog Container +/// called @%myContextDialog with a superClass of <b>MyCallbackNamespace</b>. If we wanted to hide the cursor when +/// the dialog was shown, and show it when the dialog was hidden, we could implement the following functions. +/// +/// @code +/// function MyCallbackNamespace::onContextActivate( %%this ) +/// { +/// // Hide Cursor Here +/// } +/// function MyCallbackNamespace::onContextDeactivate( %%this ) +/// { +/// // Show Cursor Here +/// } +/// @endcode +/// +/// @field GuiControl Dialog The GuiControl dialog to be shown when the context dialog is activated + +function ContextDialogContainer::onAdd(%this) +{ + // Add to our cleanup group. + $EditorClassesGroup.add( %this ); + + %this.base = new GuiButtonBaseCtrl() + { + profile = GuiTransparentProfile; + class = ContextDialogWatcher; + parent = %this; + modal = true; + }; + + // Flag not active. + %this.isPushed = false; + + // Add to our cleanup group. + $EditorClassesGroup.add( %this.base ); + + return true; + +} + +function ContextDialogContainer::onRemove(%this) +{ + %this.Hide(); + + if( isObject( %this.base ) ) + %this.base.delete(); +} + + + +//----------------------------------------------------------------------------- +/// (SimID this, int positionX, int positionY) +/// Shows the GuiControl specified in the Dialog field at the coordinates passed +/// to this function. If no coordinates are passed to this function, the Dialog control +/// is shown using it's current position. +/// +/// @param this The ContextDialogContainer object +/// @param positionX The X Position in Global Screen Coordinates to display the dialog +/// @param positionY The Y Position in Global Screen Coordinates to display the dialog +/// @param delay Optional delay before this popup is hidden that overrides that specified at construction time +/// +//----------------------------------------------------------------------------- +function ContextDialogContainer::Show( %this, %positionX, %positionY, %delay ) +{ + if( %this.isPushed == true ) + return true; + + if( !isObject( %this.Dialog ) ) + return false; + + // Store old parent. + %this.oldParent = %this.dialog.getParent(); + + // Set new parent. + %this.base.add( %this.Dialog ); + + if( %positionX !$= "" && %positionY !$= "" ) + %this.Dialog.setPositionGlobal( %positionX, %positionY ); + + Canvas.pushDialog( %this.base, 99 ); + + // Setup Delay Schedule + if( isEventPending( %this.popSchedule ) ) + cancel( %this.popSchedule ); + if( %delay !$= "" ) + %this.popSchedule = %this.schedule( %delay, hide ); + else if( %this.Delay !$= "" ) + %this.popSchedule = %this.schedule( %this.Delay, hide ); + +} + +//----------------------------------------------------------------------------- +/// (SimID this) +/// Hides the GuiControl specified in the Dialog field if shown. This function +/// is provided merely for more flexibility in when your dialog is shown. If you +/// do not call this function, it will be called when the dialog is dismissed by +/// a background click. +/// +/// @param this The ContextDialogContainer object +/// +//----------------------------------------------------------------------------- +function ContextDialogContainer::Hide( %this ) +{ + if( %this.isPushed == true ) + Canvas.popDialog( %this.base ); + + // Restore Old Parent; + if( isObject( %this.Dialog ) && isObject( %this.oldParent ) ) + %this.oldParent.add( %this.Dialog ); +} + + + +// ContextDialogWatcher Class - JDD +// CDW is a namespace link for the context background button to catch +// event information and pass it back to the main class. +// +// onClick it will dismiss the parent +// onDialogPop it will cleanup and notify user of deactivation +// onDialogPush it will initialize state information and notify user of activation +function ContextDialogWatcher::onClick( %this ) +{ + if( isObject( %this.parent ) ) + %this.parent.hide(); +} + +function ContextDialogWatcher::onDialogPop( %this ) +{ + if( !isObject( %this.parent ) ) + return; + + %this.parent.isPushed = false; + + if( %this.parent.isMethod( "onContextDeactivate" ) ) + %this.parent.onContextDeactivate(); +} + +function ContextDialogWatcher::onDialogPush( %this ) +{ + if( !isObject( %this.parent ) ) + return; + + %this.parent.isPushed = true; + + if( %this.parent.isMethod( "onContextActivate" ) ) + %this.parent.onContextActivate(); + +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/editorClasses/scripts/core/zip/zipFile.ed.cs b/Templates/Empty/game/tools/editorClasses/scripts/core/zip/zipFile.ed.cs new file mode 100644 index 000000000..9cbaa66c6 --- /dev/null +++ b/Templates/Empty/game/tools/editorClasses/scripts/core/zip/zipFile.ed.cs @@ -0,0 +1,38 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function ZipObject::addPath( %this, %path, %pathInZip ) +{ + %beginPath = expandFilename( %path ); + %path = pathConcat(%path, "*"); + %file = findFirstFile( %path ); + + while(%file !$= "") + { + %zipRel = makeRelativePath( %file, %beginPath ); + %finalZip = pathConcat(%pathInZip, %zipRel); + + %this.addFile( %file, %finalZip ); + + %file = findNextFile(%path); + } +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/editorClasses/scripts/expandos.ed.cs b/Templates/Empty/game/tools/editorClasses/scripts/expandos.ed.cs new file mode 100644 index 000000000..6d2804fe3 --- /dev/null +++ b/Templates/Empty/game/tools/editorClasses/scripts/expandos.ed.cs @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Called to setup the base expandos +function setupBaseExpandos() +{ + // FIXME TGEA doesnt currently have these due to the way it's built + return; + + setScriptPathExpando("tools", getExecutablePath() @ "/tools", true); + setScriptPathExpando("tool", getExecutablePath() , true); + setScriptPathExpando("toolResources", getExecutablePath() @ "/resources", true); + + setScriptPathExpando("core", getExecutablePath() @ "/core", true); + + // Remove the game expando so we can use this to reset expandos + removeScriptPathExpando("game"); +} diff --git a/Templates/Empty/game/tools/editorClasses/scripts/fileLoader.ed.cs b/Templates/Empty/game/tools/editorClasses/scripts/fileLoader.ed.cs new file mode 100644 index 000000000..19456af2c --- /dev/null +++ b/Templates/Empty/game/tools/editorClasses/scripts/fileLoader.ed.cs @@ -0,0 +1,108 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function loadDirectory(%path, %type, %dsoType) +{ + if( %type $= "" ) + %type = "ed.cs"; + if( %dsoType $= "" ) + %dsoType = "edso"; + + %cspath = %path @ "/*." @ %type; + + // Because in a shipping version there will be no .cs files, we can't just + // find all the cs files and exec them. + + // First we find all the scripts and compile them if there are any + // In the shipping version, this wont find anything. + if( !$Scripts::ignoreDSOs ) + { + %dsoReloc = compileDirectory(%cspath); + + // Finally we find all the dsos and exec them instead + + // If the DSOs are relocated by the engine (which will be the case when + // running the tools) then we need to look for the scripts again. + + if(! %dsoReloc) + %dsopath = %path @ "/*." @ %type @ "." @ %dsoType; + else + %dsopath = %cspath; + } + else + %dsopath = %cspath; + + //error("Execing Directory " @ %dsopath @ " ..."); + %file = findFirstFile(%dsopath); + + while(%file !$= "") + { + //error(" Found File: " @ %file); + + // As we cant exec() a .dso directly, we need to strip that part from the filename + %pos = strstr(%file, "." @ %dsoType); + if(%pos != -1) + %csfile = getSubStr(%file, 0, %pos); + else + %csfile = %file; + + exec(%csfile); + %file = findNextFile(%dsopath); + } +} + +function compileDirectory(%path, %dsoPath) +{ + %saveDSOPath = $Scripts::OverrideDSOPath; + $Scripts::OverrideDSOPath = %dsoPath; + + %dsoReloc = false; + + %file = findFirstFile(%path); + + //error("Compiling Directory " @ %path @ " ..."); + while(%file !$= "") + { + //error(" Found File: " @ %file @ " (" @ getDSOPath(%file) @ ")"); + if(filePath(%file) !$= filePath(getDSOPath(%file))) + %dsoReloc = true; + + compile(%file); + %file = findNextFile(%path); + } + + $Scripts::OverrideDSOPath = %saveDSOPath; + + return %dsoReloc; +} + +function listDirectory(%path) +{ + %file = findFirstFile(%path); + + echo("Listing Directory " @ %path @ " ..."); + while(%file !$= "") + { + echo(" " @ %file); + %file = findNextFile(%path); + } +} diff --git a/Templates/Empty/game/tools/editorClasses/scripts/guiClasses/guiThumbnail.ed.cs b/Templates/Empty/game/tools/editorClasses/scripts/guiClasses/guiThumbnail.ed.cs new file mode 100644 index 000000000..6f302a9dc --- /dev/null +++ b/Templates/Empty/game/tools/editorClasses/scripts/guiClasses/guiThumbnail.ed.cs @@ -0,0 +1,76 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// This file merely contains the base functionality for creating your own +// 'subclassed' script namkespaces that define the visual appearance of +// a thumbnail for a guiThumnailPopup list. +// +// All border creation and callback click functionality is also defined in +// this file and may be overriden in your namespaces provided that you +// properly invoke the Parent::onMethodName( %parameterList ) to all this +// base namespace to do it's dependent processing. + +//function GuiDefaultThumbnail::onAdd( %this ) +//{ + //// Nothing Here. +//} +// +//function GuiDefaultThumbnail::onRemove( %this ) +//{ + //// Nothing Here. +//} + +//----------------------------------------------------------------------------- +// Object Browser Item Default Behaviors +//----------------------------------------------------------------------------- +function GuiDefaultThumbnail::onClick( %this ) +{ + // Store data and hide the dialog. + if( isObject( %this.base ) ) + { + %this.base.item = %this; + %this.base.Hide(); + } +} + +function GuiDefaultThumbnail::onRightClick( %this ) +{ + // Nothing Here. +} + +function GuiDefaultThumbnail::onMouseLeave( %this ) +{ + // Nothing Here. +} + +function ObjectBrowserItem::onMouseEnter( %this ) +{ + // Nothing Here. +} + +function GuiDefaultThumbnail::onDoubleClick( %this ) +{ + // By Default if the base funcitonality is called + // in onClick, we will never get here. However, if + // you want to override this functionality, simply + // override onClick and don't call the parent. +} diff --git a/Templates/Empty/game/tools/editorClasses/scripts/guiClasses/guiThumbnailPopup.ed.cs b/Templates/Empty/game/tools/editorClasses/scripts/guiClasses/guiThumbnailPopup.ed.cs new file mode 100644 index 000000000..670ff0355 --- /dev/null +++ b/Templates/Empty/game/tools/editorClasses/scripts/guiClasses/guiThumbnailPopup.ed.cs @@ -0,0 +1,224 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// ContextDialogContainer Class - Example Use +//----------------------------------------------------------------------------- +// +//%MyContextDialog = new ScriptObject() +//{ +// class = ContextDialogContainer; +// superClass = GuiThumbnailPopup; +// dialog = %myContainedDialog.getID(); +// thumbType = "GuiThumbnailClass"; +// listType = "StaticSpriteThumbs"; +//}; +// %MyContextDialog.show( %positionX, %positionY ); +// %MyContextDialog.hide(); +// +// NOTES +// +// - thumbType describes a script namespace that will be linked to the creation +// of the actual thumbs in the list. This allows you to override their display +// - listType describes a script namespace that will be linked to the creation +// of the list and will have refresh and destroy called on it when you need +// to add objects to the list. to add an object, call %this.AddObject on you +// get a refresh call. +// +// +//function MyCallbackNamespace::onContextActivate( %this ) +//{ +// echo("Dialog has been pushed onto canvas, clicking outside of it will pop it!"); +//} +//function MyCallbackNamespace::onContextDeactivate( %this ) +//{ +// echo("Dialog has lost it's context and has thus been popped from the canvas!"); +//} +// +// +// Object Hierarchy +// [%scriptObject] ScriptObject (GuiThumbnailPopup) +// .superClass (ContextDialogContainer) +// (%scriptObject)->[%dialogCtrl] +// | GuiScrollCtrl [%scrollCtrl] (GuiThumbnailArray) +// | GuiDynamicCtrlArrayCtrl [%objectList] (GuiThumbnailCreator) +// .superClass ( listType ) +// .thumbType = %thumbType +// .base = %this +// +function GuiThumbnailPopup::CreateThumbPopup( %this, %parent, %thumbType, %label ) +{ + %base = new GuiWindowCtrl() + { + profile = "GuiWindowProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "260 200"; + minExtent = "140 200"; + visible = "1"; + text = %label; + maxLength = "255"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + }; + %scroll = new GuiScrollCtrl() + { + canSaveDynamicFields = "0"; + Profile = "GuiScrollProfile"; + class = "GuiThumbnailArray"; + internalName = "thumbnailScroll"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "5 13"; + Extent = "250 178"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + hScrollBar = "alwaysOff"; + vScrollBar = "alwaysOn"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "1"; + Margin = "6 2"; + thumbType = %thumbType; // Special Tag - Class of thumbObject + }; + %base.add(%scroll); + %objectList = new GuiDynamicCtrlArrayControl() + { + canSaveDynamicFields = "0"; + Profile = "GuiTransparentScrollProfile"; + class = %this.listType; + superClass = "GuiThumbnailCreator"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "250 178"; + MinExtent = "64 64"; + canSave = "1"; + Visible = "1"; + internalName = "objectList"; + hovertime = "1000"; + colCount = "0"; + colSize = %this.thumbSizeX; + rowSize = %this.thumbSizeY; + rowSpacing = "2"; + colSpacing = "2"; + thumbType = %thumbType; // Special Tag - Class of thumbObject + base = %this; // Special Tag - Link to base class for hiding of dlg + }; + %scroll.add(%objectList); + %parent.add(%base); + + return %base; + +} + +function GuiThumbnailPopup::onAdd(%this) +{ + // Call parent. + if( !Parent::onAdd( %this ) ) + return false; + + if( %this.thumbType $= "" ) + %this.thumbType = "GuiDefaultThumbnail"; + + %this.Dialog = %this.createThumbPopup( %this.base, %this.thumbType, %this.label ); + + if( !isObject( %this.Dialog ) ) + { + warn("GuiThumbnailPopup::onAdd - Invalid Context Dialog Specified!"); + return false; + } +} + + + +function GuiThumbnailArray::onRemove(%this) +{ + %this.destroy(); +} + +function GuiThumbnailArray::onWake( %this ) +{ + // Find objectList + %objectList = %this.findObjectByInternalName("ObjectList"); + + if( !isObject( %objectList ) ) + return; + + %objectList.refreshList(); +} + +function GuiThumbnailArray::refreshList(%this) +{ + // Find objectList + %objectList = %this.findObjectByInternalName("ObjectList"); + + if( !isObject( %objectList ) ) + return; + + // Parent will clear + %objectList.destroy(); + +} + +function GuiThumbnailArray::destroy(%this) +{ + // Find objectList + %objectList = %this.findObjectByInternalName("ObjectList"); + + if( !isObject( %objectList ) ) + return; + + while( %objectList.getCount() > 0 ) + { + %object = %objectList.getObject( 0 ); + if( isObject( %object ) ) + %object.delete(); + else + %objectList.remove( %object ); + } +} + +//----------------------------------------------------------------------------- +// Add a T2D Object to the Object List +//----------------------------------------------------------------------------- +function GuiThumbnailCreator::AddObject( %this, %object, %data, %tooltip ) +{ + // Add to group + $LB::ObjectLibraryGroup.add( %object ); + + // Build Object Container + %container = new GuiControl() { profile = GuiButtonProfile; }; + + // Add to list. + %this.add( %container ); + + // Return Container + return %container; +} diff --git a/Templates/Empty/game/tools/editorClasses/scripts/guiFormClass.ed.cs b/Templates/Empty/game/tools/editorClasses/scripts/guiFormClass.ed.cs new file mode 100644 index 000000000..612e47179 --- /dev/null +++ b/Templates/Empty/game/tools/editorClasses/scripts/guiFormClass.ed.cs @@ -0,0 +1,616 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// +// This will change to something more abstract in the near future, or will be moved into +// the level editor if there is no concise way to abstract it. +// +// This function will build out an empty frame and add it to its given parent. The newly +// built frame control is returned +function GuiFormClass::BuildEmptyFrame(%pos, %ext, %columns, %rows, %parentID) +{ + %frame = new GuiFrameSetCtrl() + { + profile = "GuiFrameSetProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = %pos; + extent = %ext; + columns = %columns; + rows = %rows; + borderWidth = "5"; //"4"; + //borderColor = "192 192 192"; + absoluteFrames = "1"; + relativeResizing = "1"; + specialHighlighting = "1"; + }; + + %parentID.add(%frame); + + return %frame; +} + +// +// This will change to something more abstract in the near future, or will be moved into +// the level editor if there is no concise way to abstract it. +// +// This function will build out a form control and add it to its parent. The newly built +// form control is returned. +function GuiFormClass::BuildFormControl( %parentID, %ContentLibrary ) +{ + // Find Default 'None' Content. + %contentNoneObj = GuiFormManager::FindFormContent( %ContentLibrary, "Scene View" ); + if( %contentNoneObj == 0 ) + { + error("GuiFormClass::BuildFormControl - Cannot find 'Scene View' Content Object!" ); + return false; + } + + %newFormObj = new GuiFormCtrl() + { + class = "FormControlClass"; + profile = "GuiFormProfile"; + canSaveDynamicFields = 1; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 455"; + minExtent = "20 20"; + visible = "1"; + caption = $FormClassNoContentCaption; + collapsable = "1"; + barBehindText = "1"; + hasMenu = true; + ContentLibrary = %ContentLibrary; + ContentID = %contentNoneObj; + Content = "Scene View"; + }; + %parentID.add( %newFormObj ); + + return %newFormObj; +} + + +// +// This will change to something more abstract in the near future, or will be moved into +// the level editor if there is no concise way to abstract it. +// +function FormControlClass::onWake( %this ) +{ + if( %this.ContentLibrary !$= "" && %this.Content !$= "" ) + { + %contentObj = GuiFormManager::FindFormContent( %this.ContentLibrary, %this.Content ); + if( %contentObj == 0 ) + { + error("GuiFormClass::onWake - Content Library Specified But Content Not Found!" ); + return; + } + + // Set Form Content + //if( %this.ContentID != %contentObj || !isObject( %this.ContentID ) ) + GuiFormClass::SetFormContent( %this, %contentObj ); + } + + %parentId = %this.getParent(); + %extent = %parentID.getExtent(); + %this.setExtent( GetWord(%extent, 0), GetWord(%extent, 1) ); + + GuiFormClass::BuildFormMenu( %this ); + +} + +// +// This will change to something more abstract in the near future, or will be moved into +// the level editor if there is no concise way to abstract it. +// +function GuiFormClass::BuildFormMenu( %formObj ) +{ + + if( !%formObj.hasMenu ) + return; + + // Menu Name. + %menuName = "FormMainMenu"; + + // Retrieve Menu ID. + %formMenu = %formObj.getMenuID(); + + %formMenu.clearMenuItems( %menuName ); + + //*** Setup the check mark bitmap index to start at the third bitmap + %formMenu.setCheckmarkBitmapIndex(1); + + //*** Add a menu to the menubar + %formMenu.addMenu( %menuName, %formObj); + %formMenu.setMenuBitmapIndex( %menuName, 0, true, false); + %formMenu.setMenuMargins(0, 0, 0); + + // Build Division Control Menu Items. + %formMenu.addMenuItem( %menuName, "Split This View Horizontally", 1); + %formMenu.addMenuItem( %menuName, "Split This View Vertically", 2); + %formMenu.addMenuItem( %menuName, "-", 0); + %formMenu.addMenuItem( %menuName, "Remove This View", 3); + +} + +// +// This will change to something more abstract in the near future, or will be moved into +// the level editor if there is no concise way to abstract it. +// +function GuiFormClass::SetFormContent( %formObj, %contentObj ) +{ + + // Menu Name. + %menuName = "FormMainMenu"; + + // Validate New Content. + if( !isObject( %contentObj ) ) + { + // Failure + error("GuiFormClass::SetFormContent- No Valid Content Object!" ); + return 0; + } + + // Remove any other content from the Form + %count = %formObj.getCount(); + if(%count > 1) + { + // Notify Script of Content Changing. + if( %formObj.isMethod("onContentChanging") ) + %formObj.onContentChanging( %contentObj ); + + // Object 0 is Always The Menu. + %currentContent = %formObj.getObject( 1 ); + if( isObject( %currentContent ) ) + { + // Remove from Reference List. + if( %formObj.contentID !$= "" ) + GuiFormManager::RemoveContentReference( %formObj.ContentLibrary, %formObj.contentID.Name, %currentContent ); + + // Delete the content. + %currentContent.delete(); + + // Update form Caption + %formObj.setCaption( $FormClassNoContentCaption ); + + } + } + + // Handle the Form content choices by obtaining the script build command + if( %contentObj.CreateFunction !$= "" ) + { + //*** Set the name first + %name = %contentObj.Name; + %formObj.setCaption(%name); + + // We set the content ID prior to calling the create function so + // that it may reference it's content to retrieve information about it. + %oldContentId = %formObj.contentID; + %formObj.contentID = %contentObj; + + %result = eval( %contentObj.CreateFunction @ "(" @ %formObj @ ");" ); + if(!%result) + { + //*** Couldn't set up the form's contents so set the name back. We need to + //*** do it like this to allow the form's contents to change the form caption + //*** if the above command worked. + %formObj.setCaption($FormClassNoContentCaption); + + // Restore Content ID. + %formObj.contentID = %oldContentID; + + // Notify Script of Failure. + if( %formObj.isMethod("onContentChangeFailure") ) + %formObj.onContentChangeFailure(); + } + else + { + // Add to Reference List. + %currentContent = %formObj.getObject( 1 ); + if( isObject( %currentContent ) ) + GuiFormManager::AddContentReference( %formObj.ContentLibrary, %contentObj.Name, %currentContent ); + + %formObj.Content = %formObj.contentId.name; + + // Notify Script of Content Change + if( %formObj.isMethod("onContentChanged") ) + %formObj.onContentChanged( %contentObj ); + + return %result; + } + } + return 0; +} + + +// +// Create a given content library content instance on a given parent control and +// reference count it in the ref manager. +// +function GuiFormClass::SetControlContent( %controlObj, %contentLibrary, %contentObj ) +{ + // Validate New Content. + if( !isObject( %contentObj ) ) + { + // Failure + error("GuiFormClass::SetControlContent- No Valid Content Object!" ); + return 0; + } + + // Remove any other content from the Form + if( isObject( %controlObj.ContentID ) ) + { + // Find Control of current content internal name on the control. + %currentContent = %controlObj.findObjectByInternalName( %controlObj.ContentID.Name ); + + if( isObject( %currentContent ) ) + { + + // Notify Script of Content Changing. + if( %controlObj.isMethod("onContentChanging") ) + %controlObj.onContentChanging( %contentObj ); + + // Remove from Reference List. + GuiFormManager::RemoveContentReference( %contentLibrary, %controlObj.contentID.Name, %currentContent ); + + // Delete the content. + %currentContent.delete(); + + } + } + + // Handle the Form content choices by obtaining the script build command + if( %contentObj.CreateFunction !$= "" ) + { + %name = %contentObj.Name; + + // We set the content ID prior to calling the create function so + // that it may reference it's content to retrieve information about it. + %oldContentId = %controlObj.contentID; + %controlObj.contentID = %contentObj; + + %currentContent = eval( %contentObj.CreateFunction @ "(" @ %controlObj @ ");" ); + if( !isObject( %currentContent ) ) + { + // Restore Content ID. + %controlObj.contentID = %oldContentID; + + // Notify Script of Failure. + if( %controlObj.isMethod("onContentChangeFailure") ) + %controlObj.onContentChangeFailure(); + } + else + { + // Add to Reference List. + GuiFormManager::AddContentReference( %contentLibrary, %contentObj.Name, %currentContent ); + + // Store Internal Name + %currentContent.setInternalName( %contentObj.Name ); + + // Store Content + %controlObj.Content = %controlObj.contentId.name; + + // Notify Script of Content Change + if( %controlObj.isMethod("onContentChanged") ) + %controlObj.onContentChanged( %contentObj ); + + return %currentContent; + } + } + return 0; +} + +// +// Remove a given library content instance from a control that is housing it. +// +function GuiFormClass::ClearControlContent( %controlObj, %contentLibrary ) +{ + + // Remove any other content from the Form + if( isObject( %controlObj.ContentID ) ) + { + // Find Control of current content internal name on the control. + %currentContent = %controlObj.findObjectByInternalName( %controlObj.ContentID.Name ); + + if( isObject( %currentContent ) ) + { + + // Notify Script of Content Changing. + if( %controlObj.isMethod("onContentClearing") ) + %controlObj.onContentClearing( %controlObj.ContentID ); + + // Remove from Reference List. + GuiFormManager::RemoveContentReference( %contentLibrary, %controlObj.contentID.Name, %currentContent ); + + // Delete the content. + %currentContent.delete(); + } + } +} + + +// +// This will change to something more abstract in the near future, or will be moved into +// the level editor if there is no concise way to abstract it. +// +// Turn a form into a split frame and add the form back and build a new blank +// form in the empty slot. %horizontal==ture then make a horizontal split, otherwise +// make a vertical one. +function GuiFormClass::AddFrameSplitToForm(%formid, %horizontal) +{ + %formparent = %formid.getGroup(); + + // Get form position and size + %pos = %formid.position; + %ext = %formid.extent; + %rows = "0"; + %columns = "0"; + if(%horizontal) + { + %framesplit = getWord(%ext,1) / 2; + %rows = "0 " @ %framesplit; + } + else + { + %framesplit = getWord(%ext,0) / 2; + %columns = "0 " @ %framesplit; + } + + // If the form's parent is a frame control and this form is the first control then + // we will need to move it to the front of the other children later on. Otherwise + // we'll be added to the bottom of the stack and the order will get messed up. + // This all assumes that a frame control only has two children. + %secondctrl = -1; + if(%formparent.getClassName() $= "GuiFrameSetCtrl") + { + //error("Form parent is GuiFrameSetCtrl"); + if(%formparent.getObject(0) == %formid) + { + // This form is the first child. + //error("Form is at the top"); + %secondctrl = %formparent.getObject(1); + } + } + + // If we're adding a frameset around the layout base, propogate the + // layoutRef and layoutObj's to the new parent. + if( %formID.LayoutRef !$= "" ) + %LayoutRef = %formID.LayoutRef; + else + %LayoutRef = 0; + + + // Remove form from parent, put a frame control in its place, and then add this form back to the frame + %formparent.remove(%formid); + %frame = GuiFormClass::BuildEmptyFrame(%pos, %ext, %columns, %rows, %formparent); + + if( %layoutRef != 0 ) + { + %frame.LayoutRef = %LayoutRef; + %frame.LayoutRef.layoutObj = %frame; + %frame.setCanSave( true ); + } + if(%secondctrl != -1) + { + // Move this frame to the top of its parent's children stack by removing the + // other child and adding it back again. This will force this second child to + // the bottom and our new frame back to the first child (the same location the + // original form was). Whew! Maybe the frame control needs to be modified to + // handle this. + //error("Moving to the top"); + %formparent.remove(%secondctrl); + %formparent.add(%secondctrl); + } + %frame.add(%formid); + + // Add a blank form to the bottom frame + GuiFormClass::BuildFormControl(%frame, %formid.ContentLibrary ); + + //error("New parent: " @ %frame SPC "(" @ %frame.getClassName() @ ")"); +} + +// +// This will change to something more abstract in the near future, or will be moved into +// the level editor if there is no concise way to abstract it. +// +//*** Remove a form's frame and any other of the frame's children and put the given +//*** form in its place, effectively removing the split. %keepform==true then remove +//*** all children of a parent Frame Set and keep the given Form. Otherwise, remove +//*** the given Form and keep the other child. +function GuiFormClass::RemoveFrameSplit(%formid, %keepform) +{ + //*** Get the form's parent and make sure it is a frame GUI. Other wise do nothing. + %frameID = %formid.getGroup(); + if(%frameID.getClassName() !$= "GuiFrameSetCtrl") + return; + + //*** Get frame's position and size + %pos = %frameID.position; + %ext = %frameID.extent; + + if(%keepform) + { + %form = %frameID.getObject(0); + + // Remove from Reference List. + if(%form.getClassName() $= "GuiFormCtrl") + GuiFormManager::RemoveContentReference( %form.ContentLibrary, %form.contentID.Name, %form.getObject(1) ); + + //*** Go through the frame's children and remove them (which includes our form) + %frameID.clear(); + } + else + { + + // Remove from Reference List. + if( %formId.getClassName() $= "GuiFormCtrl" ) + GuiFormManager::RemoveContentReference( %formId.ContentLibrary, %formId.contentID.Name, %formId.getObject(1) ); + + //*** Store the first child that is not the given Form + %count = %frameID.getCount(); + for(%i=0; %i < %count; %i++) + { + %child = %frameID.getObject(%i); + if(%child != %formid) + { + //*** This is the first child that isn't the given Form, so + //*** swap the given %formid with this new child so we keep it + %formid = %child; + break; + } + } + + //*** Now remove all children from the frame. + %frameID.clear(); + } + + //*** Obtain the frame's parent + %frameparentID = %frameID.getGroup(); + + //*** If the frame's parent is itself a frame, then track all of its children and add + //*** our form into the correct location, and remove our frame in the process. Otherwise + //*** just delete our frame and add our form to the parent. + if(%frameparentID.getClassName() $= "GuiFrameSetCtrl") + { + //*** Store the children + %count = %frameparentID.getCount(); + %check = -1; + for(%i=0; %i<%count; %i++) + { + %obj[%i] = %frameparentID.getObject(%i); + if(%obj[%i] == %frameID) + %check = %i; + } + + //*** Clear the existing children + %frameparentID.clear(); + + //*** Now add them back, including our form + for(%i=0; %i<%count; %i++) + { + if(%i == %check) + { + //*** Add our form + %frameparentID.add(%formid); + + } + else + { + //*** Add the old child back + %frameparentID.add(%obj[%i]); + } + } + + } else + { + // If we're about to remove a frame that has a layout ref move it to the new object (%formID) + if( %frameID.LayoutRef !$= "" ) + { + %formID.LayoutRef = %frameID.LayoutRef; + // By default if a control has been added to a form it will tag itself as cannot save. + // just to be safe, we mark it as we can since it's clearly now becoming the root of a layout. + %formID.LayoutRef.layoutObj = %formID; + %formID.setCanSave( true ); + } + //*** Remove old child and add our form to the parent + %frameparentID.remove(%frameID); + %frameparentID.add(%formid); + + } + + //*** Finally resize the form to fit + %formid.resize(getWord(%pos,0),getWord(%pos,1),getWord(%ext,0),getWord(%ext,1)); +} + + +// +// This will change to something more abstract in the near future, or will be moved into +// the level editor if there is no concise way to abstract it. +// +//*** Will resize the Form's content to fit. This is usually done at the beginning when +//*** the content is first added to the form. +function FormControlClass::sizeContentsToFit(%this, %content, %margin) +{ + %formext = %this.getExtent(); + %menupos = %this.getObject(0).getPosition(); + %menuext = %this.getObject(0).getExtent(); + + %ctrlposx = getWord(%menupos,0) + %this.contentID.Margin; + %ctrlposy = getWord(%menupos,1) + getWord(%menuext,1) + %this.contentID.Margin; + %ctrlextx = getWord(%formext,0) - %ctrlposx - %this.contentID.Margin; + %ctrlexty = getWord(%formext,1) - %ctrlposy - %this.contentID.Margin; + + %content.resize(%ctrlposx,%ctrlposy,%ctrlextx,%ctrlexty); +} + +// +// This will change to something more abstract in the near future, or will be moved into +// the level editor if there is no concise way to abstract it. +// +function FormControlClass::onResize(%this) +{ + //*** If this form has a content child, then pass along this resize notice + //*** to allow it to do something. + if(%this.getCount() > 1) + { + %child = %this.getObject(1); + if( isObject( %child ) ) + %this.sizeContentsToFit( %child ); + + if( %child.isMethod("onResize") ) + %child.onResize(%this); + } +} + +// +// This will change to something more abstract in the near future, or will be moved into +// the level editor if there is no concise way to abstract it. +// +function FormMenuBarClass::onMenuItemSelect(%this, %menuid, %menutext, %itemid, %itemtext) +{ + %formId = %menuid; // %menuid should contain the form's ID + + //error("FormMenuBarClass::onMenuSelect(): " @ %menuid SPC %menutext SPC %itemid SPC %itemtext SPC "parent: " @ %formparent); + + // If the ID is less than 1000, we know it's a layout menu item + if( %itemid < 1000 ) + { + // Handle the standard menu choices + switch(%itemid) + { + case "1": // Add horizontal split + GuiFormClass::AddFrameSplitToForm(%formid, true); + + case "2": // Add vertical split + GuiFormClass::AddFrameSplitToForm(%formid, false); + case "3": // Remove split and keep other child + GuiFormClass::RemoveFrameSplit(%formid, false); + } + + // We're Done Here. + return; + } + else + GuiFormClass::SetFormContent( %formId, %itemId ); + + +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/editorClasses/scripts/guiFormContentManager.ed.cs b/Templates/Empty/game/tools/editorClasses/scripts/guiFormContentManager.ed.cs new file mode 100644 index 000000000..5af210109 --- /dev/null +++ b/Templates/Empty/game/tools/editorClasses/scripts/guiFormContentManager.ed.cs @@ -0,0 +1,190 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- +$FormClassNoContentCaption = "None"; + +//----------------------------------------------------------------------------- +// Add Form Content to a Library or Update if it Already Exists +// +// Returns : Content ID or 0. +//----------------------------------------------------------------------------- +function GuiFormManager::AddFormContent( %library, %contentName, %contentCreate, %contentSave, %contentMargin ) +{ + // See if we were passed a library ID. + if( !isObject( %library ) ) + %libraryObj = GuiFormManager::FindLibrary( %library ); + else + %libraryObj = %library; + + // See if we Found the Library. + if( %libraryObj == 0 || !isObject( %libraryObj ) ) + { + error( "GuiFormManager::AddFormContent - Unable to Find Library by Name or ID!" ); + return 0; + } + + // See if this reference already exists. + %contentRef = GuiFormManager::FindFormContent( %libraryObj, %contentName ); + + // If it exists, just update it's create/save functions. + if( %contentRef != 0 ) + { + // Echo Update. + //echo( "GuiFormManager::AddFormContent - Found Existent Content Reference, Updating Create/Save Functions" ); + + // Apply Update. + %contentRef.CreateFunction = %contentCreate; + %contentRef.SaveFunction = %contentSave; + %contentRef.Margin = %contentMargin; + + // Return Success. + return %contentRef; + } + + // Create Content Reference List. + %refList = new SimSet(); + + // Add Reference List to Library. + %libraryObj.getObject(0).add( %refList ); + + // Create Content Reference Object. + %newContentRef = new ScriptObject() + { + Name = %contentName; + CreateFunction = %contentCreate; + SaveFunction = %contentSave; + Margin = %contentMargin; + RefList = %refList; + }; + + // Add to library. + %libraryObj.add( %newContentRef ); + + // Return Success. + return %newContentRef; +} + +//----------------------------------------------------------------------------- +// Remove Form Content from a Library +// +// Returns : True or False. +//----------------------------------------------------------------------------- +function GuiFormManager::RemoveFormContent( %library, %contentName ) +{ + // See if we were passed a library ID. + if( !isObject( %library ) ) + %libraryObj = GuiFormManager::FindLibrary( %library ); + else + %libraryObj = %library; + + // See if we Found the Library. + if( %libraryObj == 0 || !isObject( %libraryObj ) ) + return false; + + // See if this reference already exists. + %contentRef = GuiFormManager::FindFormContent( %libraryObj, %contentName ); + + // If it doesn't exist, just return success. + if( %contentRef == 0 || !isObject( %contentRef ) ) + return true; + + // Remove From Library. + %libraryObj.remove( %contentRef ); + + // Return Success. + return true; +} + + +//----------------------------------------------------------------------------- +// Find Form Content in a Library +// +// Returns : Content Reference Object ID or 0. +//----------------------------------------------------------------------------- +function GuiFormManager::FindFormContent( %library, %contentName ) +{ + // See if we were passed a library ID. + if( !isObject( %library ) ) + %libraryObj = GuiFormManager::FindLibrary( %library ); + else + %libraryObj = %library; + + // See if we Found the Library. + if( %libraryObj == 0 || !isObject( %libraryObj ) ) + return 0; + + // Look for the content by name in our library. + for( %i = 0; %i < %libraryObj.getCount(); %i++ ) + { + %object = %libraryObj.getObject( %i ); + if( %object.Name $= %contentName ) + return %object; + } + + // Return Failure. + return 0; +} + +//----------------------------------------------------------------------------- +// Get Form Content in a Library by Index +// +// Returns : Content Reference Object ID or 0. +//----------------------------------------------------------------------------- +function GuiFormManager::GetFormContentByIndex( %library, %index ) +{ + // See if we were passed a library ID. + if( !isObject( %library ) ) + %libraryObj = GuiFormManager::FindLibrary( %library ); + else + %libraryObj = %library; + + // See if we Found the Library. + if( %libraryObj == 0 || !isObject( %libraryObj ) ) + return 0; + + if( %index < %libraryObj.getCount() ) + return %libraryObj.getObject( %index ); + +} + + +//----------------------------------------------------------------------------- +// Get Form Content Count in a Library +// +// Returns : Number of content objects in this library or 0 +//----------------------------------------------------------------------------- +function GuiFormManager::GetFormContentCount( %library ) +{ + // See if we were passed a library ID. + if( !isObject( %library ) ) + %libraryObj = GuiFormManager::FindLibrary( %library ); + else + %libraryObj = %library; + + // See if we Found the Library. + if( %libraryObj == 0 || !isObject( %libraryObj ) ) + { + return 0; + } + + // Return Count. + return %libraryObj.getCount(); +} diff --git a/Templates/Empty/game/tools/editorClasses/scripts/guiFormLayoutManager.ed.cs b/Templates/Empty/game/tools/editorClasses/scripts/guiFormLayoutManager.ed.cs new file mode 100644 index 000000000..cc449b24c --- /dev/null +++ b/Templates/Empty/game/tools/editorClasses/scripts/guiFormLayoutManager.ed.cs @@ -0,0 +1,394 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +// Register a Content Library Layout +// +// Returns : Layout Object ID or 0. +//----------------------------------------------------------------------------- +function GuiFormManager::InitLayouts( %libraryName, %layoutName, %layoutObj ) +{ + // Retrieve Library Object + %libraryObj = GuiFormManager::FindLibrary( %libraryName ); + if( %libraryObj == 0 ) + { + error("GuiFormManager::RegisterLayout - Unable to find Library" SPC %libraryName ); + return 0; + } + + // Load up all Layouts in the layout base path. + loadDirectory( %libraryObj.basePath, "cs", "dso" ); + +} + +//----------------------------------------------------------------------------- +// Register a Content Library Layout +// +// Returns : True or False. +//----------------------------------------------------------------------------- +function GuiFormManager::RegisterLayout( %libraryName, %layoutName, %layoutObj ) +{ + // Retrieve Library Object + %libraryObj = GuiFormManager::FindLibrary( %libraryName ); + if( %libraryObj == 0 ) + { + error("GuiFormManager::RegisterLayout - Unable to find Library" SPC %libraryName ); + return false; + } + + // Retrieve Layout Group + %layoutGroup = %libraryObj.getObject( 1 ); + if( !isObject( %layoutGroup ) ) + { + error("GuiFormManager::RegisterLayout - Unable to locate layout group!"); + return false; + } + + // See if a layout with this name already exists. + if( GuiFormManager::FindLayout( %libraryName, %layoutName ) != 0 ) + { + error("GuiFormManager::RegisterLayout - Layout with name" SPC %layoutName SPC "already exists!"); + return false; + } + + %layoutRef = new ScriptObject() + { + layoutGroup = %layoutGroup; + layoutName = %layoutName; + layoutLibrary = %libraryObj; + layoutObj = %layoutObj; + layoutFile = %libraryObj.basePath @ %layoutName @ ".cs"; + }; + + // Tag Layout Object Properly so it can reset itself. + %layoutObj.layoutRef = %layoutRef; + + // Add Layout Object to group. + %layoutGroup.add( %layoutObj ); + + // Add Layout Object Ref to group. + %layoutGroup.add( %layoutRef ); + + // Return Success. + return true; +} + +//----------------------------------------------------------------------------- +// Unregister a Content Library Layout +// +// Returns : True or False. +//----------------------------------------------------------------------------- +function GuiFormManager::UnregisterLayout( %libraryName, %layoutName, %deleteFile ) +{ + %libraryObj = GuiFormManager::FindLibrary( %libraryName ); + if( %libraryObj == 0 ) + { + error("GuiFormManager::UnregisterLayout - Unable to find Library" SPC %libraryName ); + return false; + } + + // See if the layout exists. + %layoutObjRef = GuiFormManager::FindLayout( %libraryObj, %layoutName ); + + if( %layoutObjRef == 0 ) + return true; + + // Remove Layout File. + if( ( %deleteFile == true ) && isFile( %layoutObjRef.layoutFile ) ) + fileDelete( %layoutObjRef.layoutFile ); + + // Delete the Object. + if( isObject( %layoutObjRef.layoutObj ) ) + %layoutObjRef.layoutObj.delete(); + + // Delete the Reference + %layoutObjRef.delete(); + + // Layout Unregistered. + return true; + +} + +//----------------------------------------------------------------------------- +// Find a Content Library Layout +// +// Returns : Layout Object ID or 0. +//----------------------------------------------------------------------------- +function GuiFormManager::FindLayout( %libraryName, %layoutName ) +{ + // Fetch Library Object. + if( isObject( %libraryName ) && %libraryName.Name !$= "" ) + %libraryName = %libraryName.Name; + + %libraryObj = GuiFormManager::FindLibrary( %libraryName ); + + if( %libraryObj == 0 ) + { + error("GuiFormManager::FindLayout - Unable to find Library" SPC %libraryName ); + return 0; + } + + // Retrieve Layout Group + %layoutGroup = %libraryObj.getObject( 1 ); + if( !isObject( %layoutGroup ) ) + { + error("GuiFormManager::FindLayout - Unable to locate layout group!"); + return 0; + } + + // Find Layout Object. + for( %i = 0; %i < %layoutGroup.getCount(); %i++ ) + { + %layoutGroupIter = %layoutGroup.getObject( %i ); + if( %layoutGroupIter.getClassName() $= "ScriptObject" && %layoutGroupIter.layoutName $= %layoutName ) + return %layoutGroupIter; + } + + // Not Found + return 0; +} + +//----------------------------------------------------------------------------- +// Save a Content Library Layout +// +// Returns : True or False +//----------------------------------------------------------------------------- +function GuiFormManager::SaveLayout( %library, %layoutName, %newName ) +{ + %libraryObj = GuiFormManager::FindLibrary( %library ); + if( %libraryObj == 0 ) + { + error("GuiFormManager::SaveLayout - Unable to find Library" SPC %library ); + return false; + } + + %layoutObjRef = GuiFormManager::FindLayout( %library, %layoutName ); + if( %layoutObjRef == 0 ) + { + error("GuiFormManager::SaveLayout - Cannot find layout" SPC %layoutName ); + return false; + } + + // Do any form layout specifics saving. + GuiFormManager::SaveLayoutContent( %layoutObjRef.layoutObj ); + + %newFile = %libraryObj.basePath @ "/" @ %newName @ ".cs"; + if( %newName $= "" ) + { + %newName = %layoutObjRef.layoutName; + %newFile = %layoutObjRef.layoutFile; + } + + // Open Layout File Object. + %layoutFile = new FileObject(); + if( !%layoutFile.openForWrite( %newFile ) ) + { + error("GuiFormManager::SaveLayout - Unable to open" SPC %newFile SPC "for writing!"); + %layoutFile.delete(); + return false; + } + + // Get Layout Object + %layoutObj = %layoutObjRef.layoutObj; + + // Write Layout Object to File + %layoutFile.writeObject( %layoutObj, "%layoutObj = " ); + %layoutFile.writeLine("GuiFormManager::RegisterLayout(\"" @ %libraryObj.name @ "\",\"" @ %newName @ "\",%layoutObj);" ); + %layoutFile.close(); + %layoutFile.delete(); + + // Layout Saved + return true; + +} + +//----------------------------------------------------------------------------- +// Reload The Current Layout from the version last stored on disk. +// +// Returns : True or False +//----------------------------------------------------------------------------- +function GuiFormManager::ReloadLayout( %libraryName, %layoutName, %parent ) +{ + %layoutObj = GuiFormManager::FindLayout( %libraryName, %layoutName ); + if( %layoutObj == 0 || !isObject( %layoutObj ) ) + { + error("GuiFormManager::ReloadLayout - Unable to locate layout" SPC %layoutName SPC "in library" SPC %libraryName ); + return 0; + } + + // Store necessary layout info before the object is destroyed in UnregisterLayout. + %layoutFile = %layoutObj.layoutFile; + + // Unregister Layout but don't delete the layout file from disk. + if( !GuiFormManager::UnregisterLayout( %libraryName, %layoutName, false ) ) + { + error("GuiFormManager::ReloadLayout - Unable to unregister layout file" SPC %layoutFile ); + return 0; + } + + // Load the layout from disk. + exec( %layoutFile ); + + // Set it active. + GuiFormManager::ActivateLayout( %libraryName, %layoutName, %parent ); + + return true; +} + + +//----------------------------------------------------------------------------- +// Activate a Layout on a Given Parent. +// +// Returns : True or False +//----------------------------------------------------------------------------- +function GuiFormManager::ActivateLayout( %library, %layoutName, %parent ) +{ + %libraryObj = GuiFormManager::FindLibrary( %library ); + if( %libraryObj == 0 ) + { + error("GuiFormManager::FindLayout - Unable to find Library" SPC %library ); + return 0; + } + + %layoutObjRef = GuiFormManager::FindLayout( %library, %layoutName ); + if( %layoutObjRef == 0 ) + { + error("GuiFormManager::ActivateLayout - Cannot find layout" SPC %layoutName ); + return false; + } + + // Clear parent for new layout. + %parent.clear(); + + %layoutObj = %layoutObjRef.layoutObj; + + // Size to fit parent container. + %extent = %parent.getExtent(); + %layoutObj.setExtent( GetWord(%extent, 0), GetWord(%extent, 1) ); + + // Add to parent. + %parent.add( %layoutObj ); + + // Not Found + return true; +} + +//----------------------------------------------------------------------------- +// Deactivate a given layout. +// +// Returns : True or False +//----------------------------------------------------------------------------- +function GuiFormManager::DeactivateLayout( %library, %layoutName ) +{ + %libraryObj = GuiFormManager::FindLibrary( %library ); + if( %libraryObj == 0 ) + { + error("GuiFormManager::DeactivateLayout - Unable to find Library" SPC %library ); + return 0; + } + + %layoutObjRef = GuiFormManager::FindLayout( %library, %layoutName ); + if( %layoutObjRef == 0 ) + { + error("GuiFormManager::DeactivateLayout - Cannot find layout" SPC %layoutName ); + return false; + } + + // Retrieve Layout Group + %layoutGroup = %libraryObj.getObject( 1 ); + if( !isObject( %layoutGroup ) ) + { + error("GuiFormManager::RegisterLayout - Unable to locate layout group!"); + return 0; + } + + // Fetch Layout Object + %layoutObj = %layoutObjRef.layoutObj; + + // Clear all forms content. + GuiFormManager::ClearLayoutContent( %layoutObj ); + + // Return layout to it's home. + %layoutGroup.add( %layoutObj ); + + // Not Found + return true; +} + +//----------------------------------------------------------------------------- +// Recursively Remove Form Content +// +// Returns : None. +//----------------------------------------------------------------------------- +function GuiFormManager::SaveLayoutContent( %layoutObj ) +{ + for( %i = 0; %i < %layoutObj.getCount(); %i++ ) + { + %object = %layoutObj.getObject( %i ); + if( %object.isMemberOfClass( "SimGroup" ) ) + { + %formContent = 0; + if (%object.getCount() > 0) + %formContent = %object.getObject( 1 ); + + if( isObject( %formContent ) && %object.ContentLibrary !$= "" && %object.Content !$= "" ) + { + %contentObj = GuiFormManager::FindFormContent( %object.ContentLibrary, %object.Content ); + if( %contentObj == 0 ) + { + error("GuiFormManager::SaveLayoutContent - Content Library Specified But Content Not Found!" ); + return; + } + + if( %contentObj.SaveFunction !$= "" ) + eval( %contentObj.SaveFunction @ "(" @ %object @ "," @ %formContent @ ");" ); + } + } + else + GuiFormManager::SaveLayoutContent( %object ); + } +} + +//----------------------------------------------------------------------------- +// Recursively Remove Form Content +// +// Returns : None. +//----------------------------------------------------------------------------- +function GuiFormManager::ClearLayoutContent( %layoutObj ) +{ + for( %i = 0; %i < %layoutObj.getCount(); %i++ ) + { + %object = %layoutObj.getObject( %i ); + if( %object.getClassName() $= "GuiFormCtrl" ) + { + // Clear Content ID So that onWake recreates the content. + %object.ContentID = ""; + + %formContent = %object.getObject( 1 ); + if( isObject( %formContent ) ) + %formContent.delete(); + } + else + GuiFormManager::ClearLayoutContent( %object ); + } +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/editorClasses/scripts/guiFormLibraryManager.ed.cs b/Templates/Empty/game/tools/editorClasses/scripts/guiFormLibraryManager.ed.cs new file mode 100644 index 000000000..e8918aa92 --- /dev/null +++ b/Templates/Empty/game/tools/editorClasses/scripts/guiFormLibraryManager.ed.cs @@ -0,0 +1,161 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Register a Content Library +// +// Returns : Library Object ID or 0. +//----------------------------------------------------------------------------- +function GuiFormManager::RegisterLibrary( %libraryName, %libraryBasePath ) +{ + %libraryPrepend = "GFCM"; + %newLibraryObjectName = %libraryPrepend @ %libraryName; + + // If the library already exists, just return it's object. + if( isObject( %newLibraryObjectName ) ) + return %newLibraryObjectName.getId(); + + // We must have the content manager to continue. + if( !isObject( FormContentManager ) ) + { + error("GuiFormManager::RegisterLibrary - Unable to find FormContentManager object!"); + return 0; + } + + // Create Content Library. + %newLibrary = new SimGroup( %newLibraryObjectName ) + { + Name = %libraryName; + }; + + // Expand Base Path + %libraryFullPath = getPrefsPath( %libraryBasePath ); + + // Store disk base path + %newLibrary.basePath = %libraryFullPath; + + // Ensure Path Exists + createPath( %libraryFullPath ); + + // Add Library to Content Manager. + FormContentManager.add( %newLibrary ); + + // Create Content Library Ref Group. + %newLibraryRefGroup = new SimGroup(); + %newLibraryRefGroup.setInternalName("RefGroup"); + %newLibrary.add( %newLibraryRefGroup ); + + // Create Content Library Layout Group. + %newLibraryLayoutGroup = new SimGroup(); + %newLibraryLayoutGroup.setInternalName("LayoutGroup"); + %newLibrary.add( %newLibraryLayoutGroup ); + + // Add Library to Content Manager. + FormContentManager.add( %newLibrary ); + + + // Add [none] Content. + GuiFormManager::AddFormContent( %libraryName, $FormClassNoContentCaption ); + + // Return Library Object. + return %newLibrary; + +} + +//----------------------------------------------------------------------------- +// Unregister a Content Library +// +// Returns : True or False. +//----------------------------------------------------------------------------- +function GuiFormManager::UnregisterLibrary( %libraryName ) +{ + // Find Library Object. + %libraryObj = GuiFormManager::FindLibrary( %libraryName ); + + if( !isObject( FormContentManager ) || !isObject( %libraryObj ) ) + { + error("GuiFormManager::RegisterLibrary - Unable to find GuiFormManager or Library!"); + return false; + } + + // Remove all Content Reference Objects in this Library. + while( %libraryObj.getCount() > 0 ) + { + if( isObject( %libraryObj.getObject( 0 ) ) ) + %libraryObj.getObject( 0 ).delete(); + %libraryObj.remove( 0 ); + } + // Delete the library + %libraryObj.delete(); + + // Return Success. + return true; + +} + + +//----------------------------------------------------------------------------- +// Find a Content Library +// +// Returns : Library Object ID or 0. +//----------------------------------------------------------------------------- +function GuiFormManager::FindLibrary( %libraryName ) +{ + // Generate Library Name. + %libraryObjectName = "GFCM" @ %libraryName; + + // Find Library by Name. + if( isObject( %libraryObjectName ) ) + return %libraryObjectName.getId(); + + // Didn't find by name, see if this is already a library ID. + if( isObject( %libraryName ) ) + return %libraryName; + + // Couldn't Find Library + return 0; +} + + +function GuiFormManager::Init() +{ + // Create SimGroup. + new SimGroup( FormContentManager ){}; +} + + +function GuiFormManager::Destroy() +{ + while( FormContentManager.getCount() > 0 ) + { + %object = FormContentManager.getObject( 0 ); + + if( isObject( %object ) ) + GuiFormManager::BroadcastContentMessage( %object, FormContentManager, "onLibraryDestroyed" ); + + FormContentManager.remove( %object ); + } + + // Destroy SimGroup. + if( isObject( FormContentManager ) ) + FormContentManager.delete(); +} diff --git a/Templates/Empty/game/tools/editorClasses/scripts/guiFormMessageManager.ed.cs b/Templates/Empty/game/tools/editorClasses/scripts/guiFormMessageManager.ed.cs new file mode 100644 index 000000000..4fee6e8b7 --- /dev/null +++ b/Templates/Empty/game/tools/editorClasses/scripts/guiFormMessageManager.ed.cs @@ -0,0 +1,126 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Send a Message to all instances of a Content. +// +// Returns : The Number of Objects Communicated With or (0 if None). +//----------------------------------------------------------------------------- +function GuiFormManager::SendContentMessage( %contentObj, %sender, %message ) +{ + // See if we Found the content object. + if( %contentObj == 0 || !isObject( %contentObj ) ) + { + //error( "GuiFormManager::SendContentMessage - Invalid Content Specified!" ); + return 0; + } + + // Validate Ref List. + if( !isObject( %contentObj.RefList ) ) + { + //error( "GuiFormManager::SendContentMessage - Unable to find content RefList!" ); + return 0; + } + + %refListObj = %contentObj.RefList.getID(); + + %messagedObjects = 0; + // Look for the content by name in our library. + for( %i = 0; %i < %refListObj.getCount(); %i++ ) + { + %object = %refListObj.getObject( %i ); + + // Check for alternate MessageControl + if( isObject( %object.MessageControl ) && %object.MessageControl.isMethod("onContentMessage") ) + %object.MessageControl.onContentMessage( %sender, %message ); + else if( %object.isMethod("onContentMessage") ) // Check for Default + %object.onContentMessage( %sender, %message ); + else + continue; + %messagedObjects++; + } + + // Return Success. + return %messagedObjects; +} + + + +//----------------------------------------------------------------------------- +// Send a Message to all instances of all Content. +// +// Returns : The Number of Objects Communicated With or (0 if None). +//----------------------------------------------------------------------------- +function GuiFormManager::BroadcastContentMessage( %libraryName, %sender, %message ) +{ + %libraryObj = GuiFormManager::FindLibrary( %libraryName ); + // See if we Found the content object. + if( %libraryObj == 0 || !isObject( %libraryObj ) ) + { + //error( "GuiFormManager::BroadcastContentMessage - Invalid Library Specified!" ); + return 0; + } + + // In a library the 0 object is always the ref group. + %contentRefGroup = %libraryObj.getObject( 0 ); + + // Validate Ref Group. + if( !isObject( %contentRefGroup ) ) + { + //error( "GuiFormManager::BroadcastContentMessage - Unable to find library RefGroup!" ); + return 0; + } + + // Clear messaged object count + %messagedObjects = 0; + + // Iterate over all contents ref lists and message everyone + for( %refGroupIter = 0; %refGroupIter < %contentRefGroup.getCount(); %refGroupIter++ ) + { + + // Fetch the Object Reference List Set + %refListSet = %contentRefGroup.getObject( %refGroupIter ); + + + // Look for the content by name in our library. + for( %i = 0; %i < %refListSet.getCount(); %i++ ) + { + %object = %refListSet.getObject( %i ); + + // Check for alternate MessageControl + if( isObject( %object.MessageControl ) && %object.MessageControl.isMethod("onContentMessage") ) + %object.MessageControl.onContentMessage( %sender, %message ); + else if( %object.isMethod("onContentMessage") ) // Check for Default + %object.onContentMessage( %sender, %message ); + else + continue; + + // Increment Messaged Object Count. + %messagedObjects++; + } + + } + + // Return Success. + return %messagedObjects; +} + diff --git a/Templates/Empty/game/tools/editorClasses/scripts/guiFormReferenceManager.ed.cs b/Templates/Empty/game/tools/editorClasses/scripts/guiFormReferenceManager.ed.cs new file mode 100644 index 000000000..811947bbb --- /dev/null +++ b/Templates/Empty/game/tools/editorClasses/scripts/guiFormReferenceManager.ed.cs @@ -0,0 +1,119 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +// Add Content Reference to RefList +// +// Returns : True or False. +//----------------------------------------------------------------------------- +function GuiFormManager::AddContentReference( %library, %contentName, %control ) +{ + // Fetch Content Object. + %contentObj = GuiFormManager::FindFormContent( %library, %contentName ); + + // See if we Found the Library. + if( %contentObj == 0 || !isObject( %contentObj ) ) + { + error( "GuiFormManager::AddContentReference - Unable to Find Library by Name or ID!" ); + return false; + } + + // Validate Ref List. + if( !isObject( %contentObj.RefList ) ) + { + error( "GuiFormManager::AddContentReference - Unable to find content RefList!" ); + return false; + } + + //error("adding ref for object" SPC %control ); + + // Add Control Reference. + %contentObj.RefList.add( %control ); + + // Return Success. + return true; +} + +//----------------------------------------------------------------------------- +// Remove Content Reference from RefList +// +// Returns : True or False. +//----------------------------------------------------------------------------- +function GuiFormManager::RemoveContentReference( %library, %contentName, %control ) +{ + // Fetch Content Object. + %contentObj = GuiFormManager::FindFormContent( %library, %contentName ); + + // See if we Found the Library. + if( %contentObj == 0 || !isObject( %contentObj ) ) + { + error( "GuiFormManager::AddContentReference - Unable to Find Library by Name or ID!" ); + return false; + } + + // Validate Ref List. + if( !isObject( %contentObj.RefList ) ) + { + error( "GuiFormManager::AddContentReference - Unable to find content RefList!" ); + return false; + } + + //error("removing ref for object" SPC %control ); + + // Add Control Reference. + %contentObj.RefList.remove( %control ); + + if( %control.isMethod("onFormRemove") ) + %control.onFormRemove(); + + // Return Success. + return true; +} + +//----------------------------------------------------------------------------- +// Gets the current number of instances of the specified content that are active +// +// Returns : Number of instances or 0. +//----------------------------------------------------------------------------- +function GuiFormManager::GetContentCount( %library, %contentName ) +{ + // Fetch Content Object. + %contentObj = GuiFormManager::FindFormContent( %library, %contentName ); + + // See if we Found the Library. + if( %contentObj == 0 || !isObject( %contentObj ) ) + { + error( "GuiFormManager::GetContentCount - Unable to Find Library by Name or ID!" ); + return 0; + } + + // Validate Ref List. + if( !isObject( %contentObj.RefList ) ) + { + error( "GuiFormManager::GetContentCount - Unable to find content RefList!" ); + return 0; + } + + // Return Count. + return %contentObj.RefList.getCount(); +} diff --git a/Templates/Empty/game/tools/editorClasses/scripts/input/applicationEvents.ed.cs b/Templates/Empty/game/tools/editorClasses/scripts/input/applicationEvents.ed.cs new file mode 100644 index 000000000..a4343f410 --- /dev/null +++ b/Templates/Empty/game/tools/editorClasses/scripts/input/applicationEvents.ed.cs @@ -0,0 +1,46 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +/// +/// Public Application Events +/// +Input::GetEventManager().registerEvent( "ClosePressed" ); +Input::GetEventManager().registerEvent( "BeginShutdown" ); +Input::GetEventManager().registerEvent( "FocusChanged" ); + +function onClosePressed() +{ + //error("% Application Close - User Pressed the X button on their window"); + Input::GetEventManager().postEvent( "ClosePressed" ); +} + +function onPreExit() +{ + //error("% Application Close - quit called or quit message received""); + Input::GetEventManager().postEvent( "BeginShutdown" ); +} + +function onWindowFocusChange( %focused ) +{ + //error("% Application Close - quit called or quit message received""); + Input::GetEventManager().postEvent( "FocusChanged", %focused ); +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/editorClasses/scripts/input/dragDropEvents.ed.cs b/Templates/Empty/game/tools/editorClasses/scripts/input/dragDropEvents.ed.cs new file mode 100644 index 000000000..70582bd20 --- /dev/null +++ b/Templates/Empty/game/tools/editorClasses/scripts/input/dragDropEvents.ed.cs @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +/// +/// Public DragDrop Events +/// +Input::GetEventManager().registerEvent( "BeginDropFiles" ); +Input::GetEventManager().registerEvent( "DropFile" ); +Input::GetEventManager().registerEvent( "EndDropFiles" ); + +function onDropBegin( %fileCount ) +{ + //error("% DragDrop - Beginning file dropping of" SPC %fileCount SPC " files."); + Input::GetEventManager().postEvent( "BeginDropFiles", %fileCount ); +} +function onDropFile( %filePath ) +{ + //error(" % DragDrop - Got File : " SPC %filePath ); + Input::GetEventManager().postEvent( "DropFile", %filePath ); +} +function onDropEnd( %fileCount ) +{ + + //error("% DragDrop - Completed file dropping"); + Input::GetEventManager().postEvent( "EndDropFiles" ); +} diff --git a/Templates/Empty/game/tools/editorClasses/scripts/input/inputEvents.ed.cs b/Templates/Empty/game/tools/editorClasses/scripts/input/inputEvents.ed.cs new file mode 100644 index 000000000..ba1b9e21a --- /dev/null +++ b/Templates/Empty/game/tools/editorClasses/scripts/input/inputEvents.ed.cs @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +/// +/// Returns Projects API's EventManager Singleton +/// +function Input::GetEventManager() +{ + if( !isObject( $_Tools::InputEventManager ) ) + $_Tools::InputEventManager = new EventManager() { queue = "InputEventManager"; }; + + return $_Tools::InputEventManager; +} diff --git a/Templates/Empty/game/tools/editorClasses/scripts/platform/.gitignore b/Templates/Empty/game/tools/editorClasses/scripts/platform/.gitignore new file mode 100644 index 000000000..1bc0e838a --- /dev/null +++ b/Templates/Empty/game/tools/editorClasses/scripts/platform/.gitignore @@ -0,0 +1 @@ +# Keep directory in git repo diff --git a/Templates/Empty/game/tools/editorClasses/scripts/preferencesManager.ed.cs b/Templates/Empty/game/tools/editorClasses/scripts/preferencesManager.ed.cs new file mode 100644 index 000000000..62f84b0d3 --- /dev/null +++ b/Templates/Empty/game/tools/editorClasses/scripts/preferencesManager.ed.cs @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//*** Initializes the Preferences Manager +function initPreferencesManager() +{ + // FIXME TGEA doesnt currently have these due to the way it's built + return; + + //*** Create the Preferences Manager singleton + %pm = new PreferencesManager(pref); + registerPreferencesManager(%pm.getId()); +} diff --git a/Templates/Empty/game/tools/editorClasses/scripts/projects/projectEvents.ed.cs b/Templates/Empty/game/tools/editorClasses/scripts/projects/projectEvents.ed.cs new file mode 100644 index 000000000..dc00a49a2 --- /dev/null +++ b/Templates/Empty/game/tools/editorClasses/scripts/projects/projectEvents.ed.cs @@ -0,0 +1,115 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +/// +/// Returns Projects API's EventManager Singleton +/// +function Projects::GetEventManager() +{ + if( !isObject( $_Tools::ProjectEventManager ) ) + $_Tools::ProjectEventManager = new EventManager() { queue = "ProjectEventManager"; }; + + return $_Tools::ProjectEventManager; +} + + +function Projects::DeclareProjectTarget( %projectTargetNamespace, %objectGlobalName ) +{ + // At some point it would be nice to have a console method + // on SimObject that supported validating that another object + // implemented all the methods provided by a given namespace. + // .validateInterface("myNamespace") or some such. + %projectObject = new ScriptMsgListener( %objectGlobalName ) + { + class = %projectTargetNamespace; + superclass = ProjectBase; + }; +} + +/// +/// Public Project Events +/// + +/// ProjectOpened +/// +/// is fired when a project has been opened and all bootstrap +/// processing has occured on the project object. +/// At this point it is safe for addons to do post-load processing +/// such as creating new create entries and other specific modifications +/// to the editor. +Projects::GetEventManager().registerEvent( "ProjectOpened" ); + +/// ProjectClosed +/// +/// is fired when a project is about to be closed and it's +/// resources destroyed by the base project class. Addons +/// should use this event to free any project specific resources +/// they have allocated, as well as saving of data where applicable. +Projects::GetEventManager().registerEvent( "ProjectClosed" ); + +/// ProjectDeploy +/// +/// is fired when a game is about to be run from the editor and on +/// this event addons and third party's should without scheduling or +/// other delaying calls, deploy any game data that the game will need +/// to it's game path. +/// +/// Example, the core package zip code intercepts this message and +/// builds and deploys a new core.zip if is necessary +Projects::GetEventManager().registerEvent( "ProjectDeploy" ); + +/// Currently Unused +Projects::GetEventManager().registerEvent( "ProjectFileAdded" ); +/// Currently Unused +Projects::GetEventManager().registerEvent( "ProjectFileRemoved" ); + +/// +/// ProjectOpen Event Handler +/// - %data is the project object to be opened +function ProjectBase::onProjectOpen( %this, %data ) +{ + error("onProjectOpen Handler not implemented for class -" SPC %this.class ); +} + +/// +/// ProjectClose Event Handler +/// +function ProjectBase::onProjectClose( %this, %data ) +{ + error("onProjectClose Handler not implemented for class -" SPC %this.class ); +} + +/// +/// ProjectAddFile Event Handler +/// +function ProjectBase::onProjectAddFile( %this, %data ) +{ + error("onProjectAddFile Handler not implemented for class -" SPC %this.class ); +} + +/// +/// ProjectRemoveFile Event Handler +/// +function ProjectBase::onProjectRemoveFile( %this, %data ) +{ + error("onProjectRemoveFile Handler not implemented for class -" SPC %this.class ); +} diff --git a/Templates/Empty/game/tools/editorClasses/scripts/projects/projectInternalInterface.ed.cs b/Templates/Empty/game/tools/editorClasses/scripts/projects/projectInternalInterface.ed.cs new file mode 100644 index 000000000..398eff6d9 --- /dev/null +++ b/Templates/Empty/game/tools/editorClasses/scripts/projects/projectInternalInterface.ed.cs @@ -0,0 +1,188 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +/// +/// Internal Project Events +/// +Projects::GetEventManager().registerEvent( "_ProjectCreate" ); +Projects::GetEventManager().registerEvent( "_ProjectOpen" ); +Projects::GetEventManager().registerEvent( "_ProjectClose" ); +Projects::GetEventManager().registerEvent( "_ProjectAddFile" ); +Projects::GetEventManager().registerEvent( "_ProjectRemoveFile" ); + +/// +/// Project Context Methods +/// + +function ProjectBase::isActive( %this ) +{ + if( Projects::GetEventManager().activeProject == %this.getId() ) + return true; + else + return false; +} + +function ProjectBase::getActiveProject( %this ) +{ + return Projects::GetEventManager().activeProject; +} + +function ProjectBase::setActive( %this ) +{ + %activeProject = %this.getActiveProject(); + + if( isObject( %activeProject ) ) + { + // If another is active, properly post a close event for now THEN + // and only then should we change the .activeProject field on the evtmgr + } + + Projects::GetEventManager().activeProject = %this; +} + +function ProjectBase::onAdd( %this ) +{ + // Subscribe to base events + Projects::GetEventManager().subscribe( %this, "_ProjectCreate", "_onProjectCreate" ); + Projects::GetEventManager().subscribe( %this, "_ProjectOpen", "_onProjectOpen" ); + Projects::GetEventManager().subscribe( %this, "_ProjectClose", "_onProjectClose" ); + Projects::GetEventManager().subscribe( %this, "_ProjectAddFile", "_onProjectAddFile" ); + Projects::GetEventManager().subscribe( %this, "_ProjectRemoveFile", "_onProjectRemoveFile" ); + +} + +function ProjectBase::onRemove( %this ) +{ + // Remove subscriptions to base events + Projects::GetEventManager().remove( %this, "_ProjectCreate" ); + Projects::GetEventManager().remove( %this, "_ProjectOpen" ); + Projects::GetEventManager().remove( %this, "_ProjectClose" ); + Projects::GetEventManager().remove( %this, "_ProjectAddFile" ); + Projects::GetEventManager().remove( %this, "_ProjectRemoveFile" ); + +} + +/// +/// Internal ProjectOpen Event Handler +/// - %data is the project file path to be opened +function ProjectBase::_onProjectOpen( %this, %data ) +{ + // Sanity check calling of this + if( !%this.isMethod( "onProjectOpen" ) ) + { + error("Incomplete Project Interface - onProjectOpen method is non-existent!"); + return false; + } + + if( !%this.LoadProject( %data ) ) + { + messageBox("Unable to Load Project", "The project file you're attempting to open was created with an incompatible version of this software\n\nConversion of 1.1.X projects will be addressed soon, we apologize for the inconvenience.","Ok","Error"); + + return false; + } + + %this.gamePath = filePath( %data ); + %this.projectFile = %data; + + %toggle = $Scripts::ignoreDSOs; + $Scripts::ignoreDSOs = true; + + %this.gameResPath = %this.gamePath @ "/*"; + + // Set current dir to game + setCurrentDirectory( %this.gamePath ); + + // Set ^game expando + setScriptPathExpando("project", %this.gamePath ); + setScriptPathExpando("game", %this.gamePath @ "/game" ); + + %this.onProjectOpen( %data ); + %this.setActive(); + + Projects::GetEventManager().postEvent( "ProjectOpened", %this ); + + $Scripts::ignoreDSOs = %toggle; + $pref::lastProject = %data; +} + +/// +/// Internal ProjectClose Event Handler +/// +function ProjectBase::_onProjectClose( %this, %data ) +{ + + Projects::GetEventManager().postEvent( "ProjectClosed", %this ); + + // Sanity check calling of this + if( !%this.isMethod( "onProjectClose" ) ) + error("Incomplete Project Interface - onProjectClose method is non-existent!"); + else + %this.onProjectClose( %data ); + + // Reset to tools directory + setCurrentDirectory( getMainDotCsDir() ); + + // Remove expandos + removeScriptPathExpando( "game" ); + removeScriptPathExpando( "project" ); +} + +/// +/// Internal ProjectCreate Event Handler (Optionally Inherited by public interface) +/// +function ProjectBase::_onProjectCreate( %this, %data ) +{ + // Force a write out of the project file + if( !%this.SaveProject( %data ) ) + return false; + + // Sanity check calling of this + if( %this.isMethod( "onProjectCreate" ) ) + %this.onProjectCreate( %data ); +} + + +/// +/// Internal ProjectAddFile Event Handler +/// +function ProjectBase::_onProjectAddFile( %this, %data ) +{ + // Sanity check calling of this + if( !%this.isMethod( "onProjectAddFile" ) ) + error("Incomplete Project Interface - onProjectAddFile method is non-existent!"); + else + %this.onProjectAddFile( %data ); + +} + +/// +/// Internal ProjectRemoveFile Event Handler +/// +function ProjectBase::_onProjectRemoveFile( %this, %data ) +{ + // Sanity check calling of this + if( !%this.isMethod( "onProjectRemoveFile" ) ) + error("Incomplete Project Interface - onProjectRemoveFile method is non-existent!"); + else + %this.onProjectRemoveFile( %data ); + +} diff --git a/Templates/Empty/game/tools/editorClasses/scripts/utility.ed.cs b/Templates/Empty/game/tools/editorClasses/scripts/utility.ed.cs new file mode 100644 index 000000000..e1dadfeee --- /dev/null +++ b/Templates/Empty/game/tools/editorClasses/scripts/utility.ed.cs @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function isInList( %word, %list ) +{ + %count = getWordCount( %list ); + for( %i = 0; %i < %count; %i++ ) + { + %entry = getWord( %list, %i ); + if( %word $= %entry ) + return true; + } + + return false; +} + +function isInFieldList(%word, %list) +{ + %count = getFieldCount( %list ); + for( %i = 0; %i < %count; %i++ ) + { + %entry = getField( %list, %i ); + if( %word $= %entry ) + return true; + } + + return false; +} diff --git a/Templates/Empty/game/tools/forestEditor/forestEditToolbar.ed.gui b/Templates/Empty/game/tools/forestEditor/forestEditToolbar.ed.gui new file mode 100644 index 000000000..d7f3d50a0 --- /dev/null +++ b/Templates/Empty/game/tools/forestEditor/forestEditToolbar.ed.gui @@ -0,0 +1,437 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ForestEditToolbar,EditorGuiGroup) { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "306 0"; + Extent = "800 40"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ForestEditToolbar"; + canSaveDynamicFields = "1"; + enabled = "1"; + + new GuiTextCtrl() { + text = "Brush Settings"; + maxLength = "255"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "6 7"; + Extent = "70 16"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiControl() { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "760 40"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiControl(ForestBrushSizeTextEditContainer) { + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "72 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Size"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "21 5"; + Extent = "47 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + text = "9"; + maxLength = "4"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "49 2"; + Extent = "42 18"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + AltCommand = "ForestTools->BrushTool.size = $ThisControl.getValue();"; + validate = "ForestEditorGui.validateBrushSize();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "textEdit"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "core/art/gui/images/dropslider"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "83 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(ForestBrushSizeSliderCtrlContainer);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Changes size of the brush"; + hovertime = "750"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapCtrl() { + bitmap = "core/art/gui/images/separator-h.png"; + wrap = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "200 3"; + Extent = "2 26"; + MinExtent = "1 1"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiControl(ForestBrushPressureTextEditContainer) { + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "208 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Pressure"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 5"; + Extent = "47 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + text = "100"; + maxLength = "3"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "49 2"; + Extent = "42 18"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "ForestTools->BrushTool.pressure = $ThisControl.getValue() / 100;"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "textEdit"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "core/art/gui/images/dropslider"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "83 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(ForestBrushPressureSliderCtrlContainer);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Changes the pressure"; + hovertime = "750"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapCtrl() { + bitmap = "core/art/gui/images/separator-h.png"; + wrap = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "336 3"; + Extent = "2 26"; + MinExtent = "1 1"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiControl(ForestBrushHardnessTextEditContainer) { + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "352 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Hardness"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 5"; + Extent = "47 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + text = "1"; + maxLength = "3"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "49 2"; + Extent = "42 18"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "ForestTools->BrushTool.hardness = $ThisControl.getValue() / 100);"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "textEdit"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "core/art/gui/images/dropslider"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "83 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(ForestBrushHardnessSliderCtrlContainer);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Changes the hardness curve."; + hovertime = "750"; + canSaveDynamicFields = "0"; + }; + }; + }; +}; + +new GuiMouseEventCtrl(ForestBrushSizeSliderCtrlContainer,EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "GuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(ForestBrushSizeTextEditContainer.position) + firstWord(ForestEditToolbar.position)+11 SPC + (getWord(ForestBrushSizeTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ForestTools->BrushTool.size = $ThisControl.value;"; + range = "1" SPC getWord(ETerrainEditor.maxBrushSize, 0); + ticks = "0"; + value = "0"; + }; +}; + +new GuiMouseEventCtrl(ForestBrushPressureSliderCtrlContainer,EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "GuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(ForestBrushPressureTextEditContainer.position) + firstWord(ForestEditToolbar.position) SPC + (getWord(ForestBrushPressureTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ForestTools->BrushTool.pressure = $ThisControl.value;"; + range = "0.01 1"; + ticks = "0"; + value = "0"; + }; +}; + +new GuiMouseEventCtrl(ForestBrushHardnessSliderCtrlContainer,EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "GuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(ForestBrushHardnessTextEditContainer.position) + firstWord(ForestEditToolbar.position) SPC + (getWord(TForestBrushHardnessTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ForestTools->BrushTool.hardness = $ThisControl.value;"; + range = "0 1"; + ticks = "0"; + value = "0"; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/forestEditor/forestEditor.cs b/Templates/Empty/game/tools/forestEditor/forestEditor.cs new file mode 100644 index 000000000..274f735a5 --- /dev/null +++ b/Templates/Empty/game/tools/forestEditor/forestEditor.cs @@ -0,0 +1,27 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +singleton GuiControlProfile (ForestEditorProfile) +{ + canKeyFocus = true; + category = "Editor"; +}; \ No newline at end of file diff --git a/Templates/Empty/game/tools/forestEditor/forestEditorGui.cs b/Templates/Empty/game/tools/forestEditor/forestEditorGui.cs new file mode 100644 index 000000000..d2c5b9737 --- /dev/null +++ b/Templates/Empty/game/tools/forestEditor/forestEditorGui.cs @@ -0,0 +1,466 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +// ForestEditorGui Script Methods + +function ForestEditorGui::setActiveTool( %this, %tool ) +{ + if ( %tool == ForestTools->BrushTool ) + ForestEditTabBook.selectPage(0); + + Parent::setActiveTool( %this, %tool ); +} + +/// This is called by the editor when the active forest has +/// changed giving us a chance to update the GUI. +function ForestEditorGui::onActiveForestUpdated( %this, %forest, %createNew ) +{ + %gotForest = isObject( %forest ); + + // Give the user a chance to add a forest. + if ( !%gotForest && %createNew ) + { + MessageBoxYesNo( "Forest", + "There is not a Forest in this mission. Do you want to add one?", + %this @ ".createForest();", "" ); + return; + } +} + +/// Called from a message box when a forest is not found. +function ForestEditorGui::createForest( %this ) +{ + if ( isObject( theForest ) ) + { + error( "Cannot create a second 'theForest' Forest!" ); + return; + } + + // Allocate the Forest and make it undoable. + new Forest( theForest ) + { + dataFile = ""; + parentGroup = "MissionGroup"; + }; + + MECreateUndoAction::submit( theForest ); + + ForestEditorInspector.inspect( theForest ); + + EWorldEditor.isDirty = true; +} + +function ForestEditorGui::newBrush( %this ) +{ + %internalName = getUniqueInternalName( "Brush", ForestBrushGroup, true ); + + %brush = new ForestBrush() + { + internalName = %internalName; + parentGroup = ForestBrushGroup; + }; + + MECreateUndoAction::submit( %brush ); + + ForestEditBrushTree.open( ForestBrushGroup ); + ForestEditBrushTree.buildVisibleTree(true); + %item = ForestEditBrushTree.findItemByObjectId( %brush ); + ForestEditBrushTree.clearSelection(); + ForestEditBrushTree.addSelection( %item ); + ForestEditBrushTree.scrollVisible( %item ); + + ForestEditorPlugin.dirty = true; +} + +function ForestEditorGui::newElement( %this ) +{ + %sel = ForestEditBrushTree.getSelectedObject(); + + if ( !isObject( %sel ) ) + %parentGroup = ForestBrushGroup; + else + { + if ( %sel.getClassName() $= "ForestBrushElement" ) + %parentGroup = %sel.parentGroup; + else + %parentGroup = %sel; + } + + %internalName = getUniqueInternalName( "Element", ForestBrushGroup, true ); + + %element = new ForestBrushElement() + { + internalName = %internalName; + parentGroup = %parentGroup; + }; + + MECreateUndoAction::submit( %element ); + + ForestEditBrushTree.clearSelection(); + ForestEditBrushTree.buildVisibleTree( true ); + %item = ForestEditBrushTree.findItemByObjectId( %element.getId() ); + ForestEditBrushTree.scrollVisible( %item ); + ForestEditBrushTree.addSelection( %item ); + + ForestEditorPlugin.dirty = true; +} + +function ForestEditorGui::deleteBrushOrElement( %this ) +{ + ForestEditBrushTree.deleteSelection(); + ForestEditorPlugin.dirty = true; +} + +function ForestEditorGui::newMesh( %this ) +{ + %spec = "All Mesh Files|*.dts;*.dae|DTS|*.dts|DAE|*.dae"; + + %dlg = new OpenFileDialog() + { + Filters = %spec; + DefaultPath = $Pref::WorldEditor::LastPath; + DefaultFile = ""; + ChangePath = true; + }; + + %ret = %dlg.Execute(); + + if ( %ret ) + { + $Pref::WorldEditor::LastPath = filePath( %dlg.FileName ); + %fullPath = makeRelativePath( %dlg.FileName, getMainDotCSDir() ); + %file = fileBase( %fullPath ); + } + + %dlg.delete(); + + if ( !%ret ) + return; + + %name = getUniqueName( %file ); + + %str = "datablock TSForestItemData( " @ %name @ " ) { shapeFile = \"" @ %fullPath @ "\"; };"; + eval( %str ); + + if ( isObject( %name ) ) + { + ForestEditMeshTree.clearSelection(); + ForestEditMeshTree.buildVisibleTree( true ); + %item = ForestEditMeshTree.findItemByObjectId( %name.getId() ); + ForestEditMeshTree.scrollVisible( %item ); + ForestEditMeshTree.addSelection( %item ); + + ForestDataManager.setDirty( %name, "art/forest/managedItemData.cs" ); + + %element = new ForestBrushElement() + { + internalName = %name; + forestItemData = %name; + parentGroup = ForestBrushGroup; + }; + + ForestEditBrushTree.clearSelection(); + ForestEditBrushTree.buildVisibleTree( true ); + %item = ForestEditBrushTree.findItemByObjectId( %element.getId() ); + ForestEditBrushTree.scrollVisible( %item ); + ForestEditBrushTree.addSelection( %item ); + + pushInstantGroup(); + %action = new MECreateUndoAction() + { + actionName = "Create TSForestItemData"; + }; + popInstantGroup(); + + %action.addObject( %name ); + %action.addObject( %element ); + %action.addToManager( Editor.getUndoManager() ); + + ForestEditorPlugin.dirty = true; + } +} + +function ForestEditorGui::deleteMesh( %this ) +{ + %obj = ForestEditMeshTree.getSelectedObject(); + + // Can't delete itemData's that are in use without + // crashing at the moment... + + if ( isObject( %obj ) ) + { + MessageBoxOKCancel( "Warning", + "Deleting this mesh will also delete BrushesElements and ForestItems referencing it.", + "ForestEditorGui.okDeleteMesh(" @ %obj @ ");", + "" ); + } +} + +function ForestEditorGui::okDeleteMesh( %this, %mesh ) +{ + // Remove mesh from file + ForestDataManager.removeObjectFromFile( %mesh, "art/forest/managedItemData.cs" ); + + // Submitting undo actions is handled in code. + %this.deleteMeshSafe( %mesh ); + + // Update TreeViews. + ForestEditBrushTree.buildVisibleTree( true ); + ForestEditMeshTree.buildVisibleTree( true ); + + ForestEditorPlugin.dirty = true; +} + +function ForestEditorGui::validateBrushSize( %this ) +{ + %minBrushSize = 1; + %maxBrushSize = getWord(ETerrainEditor.maxBrushSize, 0); + + %val = $ThisControl.getText(); + if(%val < %minBrushSize) + $ThisControl.setValue(%minBrushSize); + else if(%val > %maxBrushSize) + $ThisControl.setValue(%maxBrushSize); +} + + + +// Child-control Script Methods + + +function ForestEditMeshTree::onSelect( %this, %obj ) +{ + ForestEditorInspector.inspect( %obj ); +} + +function ForestEditBrushTree::onRemoveSelection( %this, %obj ) +{ + %this.buildVisibleTree( true ); + ForestTools->BrushTool.collectElements(); + + if ( %this.getSelectedItemsCount() == 1 ) + ForestEditorInspector.inspect( %obj ); + else + ForestEditorInspector.inspect( "" ); +} + +function ForestEditBrushTree::onAddSelection( %this, %obj ) +{ + %this.buildVisibleTree( true ); + ForestTools->BrushTool.collectElements(); + + if ( %this.getSelectedItemsCount() == 1 ) + ForestEditorInspector.inspect( %obj ); + else + ForestEditorInspector.inspect( "" ); +} + +function ForestEditTabBook::onTabSelected( %this, %text, %idx ) +{ + %bbg = ForestEditorPalleteWindow.findObjectByInternalName("BrushButtonGroup"); + %mbg = ForestEditorPalleteWindow.findObjectByInternalName("MeshButtonGroup"); + + %bbg.setVisible( false ); + %mbg.setVisible( false ); + + if ( %text $= "Brushes" ) + { + %bbg.setVisible( true ); + %obj = ForestEditBrushTree.getSelectedObject(); + ForestEditorInspector.inspect( %obj ); + } + else if ( %text $= "Meshes" ) + { + %mbg.setVisible( true ); + %obj = ForestEditMeshTree.getSelectedObject(); + ForestEditorInspector.inspect( %obj ); + } +} + +function ForestEditBrushTree::onDeleteSelection( %this ) +{ + %list = ForestEditBrushTree.getSelectedObjectList(); + + MEDeleteUndoAction::submit( %list, true ); + + ForestEditorPlugin.dirty = true; +} + +function ForestEditBrushTree::onDragDropped( %this ) +{ + ForestEditorPlugin.dirty = true; +} + +function ForestEditMeshTree::onDragDropped( %this ) +{ + ForestEditorPlugin.dirty = true; +} + +function ForestEditMeshTree::onDeleteObject( %this, %obj ) +{ + // return true - skip delete. + return true; +} + +function ForestEditMeshTree::onDoubleClick( %this ) +{ + %obj = %this.getSelectedObject(); + + %name = getUniqueInternalName( %obj.getName(), ForestBrushGroup, true ); + + %element = new ForestBrushElement() + { + internalName = %name; + forestItemData = %obj.getName(); + parentGroup = ForestBrushGroup; + }; + + //ForestDataManager.setDirty( %element, "art/forest/brushes.cs" ); + + ForestEditBrushTree.clearSelection(); + ForestEditBrushTree.buildVisibleTree( true ); + %item = ForestEditBrushTree.findItemByObjectId( %element ); + ForestEditBrushTree.scrollVisible( %item ); + ForestEditBrushTree.addSelection( %item ); + + ForestEditorPlugin.dirty = true; +} + +function ForestEditBrushTree::handleRenameObject( %this, %name, %obj ) +{ + if ( %name !$= "" ) + { + %found = ForestBrushGroup.findObjectByInternalName( %name ); + if ( isObject( %found ) && %found.getId() != %obj.getId() ) + { + MessageBoxOK( "Error", "Brush or Element with that name already exists.", "" ); + + // true as in, we handled it, don't rename the object. + return true; + } + } + + // Since we aren't showing any groups whens inspecting a ForestBrushGroup + // we can't push this event off to the inspector to handle. + + //return GuiTreeViewCtrl::handleRenameObject( %this, %name, %obj ); + + + // The instant group will try to add our + // UndoAction if we don't disable it. + pushInstantGroup(); + + %nameOrClass = %obj.getName(); + if ( %nameOrClass $= "" ) + %nameOrClass = %obj.getClassname(); + + %action = new InspectorFieldUndoAction() + { + actionName = %nameOrClass @ "." @ "internalName" @ " Change"; + + objectId = %obj.getId(); + fieldName = "internalName"; + fieldValue = %obj.internalName; + arrayIndex = 0; + + inspectorGui = ""; + }; + + // Restore the instant group. + popInstantGroup(); + + %action.addToManager( Editor.getUndoManager() ); + EWorldEditor.isDirty = true; + + return false; +} + +function ForestEditorInspector::inspect( %this, %obj ) +{ + if ( isObject( %obj ) ) + %class = %obj.getClassName(); + + %this.showObjectName = false; + %this.showCustomFields = false; + + switch$ ( %class ) + { + case "ForestBrush": + %this.groupFilters = "+NOTHING,-Ungrouped"; + + case "ForestBrushElement": + %this.groupFilters = "+ForestBrushElement,-Ungrouped"; + + case "TSForestItemData": + %this.groupFilters = "+Media,+Wind"; + + default: + %this.groupFilters = ""; + } + + Parent::inspect( %this, %obj ); +} + +function ForestEditorInspector::onInspectorFieldModified( %this, %object, %fieldName, %oldValue, %newValue ) +{ + // The instant group will try to add our + // UndoAction if we don't disable it. + %instantGroup = $InstantGroup; + $InstantGroup = 0; + + %nameOrClass = %object.getName(); + if ( %nameOrClass $= "" ) + %nameOrClass = %object.getClassname(); + + %action = new InspectorFieldUndoAction() + { + actionName = %nameOrClass @ "." @ %fieldName @ " Change"; + + objectId = %object.getId(); + fieldName = %fieldName; + fieldValue = %oldValue; + + inspectorGui = %this; + }; + + // Restore the instant group. + $InstantGroup = %instantGroup; + + %action.addToManager( Editor.getUndoManager() ); + + if ( %object.getClassName() $= "TSForestItemData" ) + ForestDataManager.setDirty( %object ); + + ForestEditorPlugin.dirty = true; +} + +function ForestEditorInspector::onFieldSelected( %this, %fieldName, %fieldTypeStr, %fieldDoc ) +{ + //FieldInfoControl.setText( "<font:ArialBold:14>" @ %fieldName @ "<font:ArialItalic:14> (" @ %fieldTypeStr @ ") " NL "<font:Arial:14>" @ %fieldDoc ); +} + +function ForestBrushSizeSliderCtrlContainer::onWake(%this) +{ + %this-->slider.range = "1" SPC getWord(ETerrainEditor.maxBrushSize, 0); + %this-->slider.setValue(ForestBrushSizeTextEditContainer-->textEdit.getValue()); +} diff --git a/Templates/Empty/game/tools/forestEditor/forestEditorGui.gui b/Templates/Empty/game/tools/forestEditor/forestEditorGui.gui new file mode 100644 index 000000000..21462b5bc --- /dev/null +++ b/Templates/Empty/game/tools/forestEditor/forestEditorGui.gui @@ -0,0 +1,511 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new ForestEditorCtrl(ForestEditorGui,EditorGuiGroup) { + renderMissionArea = "0"; + missionAreaFillColor = "255 0 0 20"; + missionAreaFrameColor = "255 0 0 128"; + allowBorderMove = "0"; + borderMovePixelSize = "20"; + borderMoveSpeed = "0.1"; + consoleFrameColor = "255 0 0 255"; + consoleFillColor = "255 0 0 120"; + consoleSphereLevel = "1"; + consoleCircleSegments = "32"; + consoleLineWidth = "1"; + GizmoProfile = "GlobalGizmoProfile"; + cameraZRot = "0"; + forceFOV = "0"; + reflectPriority = "1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ForestEditorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiWindowCollapseCtrl(ForestEditorPalleteWindow) { + CollapseGroup = "-1"; + CollapseGroupNum = "-1"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Forest Editor"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiWindowCollapseProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1)-1; + Extent = "210 252"; + MinExtent = "210 100"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "PalleteWindow"; + canSaveDynamicFields = "0"; + + new GuiTabBookCtrl(ForestEditTabBook) { + TabPosition = "Top"; + TabMargin = "10"; + MinTabWidth = "60"; + TabHeight = "20"; + AllowReorder = "0"; + FrontTabPadding = "0"; + Docking = "Client"; + Margin = "3 1 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "3 44"; + Extent = "210 205"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTabPageCtrl() { + fitBook = "0"; + text = "Brushes"; + maxLength = "1024"; + Docking = "Client"; + Margin = "-1 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiTabPageProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 22"; + Extent = "210 194"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "BrushesTab"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = true; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "210 194"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTreeViewCtrl(ForestEditBrushTree) { + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "1"; + MultipleSelections = "1"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "1"; + ClearAllOnSingleSelection = "1"; + showRoot = "0"; + internalNamesOnly = "1"; + objectNamesOnly = "0"; + useInspectorTooltips = "0"; + tooltipOnWidthOnly = "0"; + compareToObjectID = "1"; + canRenameObjects = "1"; + renameInternal = "1"; + isContainer = "1"; + Profile = "GuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "208 2"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiTabPageCtrl() { + fitBook = "0"; + text = "Meshes"; + maxLength = "1024"; + Docking = "Client"; + Margin = "-1 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiTabPageProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 22"; + Extent = "210 183"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "MeshesTab"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = true; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "210 194"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTreeViewCtrl(ForestEditMeshTree) { + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "0"; + DragToItemAllowed = "0"; + ClearAllOnSingleSelection = "1"; + showRoot = "0"; + internalNamesOnly = "0"; + objectNamesOnly = "1"; + useInspectorTooltips = "0"; + tooltipOnWidthOnly = "0"; + compareToObjectID = "1"; + canRenameObjects = "1"; + renameInternal = "0"; + isContainer = "1"; + Profile = "GuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 -67"; + Extent = "208 2"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "$ThisControl.onDoubleClick();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; + new GuiStackControl() { + StackingType = "Horizontal"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "3"; + DynamicSize = "1"; + ChangeChildSizeToFit = "0"; + ChangeChildPosition = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "170 25"; + Extent = "35 17"; + MinExtent = "16 16"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "MeshButtonGroup"; + canSaveDynamicFields = "0"; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/forestEditor/images/new-mesh"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ForestEditorGui.newMesh();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Add New Mesh"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "19 0"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ForestEditorGui.deleteMesh();"; + tooltip = "Delete Selected"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + new GuiStackControl() { + StackingType = "Horizontal"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "3"; + DynamicSize = "1"; + ChangeChildSizeToFit = "0"; + ChangeChildPosition = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "151 25"; + Extent = "54 17"; + MinExtent = "16 16"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "BrushButtonGroup"; + canSaveDynamicFields = "0"; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/forestEditor/images/new-brush"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ForestEditorGui.newBrush();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Add New Brush Group"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/forestEditor/images/new-element"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "19 0"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ForestEditorGui.newElement();"; + tooltip = "Add New Brush Element"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "38 0"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ForestEditorGui.deleteBrushOrElement();"; + tooltip = "Delete Selected"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiWindowCollapseCtrl(ForestEditorPropertiesWindow) { + CollapseGroup = "-1"; + CollapseGroupNum = "-1"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Properties"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiWindowCollapseProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) + getWord(ForestEditorPalleteWindow.extent, 1) - 2; + Extent = "210 460"; + MinExtent = "210 50"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "PropertiesWindow"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = true; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Docking = "Client"; + Margin = "3 1 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "3 23"; + Extent = "210 263"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiInspector(ForestEditorInspector) { + dividerMargin = "5"; + showCustomFields = "0"; + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + DynamicSize = "1"; + ChangeChildSizeToFit = "1"; + ChangeChildPosition = "1"; + isContainer = "1"; + Profile = "GuiInspectorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "1 1"; + Extent = "193 16"; + MinExtent = "16 16"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "Inspector"; + canSaveDynamicFields = "0"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/forestEditor/images/erase-all-btn_d.png b/Templates/Empty/game/tools/forestEditor/images/erase-all-btn_d.png new file mode 100644 index 000000000..24af47fb0 Binary files /dev/null and b/Templates/Empty/game/tools/forestEditor/images/erase-all-btn_d.png differ diff --git a/Templates/Empty/game/tools/forestEditor/images/erase-all-btn_h.png b/Templates/Empty/game/tools/forestEditor/images/erase-all-btn_h.png new file mode 100644 index 000000000..66d75bb5b Binary files /dev/null and b/Templates/Empty/game/tools/forestEditor/images/erase-all-btn_h.png differ diff --git a/Templates/Empty/game/tools/forestEditor/images/erase-all-btn_n.png b/Templates/Empty/game/tools/forestEditor/images/erase-all-btn_n.png new file mode 100644 index 000000000..ec82f5ac0 Binary files /dev/null and b/Templates/Empty/game/tools/forestEditor/images/erase-all-btn_n.png differ diff --git a/Templates/Empty/game/tools/forestEditor/images/erase-element-btn_d.png b/Templates/Empty/game/tools/forestEditor/images/erase-element-btn_d.png new file mode 100644 index 000000000..8f45d199e Binary files /dev/null and b/Templates/Empty/game/tools/forestEditor/images/erase-element-btn_d.png differ diff --git a/Templates/Empty/game/tools/forestEditor/images/erase-element-btn_h.png b/Templates/Empty/game/tools/forestEditor/images/erase-element-btn_h.png new file mode 100644 index 000000000..26189746f Binary files /dev/null and b/Templates/Empty/game/tools/forestEditor/images/erase-element-btn_h.png differ diff --git a/Templates/Empty/game/tools/forestEditor/images/erase-element-btn_n.png b/Templates/Empty/game/tools/forestEditor/images/erase-element-btn_n.png new file mode 100644 index 000000000..05fb6690f Binary files /dev/null and b/Templates/Empty/game/tools/forestEditor/images/erase-element-btn_n.png differ diff --git a/Templates/Empty/game/tools/forestEditor/images/forest-editor-btn_d.png b/Templates/Empty/game/tools/forestEditor/images/forest-editor-btn_d.png new file mode 100644 index 000000000..79745e5bd Binary files /dev/null and b/Templates/Empty/game/tools/forestEditor/images/forest-editor-btn_d.png differ diff --git a/Templates/Empty/game/tools/forestEditor/images/forest-editor-btn_h.png b/Templates/Empty/game/tools/forestEditor/images/forest-editor-btn_h.png new file mode 100644 index 000000000..5351983f6 Binary files /dev/null and b/Templates/Empty/game/tools/forestEditor/images/forest-editor-btn_h.png differ diff --git a/Templates/Empty/game/tools/forestEditor/images/forest-editor-btn_n.png b/Templates/Empty/game/tools/forestEditor/images/forest-editor-btn_n.png new file mode 100644 index 000000000..3c305350f Binary files /dev/null and b/Templates/Empty/game/tools/forestEditor/images/forest-editor-btn_n.png differ diff --git a/Templates/Empty/game/tools/forestEditor/images/new-brush_d.png b/Templates/Empty/game/tools/forestEditor/images/new-brush_d.png new file mode 100644 index 000000000..df1e11c35 Binary files /dev/null and b/Templates/Empty/game/tools/forestEditor/images/new-brush_d.png differ diff --git a/Templates/Empty/game/tools/forestEditor/images/new-brush_h.png b/Templates/Empty/game/tools/forestEditor/images/new-brush_h.png new file mode 100644 index 000000000..57391fe5f Binary files /dev/null and b/Templates/Empty/game/tools/forestEditor/images/new-brush_h.png differ diff --git a/Templates/Empty/game/tools/forestEditor/images/new-brush_n.png b/Templates/Empty/game/tools/forestEditor/images/new-brush_n.png new file mode 100644 index 000000000..e5d51f5d0 Binary files /dev/null and b/Templates/Empty/game/tools/forestEditor/images/new-brush_n.png differ diff --git a/Templates/Empty/game/tools/forestEditor/images/new-element_d.png b/Templates/Empty/game/tools/forestEditor/images/new-element_d.png new file mode 100644 index 000000000..bac080398 Binary files /dev/null and b/Templates/Empty/game/tools/forestEditor/images/new-element_d.png differ diff --git a/Templates/Empty/game/tools/forestEditor/images/new-element_h.png b/Templates/Empty/game/tools/forestEditor/images/new-element_h.png new file mode 100644 index 000000000..c9ddc03f0 Binary files /dev/null and b/Templates/Empty/game/tools/forestEditor/images/new-element_h.png differ diff --git a/Templates/Empty/game/tools/forestEditor/images/new-element_n.png b/Templates/Empty/game/tools/forestEditor/images/new-element_n.png new file mode 100644 index 000000000..61f42fb9c Binary files /dev/null and b/Templates/Empty/game/tools/forestEditor/images/new-element_n.png differ diff --git a/Templates/Empty/game/tools/forestEditor/images/new-mesh_d.png b/Templates/Empty/game/tools/forestEditor/images/new-mesh_d.png new file mode 100644 index 000000000..c21bb3969 Binary files /dev/null and b/Templates/Empty/game/tools/forestEditor/images/new-mesh_d.png differ diff --git a/Templates/Empty/game/tools/forestEditor/images/new-mesh_h.png b/Templates/Empty/game/tools/forestEditor/images/new-mesh_h.png new file mode 100644 index 000000000..705a7a836 Binary files /dev/null and b/Templates/Empty/game/tools/forestEditor/images/new-mesh_h.png differ diff --git a/Templates/Empty/game/tools/forestEditor/images/new-mesh_n.png b/Templates/Empty/game/tools/forestEditor/images/new-mesh_n.png new file mode 100644 index 000000000..c4c01754c Binary files /dev/null and b/Templates/Empty/game/tools/forestEditor/images/new-mesh_n.png differ diff --git a/Templates/Empty/game/tools/forestEditor/images/paint-forest-btn_d.png b/Templates/Empty/game/tools/forestEditor/images/paint-forest-btn_d.png new file mode 100644 index 000000000..2d2facc71 Binary files /dev/null and b/Templates/Empty/game/tools/forestEditor/images/paint-forest-btn_d.png differ diff --git a/Templates/Empty/game/tools/forestEditor/images/paint-forest-btn_h.png b/Templates/Empty/game/tools/forestEditor/images/paint-forest-btn_h.png new file mode 100644 index 000000000..8a2bda1eb Binary files /dev/null and b/Templates/Empty/game/tools/forestEditor/images/paint-forest-btn_h.png differ diff --git a/Templates/Empty/game/tools/forestEditor/images/paint-forest-btn_n.png b/Templates/Empty/game/tools/forestEditor/images/paint-forest-btn_n.png new file mode 100644 index 000000000..ad9242ead Binary files /dev/null and b/Templates/Empty/game/tools/forestEditor/images/paint-forest-btn_n.png differ diff --git a/Templates/Empty/game/tools/forestEditor/main.cs b/Templates/Empty/game/tools/forestEditor/main.cs new file mode 100644 index 000000000..a5fc84f38 --- /dev/null +++ b/Templates/Empty/game/tools/forestEditor/main.cs @@ -0,0 +1,285 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function initializeForestEditor() +{ + echo(" % - Initializing Forest Editor"); + + exec( "./forestEditor.cs" ); + exec( "./forestEditorGui.gui" ); + exec( "./forestEditToolbar.ed.gui" ); + + exec( "./forestEditorGui.cs" ); + exec( "./tools.cs" ); + + ForestEditorGui.setVisible( false ); + ForestEditorPalleteWindow.setVisible( false ); + ForestEditorPropertiesWindow.setVisible( false ); + ForestEditToolbar.setVisible( false ); + + EditorGui.add( ForestEditorGui ); + EditorGui.add( ForestEditorPalleteWindow ); + EditorGui.add( ForestEditorPropertiesWindow ); + EditorGui.add( ForestEditToolbar ); + + new ScriptObject( ForestEditorPlugin ) + { + superClass = "EditorPlugin"; + editorGui = ForestEditorGui; + }; + + new SimSet(ForestTools) + { + new ForestBrushTool() + { + internalName = "BrushTool"; + toolTip = "Paint Tool"; + buttonImage = "tools/forest/images/brushTool"; + }; + + new ForestSelectionTool() + { + internalName = "SelectionTool"; + toolTip = "Selection Tool"; + buttonImage = "tools/forest/images/selectionTool"; + }; + }; + + %map = new ActionMap(); + %map.bindCmd( keyboard, "1", "ForestEditorSelectModeBtn.performClick();", "" ); // Select + %map.bindCmd( keyboard, "2", "ForestEditorMoveModeBtn.performClick();", "" ); // Move + %map.bindCmd( keyboard, "3", "ForestEditorRotateModeBtn.performClick();", "" ); // Rotate + %map.bindCmd( keyboard, "4", "ForestEditorScaleModeBtn.performClick();", "" ); // Scale + %map.bindCmd( keyboard, "5", "ForestEditorPaintModeBtn.performClick();", "" ); // Paint + %map.bindCmd( keyboard, "6", "ForestEditorEraseModeBtn.performClick();", "" ); // Erase + %map.bindCmd( keyboard, "7", "ForestEditorEraseSelectedModeBtn.performClick();", "" ); // EraseSelected + //%map.bindCmd( keyboard, "backspace", "ForestEditorGui.onDeleteKey();", "" ); + //%map.bindCmd( keyboard, "delete", "ForestEditorGui.onDeleteKey();", "" ); + ForestEditorPlugin.map = %map; +} + +function destroyForestEditor() +{ +} + +// NOTE: debugging helper. +function reinitForest() +{ + exec( "./main.cs" ); + exec( "./forestEditorGui.cs" ); + exec( "./tools.cs" ); +} + +function ForestEditorPlugin::onWorldEditorStartup( %this ) +{ + new PersistenceManager( ForestDataManager ); + + %brushPath = "art/forest/brushes.cs"; + if ( !isFile( %brushPath ) ) + createPath( %brushPath ); + + // This creates the ForestBrushGroup, all brushes, and elements. + exec( %brushpath ); + + if ( !isObject( ForestBrushGroup ) ) + { + new SimGroup( ForestBrushGroup ); + %this.showError = true; + } + + ForestEditBrushTree.open( ForestBrushGroup ); + + if ( !isObject( ForestItemDataSet ) ) + new SimSet( ForestItemDataSet ); + + ForestEditMeshTree.open( ForestItemDataSet ); + + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Forest Editor", "", ForestEditorPlugin ); + + // Add ourselves to the tools menu. + %tooltip = "Forest Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "ForestEditorPlugin", "ForestEditorPalette", expandFilename("tools/forestEditor/images/forest-editor-btn"), %tooltip ); + + //connect editor windows + GuiWindowCtrl::attach( ForestEditorPropertiesWindow, ForestEditorPalleteWindow ); + ForestEditTabBook.selectPage(0); +} + +function ForestEditorPlugin::onWorldEditorShutdown( %this ) +{ + if ( isObject( ForestBrushGroup ) ) + ForestBrushGroup.delete(); + if ( isObject( ForestDataManager ) ) + ForestDataManager.delete(); +} + +function ForestEditorPlugin::onActivated( %this ) +{ + EditorGui.bringToFront( ForestEditorGui ); + ForestEditorGui.setVisible( true ); + ForestEditorPalleteWindow.setVisible( true ); + ForestEditorPropertiesWindow.setVisible( true ); + ForestEditorGui.makeFirstResponder( true ); + //ForestEditToolbar.setVisible( true ); + + %this.map.push(); + Parent::onActivated(%this); + + ForestEditBrushTree.open( ForestBrushGroup ); + ForestEditMeshTree.open( ForestItemDataSet ); + + // Open the Brush tab. + ForestEditTabBook.selectPage(0); + + // Sync the pallete button state + + // And toolbar. + %tool = ForestEditorGui.getActiveTool(); + if ( isObject( %tool ) ) + %tool.onActivated(); + + if ( !isObject( %tool ) ) + { + ForestEditorPaintModeBtn.performClick(); + + if ( ForestEditBrushTree.getItemCount() > 0 ) + { + ForestEditBrushTree.selectItem( 0, true ); + } + } + else if ( %tool == ForestTools->SelectionTool ) + { + %mode = GlobalGizmoProfile.mode; + switch$ (%mode) + { + case "None": + ForestEditorSelectModeBtn.performClick(); + case "Move": + ForestEditorMoveModeBtn.performClick(); + case "Rotate": + ForestEditorRotateModeBtn.performClick(); + case "Scale": + ForestEditorScaleModeBtn.performClick(); + } + } + else if ( %tool == ForestTools->BrushTool ) + { + %mode = ForestTools->BrushTool.mode; + switch$ (%mode) + { + case "Paint": + ForestEditorPaintModeBtn.performClick(); + case "Erase": + ForestEditorEraseModeBtn.performClick(); + case "EraseSelected": + ForestEditorEraseSelectedModeBtn.performClick(); + } + } + + if ( %this.showError ) + MessageBoxOK( "Error", "Your art/forest folder does not contain a valid brushes.cs. Brushes you create will not be saved!" ); +} + +function ForestEditorPlugin::onDeactivated( %this ) +{ + ForestEditorGui.setVisible( false ); + ForestEditorPalleteWindow.setVisible( false ); + ForestEditorPropertiesWindow.setVisible( false ); + + %tool = ForestEditorGui.getActiveTool(); + if ( isObject( %tool ) ) + %tool.onDeactivated(); + + // Also take this opportunity to save. + ForestDataManager.saveDirty(); + + %this.map.pop(); + + Parent::onDeactivated(%this); +} + +function ForestEditorPlugin::isDirty( %this ) +{ + %dirty = %this.dirty || ForestEditorGui.isDirty(); + return %dirty; +} + +function ForestEditorPlugin::clearDirty( %this ) +{ + %this.dirty = false; +} + +function ForestEditorPlugin::onSaveMission( %this, %missionFile ) +{ + ForestDataManager.saveDirty(); + + if ( isObject( theForest ) ) + theForest.saveDataFile(); + + ForestBrushGroup.save( "art/forest/brushes.cs" ); +} + +function ForestEditorPlugin::onEditorSleep( %this ) +{ +} + +function ForestEditorPlugin::onEditMenuSelect( %this, %editMenu ) +{ + %hasSelection = false; + + %selTool = ForestTools->SelectionTool; + if ( ForestEditorGui.getActiveTool() == %selTool ) + if ( %selTool.getSelectionCount() > 0 ) + %hasSelection = true; + + %editMenu.enableItem( 3, %hasSelection ); // Cut + %editMenu.enableItem( 4, %hasSelection ); // Copy + %editMenu.enableItem( 5, %hasSelection ); // Paste + %editMenu.enableItem( 6, %hasSelection ); // Delete + %editMenu.enableItem( 8, %hasSelection ); // Deselect +} + +function ForestEditorPlugin::handleDelete( %this ) +{ + ForestTools->SelectionTool.deleteSelection(); +} + +function ForestEditorPlugin::handleDeselect( %this ) +{ + ForestTools->SelectionTool.clearSelection(); +} + +function ForestEditorPlugin::handleCut( %this ) +{ + ForestTools->SelectionTool.cutSelection(); +} + +function ForestEditorPlugin::handleCopy( %this ) +{ + ForestTools->SelectionTool.copySelection(); +} + +function ForestEditorPlugin::handlePaste( %this ) +{ + ForestTools->SelectionTool.pasteSelection(); +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/forestEditor/tools.cs b/Templates/Empty/game/tools/forestEditor/tools.cs new file mode 100644 index 000000000..e6f28e8be --- /dev/null +++ b/Templates/Empty/game/tools/forestEditor/tools.cs @@ -0,0 +1,61 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function ForestBrushTool::onActivated( %this ) +{ + ForestEditToolbar.setVisible( true ); + %this.syncBrushToolbar(); +} + +function ForestBrushTool::onDeactivated( %this ) +{ + ForestEditToolbar.setVisible( false ); +} + +function ForestBrushTool::syncBrushToolbar( %this ) +{ + %size = %this.size; + ForestBrushSizeSliderCtrlContainer->slider.setValue( %size ); + ForestBrushSizeTextEditContainer-->textEdit.setValue( %size ); + + %pres = %this.pressure; + ForestBrushPressureSliderCtrlContainer->slider.setValue( %pres ); + ForestBrushPressureTextEditContainer-->textEdit.setValue( mCeil(100 * %pres) @ "%" ); + + %hard = %this.hardness; + ForestBrushHardnessSliderCtrlContainer->slider.setValue( %hard ); + ForestBrushHardnessTextEditContainer-->textEdit.setValue( mCeil(100 * %hard) @ "%"); +} + +function ForestBrushTool::onMouseDown( %this ) +{ + ForestEditTabBook.selectPage( 0 ); +} + +function ForestSelectionTool::onActivated( %this ) +{ +} + +function ForestSelectionTool::onDeactivated( %this ) +{ + %this.clearSelection(); +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/gui/EditorLoadingGui.gui b/Templates/Empty/game/tools/gui/EditorLoadingGui.gui new file mode 100644 index 000000000..5fb289410 --- /dev/null +++ b/Templates/Empty/game/tools/gui/EditorLoadingGui.gui @@ -0,0 +1,72 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(EditorLoadingGui, EditorGuiGroup) { + isContainer = "1"; + Profile = "GuiOverlayProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiControl() { + isContainer = "1"; + Profile = "editorMenu_wBorderProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "277 271"; + Extent = "245 57"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "Dialog"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Loading the World Editor..."; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextBoldCenterProfile"; + HorizSizing = "width"; + VertSizing = "center"; + position = "5 19"; + Extent = "236 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + +function EditorLoadingGui::onWake(%this) +{ + %res = %this.getExtent(); + %resX = getWord(%res, 0); + %resY = getWord(%res, 1); + + %dialog = %this-->Dialog; + %dialogExtent = %dialog.getExtent(); + %dialogWidth = getWord(%dialogExtent, 0); + %dialogHeight = getWord(%dialogExtent, 1); + %dialogPostion = %dialog.getPosition(); + + %posX = (%resX / 2) - (%dialogWidth / 2); + %posY = (%resY / 2) - (%dialogHeight / 2); + %dialog.setPosition(%posX, %posY); +} diff --git a/Templates/Empty/game/tools/gui/GuiEaseEditDlg.ed.cs b/Templates/Empty/game/tools/gui/GuiEaseEditDlg.ed.cs new file mode 100644 index 000000000..44345f9f4 --- /dev/null +++ b/Templates/Empty/game/tools/gui/GuiEaseEditDlg.ed.cs @@ -0,0 +1,183 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------------------------- + +function GetEaseF( %currentEase, %callback, %root ) +{ + GuiEaseEditDlg.init( %currentEase, %callback ); + + if( !isObject( %root ) ) + %root = Canvas; + + %root.pushDialog( GuiEaseEditDlg ); +} + +//============================================================================================= +// GuiEaseEditDlg +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEaseEditDlg::init( %this, %ease, %callback ) +{ + // Initialize direction popup. + + %directionList = %this-->directionList; + if( !%directionList.size() ) + { + %directionList.add( "InOut", $Ease::InOut ); + %directionList.add( "In", $Ease::In ); + %directionList.add( "Out", $Ease::Out ); + } + + // Initialize type popup. + + %typeList = %this-->typeList; + if( !%typeList.size() ) + { + %typeList.add( "Linear", $Ease::Linear ); + %typeList.add( "Quadratic", $Ease::Quadratic ); + %typeList.add( "Cubic", $Ease::Cubic ); + %typeList.add( "Quartic", $Ease::Quartic ); + %typeList.add( "Quintic", $Ease::Quintic ); + %typeList.add( "Sinusoidal", $Ease::Sinusoidal ); + %typeList.add( "Exponential", $Ease::Exponential ); + %typeList.add( "Circular", $Ease::Circular ); + %typeList.add( "Elastic", $Ease::Elastic ); + %typeList.add( "Back", $Ease::Back ); + %typeList.add( "Bounce", $Ease::Bounce ); + } + + // Set the initial easing curve. + + %this.oldEase = %ease; + %this.setEase( %ease ); + + // Remember callback. + + %this.callback = %callback; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEaseEditDlg::setEase( %this, %ease ) +{ + %this-->easeView.ease = %ease; + %this-->directionList.setSelected( getWord( %ease, 0 ), false ); + %this-->typeList.setSelected( getWord( %ease, 1 ), false ); + %this-->param1Value.setValue( getWord( %ease, 2 ) ); + %this-->param2Value.setValue( getWord( %ease, 3 ) ); + + %this.onEaseTypeSet(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEaseEditDlg::onEaseTypeSet( %this ) +{ + switch( %this-->typeList.getSelected() ) + { + case $Ease::Elastic: + %this-->param1Value.setActive( true ); + %this-->param2Value.setActive( true ); + + case $Ease::Back: + %this-->param1Value.setActive( true ); + %this-->param2Value.setActive( false ); + + default: + %this-->param1Value.setActive( false ); + %this-->param2Value.setActive( false ); + } +} + +//--------------------------------------------------------------------------------------------- + +function GuiEaseEditDlg::onOK( %this ) +{ + eval( %this.callback @ "( \"" @ %this-->easeView.ease @ "\" );" ); + %this.getRoot().popDialog( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEaseEditDlg::onCancel( %this ) +{ + %this.getRoot().popDialog( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEaseEditDlg::onSetParam1( %this, %value ) +{ + %easeView = %this-->easeView; + + %ease = %easeView.ease; + %ease = setWord( %ease, 2, %value ); + %easeView.ease = %ease; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEaseEditDlg::onSetParam2( %this, %value ) +{ + %easeView = %this-->easeView; + + %ease = %easeView.ease; + %ease = setWord( %ease, 3, %value ); + %easeView.ease = %ease; +} + +//============================================================================================= +// GuiEaseEditDirectionList +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEaseEditDirectionList::onSelect( %this, %id, %text ) +{ + %easeView = GuiEaseEditDlg-->easeView; + + %ease = %easeView.ease; + %ease = setWord( %ease, 0, %id ); + %easeview.ease = %ease; +} + +//============================================================================================= +// GuiEaseEditTypeList +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEaseEditTypeList::onSelect( %this, %id, %text ) +{ + %easeView = GuiEaseEditDlg-->easeView; + + %ease = %easeView.ease; + %ease = setWord( %ease, 1, %id ); + %easeview.ease = %ease; + + GuiEaseEditDlg.onEaseTypeSet(); +} diff --git a/Templates/Empty/game/tools/gui/GuiEaseEditDlg.ed.gui b/Templates/Empty/game/tools/gui/GuiEaseEditDlg.ed.gui new file mode 100644 index 000000000..e91292b5c --- /dev/null +++ b/Templates/Empty/game/tools/gui/GuiEaseEditDlg.ed.gui @@ -0,0 +1,332 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(GuiEaseEditDlg,EditorGuiGroup) { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiWindowCtrl() { + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "GuiEaseEditDlg.onCancel();"; + EdgeSnap = "1"; + text = "Edit Easing Curve"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "334 145"; + Extent = "269 214"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "window"; + canSaveDynamicFields = "0"; + + new GuiBitmapBorderCtrl() { + isContainer = "1"; + Profile = "GuiGroupBorderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 27"; + Extent = "95 151"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Direction"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiAutoSizeTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "6 3"; + Extent = "43 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "6 20"; + Extent = "83 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "directionList"; + canSaveDynamicFields = "0"; + class = "GuiEaseEditDirectionList"; + className = "GuiEaseEditDirectionList"; + }; + new GuiTextCtrl() { + text = "Type"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiAutoSizeTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "6 40"; + Extent = "25 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "6 57"; + Extent = "83 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "typeList"; + canSaveDynamicFields = "0"; + class = "GuiEaseEditTypeList"; + className = "GuiEaseEditTypeList"; + }; + new GuiTextCtrl() { + text = "Param1"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiAutoSizeTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "6 76"; + Extent = "38 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Param2"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiAutoSizeTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "6 111"; + Extent = "38 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditSliderCtrl() { + format = "%3.2f"; + range = "-1e+03 1e+03"; + increment = "0.1"; + focusOnMouseWheel = "0"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + text = "-1.00"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "6 93"; + Extent = "83 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "GuiEaseEditDlg.onSetParam1( $ThisControl.getValue() );"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "param1Value"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditSliderCtrl() { + format = "%3.2f"; + range = "-1e+03 1e+03"; + increment = "0.1"; + focusOnMouseWheel = "0"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + text = "-1.00"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "6 128"; + Extent = "83 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "GuiEaseEditDlg.onSetParam2( $ThisControl.getValue() );"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "param2Value"; + canSaveDynamicFields = "0"; + }; + }; + new GuiButtonCtrl() { + text = "OK"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "67 184"; + Extent = "115 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GuiEaseEditDlg.onOK();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "184 184"; + Extent = "73 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GuiEaseEditDlg.onCancel();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiEaseViewCtrl() { + wrap = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "107 28"; + Extent = "150 150"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "easeView"; + canSaveDynamicFields = "0"; + ease = "1 2 -1 -1"; + easeColor = "0.537255 0.537255 0.537255 1"; + easeWidth = "4"; + axisColor = "0.509804 0.509804 0.509804 1"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/gui/colladaImport.ed.gui b/Templates/Empty/game/tools/gui/colladaImport.ed.gui new file mode 100644 index 000000000..873c3d692 --- /dev/null +++ b/Templates/Empty/game/tools/gui/colladaImport.ed.gui @@ -0,0 +1,1698 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ColladaImportDlg,EditorGuiGroup) { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiWindowCtrl() { + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "Canvas.popDialog(ColladaImportDlg);"; + EdgeSnap = "1"; + text = ""; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "254 136"; + Extent = "516 447"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Accelerator = "escape"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "window"; + canSaveDynamicFields = "0"; + + new GuiControl() { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "8 24"; + Extent = "238 417"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 3"; + Extent = "238 366"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiTreeViewCtrl(ColladaImportTreeView) { + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "0"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "0"; + DragToItemAllowed = "0"; + ClearAllOnSingleSelection = "1"; + showRoot = "1"; + internalNamesOnly = "0"; + objectNamesOnly = "0"; + useInspectorTooltips = "0"; + tooltipOnWidthOnly = "0"; + compareToObjectID = "1"; + canRenameObjects = "1"; + renameInternal = "0"; + isContainer = "1"; + Profile = "GuiTreeViewProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "1 1"; + Extent = "74 63"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiControl() { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "254 24"; + Extent = "254 417"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiBitmapBorderCtrl() { + isContainer = "1"; + Profile = "GuiGroupBorderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 3"; + Extent = "254 60"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Nodes"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "42 2"; + Extent = "32 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = ""; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "90 2"; + Extent = "60 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "nodes"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Meshes"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "36 22"; + Extent = "38 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = ""; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "90 22"; + Extent = "60 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "meshes"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Polygons"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "132 22"; + Extent = "47 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = ""; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "193 22"; + Extent = "60 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "polygons"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Materials"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "135 2"; + Extent = "44 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = ""; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "193 2"; + Extent = "60 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "Materials"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Lights"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "23 41"; + Extent = "52 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = ""; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "91 41"; + Extent = "60 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "lights"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Animations"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "127 41"; + Extent = "52 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = ""; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "191 41"; + Extent = "60 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "animations"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapBorderCtrl() { + isContainer = "1"; + Profile = "GuiGroupBorderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 68"; + Extent = "254 153"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "LOD"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "59 6"; + Extent = "22 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "DetectDTS"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "97 6"; + Extent = "92 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Method used to determine LOD for meshes in the model"; + hovertime = "1000"; + internalName = "lodType"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + text = ""; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "196 6"; + Extent = "49 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Detail size for all meshes in this model (when LOD type is SingleSize)"; + hovertime = "1000"; + internalName = "singleDetailSize"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Materials Prefix"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 32"; + Extent = "73 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "97 32"; + Extent = "148 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ColladaImportTreeView.refresh(\"materials\");"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "materialPrefix"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Import Nodes"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "13 58"; + Extent = "72 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "97 58"; + Extent = "148 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ColladaImportTreeView.refresh(\"nodes\");"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "alwaysImport"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Ignore Nodes"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 82"; + Extent = "65 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "97 82"; + Extent = "148 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ColladaImportTreeView.refresh(\"nodes\");"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "neverImport"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Import Meshes"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "13 106"; + Extent = "72 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "97 106"; + Extent = "148 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ColladaImportTreeView.refresh(\"nodes\");"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "alwaysImportMesh"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Ignore Meshes"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "13 130"; + Extent = "72 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "97 130"; + Extent = "148 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ColladaImportTreeView.refresh(\"nodes\");"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "neverImportMesh"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapBorderCtrl() { + isContainer = "1"; + Profile = "GuiGroupBorderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 226"; + Extent = "254 105"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = " Override up_axis"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 7"; + Extent = "102 13"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ColladaImportDlg.updateOverrideUpAxis($ThisControl.getValue());"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Overrides the <up_axis> specified in the DAE file"; + hovertime = "1000"; + internalName = "overrideUpAxis"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "151 6"; + Extent = "66 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "upAxis"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = " Override scale"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 27"; + Extent = "92 13"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ColladaImportDlg.updateOverrideScale($ThisControl.getValue());"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Overrides the <unit> scale specified in the DAE file"; + hovertime = "1000"; + internalName = "overrideScale"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + text = ""; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "151 27"; + Extent = "66 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "scale"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = " Ignore bone scaling"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 48"; + Extent = "114 13"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Ignores <scale> elements within <node>s to fix issues with some models"; + hovertime = "1000"; + internalName = "ignoreNodeScale"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = " Center model"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 67"; + Extent = "82 13"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Translates model so the origin is at the center"; + hovertime = "1000"; + internalName = "adjustCenter"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = " Floor model"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "151 67"; + Extent = "72 13"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Translates model so the origin is at the bottom"; + hovertime = "1000"; + internalName = "adjustFloor"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = " Force update materials.cs"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 86"; + Extent = "148 13"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Forces update of materials.cs (even if Materials already exist)"; + hovertime = "1000"; + internalName = "forceUpdateMaterials"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapBorderCtrl() { + isContainer = "1"; + Profile = "GuiGroupBorderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 338"; + Extent = "254 24"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = " Add lights to scene"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 5"; + Extent = "148 13"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Loads the lights from the DAE file and adds them to the current scene."; + hovertime = "1000"; + internalName = "loadLights"; + canSaveDynamicFields = "0"; + }; + }; + new GuiButtonCtrl() { + text = "Load from .cfg"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 368"; + Extent = "86 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ColladaImportDlg.readDtsConfig();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Save to .cfg"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 395"; + Extent = "86 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ColladaImportDlg.writeDtsConfig();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "OK"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "159 368"; + Extent = "86 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ColladaImportDlg.onOK();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Load the COLLADA model"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "159 395"; + Extent = "86 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ColladaImportDlg.onCancel();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Exit without loading the COLLADA model"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- + +new GuiControl(ColladaImportProgress,EditorGuiGroup) { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiWindowCtrl() { + internalName = "window"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Importing cowboy.dae"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "362 338"; + Extent = "300 92"; + MinExtent = "48 92"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiProgressBitmapCtrl() { + internalName = "progressBar"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiRLProgressBitmapProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "10 34"; + Extent = "280 24"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + internalName = "progressText"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "10 62"; + Extent = "280 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; +}; + +function ColladaImportTreeView::onDefineIcons(%this) +{ + // Set the tree view icon indices and texture paths + %this._imageNone = 0; + %this._imageNode = 1; + %this._imageMesh = 2; + %this._imageMaterial = 3; + %this._imageLight = 4; + %this._imageAnimation = 5; + %this._imageExNode = 6; + %this._imageExMaterial = 7; + + %icons = ":" @ // no icon + "tools/gui/images/ColladaImport/iconNode:" @ // normal node + "tools/gui/images/ColladaImport/iconMesh:" @ // mesh + "tools/gui/images/ColladaImport/iconMaterial:" @ // new material + "tools/gui/images/ColladaImport/iconLight:" @ // light + "tools/gui/images/ColladaImport/iconAnimation:" @ // sequence + "tools/gui/images/ColladaImport/iconIgnoreNode:" @ // ignored node + "tools/gui/images/ColladaImport/iconExistingMaterial"; // existing material + + %this.buildIconTable( %icons ); +} + +function ColladaImportDlg::showDialog(%this, %shapePath, %cmd) +{ + %this.path = %shapePath; + %this.cmd = %cmd; + + // Only allow loading lights if creating a new scene object + %canLoadLights = (strstr(%this.cmd, "EWCreatorWindow.create") != -1); + + // Check for an existing TSShapeConstructor object. Need to exec the script + // manually as the DAE resource may not have been loaded yet + %csPath = filePath(%this.path) @ "/" @ fileBase(%this.path) @ ".cs"; + if (isFile(%csPath)) + exec(%csPath); + + %this.constructor = ShapeEditor.findConstructor(%this.path); + + // Only show the import dialog if required. Note that 'enumColladaScene' will + // fail if the COLLADA file is missing, or a cached.dts is available. + $collada::forceLoadDAE = EditorSettings.value("forceLoadDAE"); + if ( (fileExt(%shapePath) $= ".dts") || + !enumColladaForImport(%shapePath, ColladaImportTreeView) ) + { + eval(%cmd); + $collada::forceLoadDAE = false; + + // Load lights from the DAE if possible + if (%canLoadLights && (%this.constructor > 0) && (%this.constructor.loadLights == 1)) + %this.loadLights(); + + return; + } + $collada::forceLoadDAE = false; + + // Initialise GUI + ColladaImportTreeView.onDefineIcons(); + + %this-->window.text = "COLLADA Import:" SPC %this.path; + + %this-->upAxis.clear(); + %this-->upAxis.add("X_AXIS", 1); + %this-->upAxis.add("Y_AXIS", 2); + %this-->upAxis.add("Z_AXIS", 3); + + %this-->lodType.clear(); + %this-->lodType.add("DetectDTS", 1); + %this-->lodType.add("SingleSize", 2); + %this-->lodType.add("TrailingNumber", 3); + + %this-->loadLights.setActive(%canLoadLights); + + // Set model details + %this-->nodes.setText(ColladaImportTreeView._nodeCount); + %this-->meshes.setText(ColladaImportTreeView._meshCount); + %this-->polygons.setText(ColladaImportTreeView._polygonCount); + %this-->materials.setText(ColladaImportTreeView._materialCount); + %this-->lights.setText(ColladaImportTreeView._lightCount); + %this-->animations.setText(ColladaImportTreeView._animCount); + + %this.updateOverrideUpAxis(false); + %this.updateOverrideScale(false); + + if (%this.constructor > 0) + { + if (%this.constructor.upAxis !$= "DEFAULT") + { + %this-->upAxis.setText(%this.constructor.upAxis); + %this.updateOverrideUpAxis(true); + } + if (%this.constructor.unit > 0) + { + %this-->scale.setText(%this.constructor.unit); + %this.updateOverrideScale(true); + } + + %this-->lodType.setText(%this.constructor.lodType); + %this-->singleDetailSize.setText(%this.constructor.singleDetailSize); + %this-->materialPrefix.setText(%this.constructor.matNamePrefix); + %this-->alwaysImport.setText(strreplace(%this.constructor.alwaysImport, "\t", ";")); + %this-->neverImport.setText(strreplace(%this.constructor.neverImport, "\t", ";")); + %this-->alwaysImportMesh.setText(strreplace(%this.constructor.alwaysImportMesh, "\t", ";")); + %this-->neverImportMesh.setText(strreplace(%this.constructor.neverImportMesh, "\t", ";")); + %this-->ignoreNodeScale.setStateOn(%this.constructor.ignoreNodeScale); + %this-->adjustCenter.setStateOn(%this.constructor.adjustCenter); + %this-->adjustFloor.setStateOn(%this.constructor.adjustFloor); + %this-->forceUpdateMaterials.setStateOn(%this.constructor.forceUpdateMaterials); + %this-->loadLights.setStateOn(%this.constructor.loadLights); + } + else + { + // Default settings + %this-->lodType.setText("DetectDTS"); + %this-->singleDetailSize.setText("2"); + %this-->materialPrefix.setText(""); + %this-->alwaysImport.setText(""); + %this-->neverImport.setText(""); + %this-->alwaysImportMesh.setText(""); + %this-->neverImportMesh.setText(""); + %this-->ignoreNodeScale.setStateOn(0); + %this-->adjustCenter.setStateOn(0); + %this-->adjustFloor.setStateOn(0); + %this-->forceUpdateMaterials.setStateOn(0); + %this-->loadLights.setStateOn(0); + } + + Canvas.pushDialog(%this); + + ColladaImportTreeView.refresh("all"); +} + +function ColladaImportDlg::readDtsConfig(%this) +{ + %filename = filePath( %this.path ) @ "/" @ fileBase( %this.path ) @ ".cfg"; + %filename2 = filePath( %this.path ) @ "/" @ "dtsScene.cfg"; + + %fo = new FileObject(); + if ( %fo.openForRead( %filename ) || %fo.openForRead( %filename2 ) ) + { + %alwaysImport = ""; + %neverImport = ""; + + %mode = "none"; + while ( !%fo.isEOF() ) + { + %line = trim( %fo.readLine() ); + + if ( %line $= "AlwaysExport:" ) // Start of the AlwaysExport list + %mode = "always"; + else if ( %line $= "NeverExport:" ) // Start of the NeverExport list + %mode = "never"; + else if ( startswith( %line, "+" ) || startswith( %line, "-" ) ) // Boolean parameters (not supported) + %mode = "none"; + else if ( startswith( %line, "=" ) ) // Float and integer parameters (not supported) + %mode = "none"; + else if ( !startswith( %line, "//" ) ) // Non-commented lines + { + switch$ (%mode) + { + case "always": + %alwaysImport = %alwaysImport TAB %line; + case "never": + %neverImport = %neverImport TAB %line; + } + } + } + %fo.close(); + + %alwaysImport = strreplace( trim( %alwaysImport ), "\t", ";" ); + %neverImport = strreplace( trim( %neverImport ), "\t", ";" ); + + %this-->alwaysImport.setText( %alwaysImport ); + %this-->neverImport.setText( %neverImport ); + } + else + { + error( "Failed to open " @ %filename @ " or " @ %filename2 @ " for reading" ); + } + + %fo.delete(); +} + +function ColladaImportDlg::writeDtsConfig(%this) +{ + %filename = filePath( %this.path ) @ "/" @ fileBase( %this.path ) @ ".cfg"; + + %fo = new FileObject(); + if ( %fo.openForWrite( %filename ) ) + { + // AlwaysImport + %fo.writeLine("AlwaysExport:"); + %alwaysImport = trim( strreplace( %this-->alwaysImport.getText(), ";", "\t" ) ); + %count = getFieldCount( %alwaysImport ); + for (%i = 0; %i < %count; %i++) + %fo.writeLine( getField( %alwaysImport, %i ) ); + %fo.writeLine(""); + + // NeverImport + %fo.writeLine("NeverExport:"); + %neverImport = trim( strreplace( %this-->neverImport.getText(), ";", "\t" ) ); + %count = getFieldCount( %neverImport ); + for (%i = 0; %i < %count; %i++) + %fo.writeLine( getField( %neverImport, %i ) ); + %fo.writeLine(""); + + %fo.close(); + } + else + { + error( "Failed to open " @ %filename @ " for writing" ); + } + + %fo.delete(); +} + +function ColladaImportDlg::updateOverrideUpAxis(%this, %override) +{ + %this-->overrideUpAxis.setStateOn(%override); + %this-->upAxis.setActive(%override); + if (!%override) + %this-->upAxis.setText(ColladaImportTreeView._upAxis); +} + +function ColladaImportDlg::updateOverrideScale(%this, %override) +{ + %this-->overrideScale.setStateOn(%override); + %this-->scale.setActive(%override); + if (!%override) + %this-->scale.setText(ColladaImportTreeView._unit); +} + +function ColladaImportTreeView::refresh(%this, %what) +{ + %shapeRoot = %this.getFirstRootItem(); + %materialsRoot = %this.getNextSibling(%shapeRoot); + %animRoot = %this.getNextSibling(%materialsRoot); + + // Refresh nodes + if ((%what $= "all") || (%what $= "nodes")) + { + // Indicate whether nodes will be ignored on import + %this._alwaysImport = strreplace(ColladaImportDlg-->alwaysImport.getText(), ";", "\t"); + %this._neverImport = strreplace(ColladaImportDlg-->neverImport.getText(), ";", "\t"); + %this._alwaysImportMesh = strreplace(ColladaImportDlg-->alwaysImportMesh.getText(), ";", "\t"); + %this._neverImportMesh = strreplace(ColladaImportDlg-->neverImportMesh.getText(), ";", "\t"); + %this.refreshNode(%this.getChild(%shapeRoot)); + } + + // Refresh materials + if ((%what $= "all") || (%what $= "materials")) + { + %matPrefix = ColladaImportDlg-->materialPrefix.getText(); + %id = %this.getChild(%materialsRoot); + while (%id > 0) + { + %baseName = %this.getItemValue(%id); + %name = %matPrefix @ %baseName; + + // Indicate whether material name is already mapped + %this.editItem(%id, %name, %baseName); + %mapped = getMaterialMapping(%name); + if (%mapped $= "") + { + %this.setItemTooltip(%id, "A new material will be mapped to this name"); + %this.setItemImages(%id, %this._imageMaterial, %this._imageMaterial); + } + else + { + %this.setItemTooltip(%id, %mapped SPC "is already mapped to this material name"); + %this.setItemImages(%id, %this._imageExMaterial, %this._imageExMaterial); + } + + %id = %this.getNextSibling(%id); + } + } + + // Refresh animations + if ((%what $= "all") || (%what $= "animations")) + { + %id = %this.getChild(%animRoot); + while (%id > 0) + { + %this.setItemImages(%id, %this._imageAnim, %this._imageAnim); + %id = %this.getNextSibling(%id); + } + } +} + +function ColladaImportTreeView::refreshNode(%this, %id) +{ + while (%id > 0) + { + switch$ (%this.getItemValue(%id)) + { + case "mesh": + // Check if this mesh will be ignored on import + if (strIsMatchMultipleExpr(%this._alwaysImportMesh, %this.getItemText(%id)) || + !strIsMatchMultipleExpr(%this._neverImportMesh, %this.getItemText(%id)) ) + { + %this.setItemTooltip(%id, ""); + %this.setItemImages(%id, %this._imageMesh, %this._imageMesh); + } + else + { + %this.setItemTooltip(%id, "This mesh will be ignored on import"); + %this.setItemImages(%id, %this._imageExNode, %this._imageExNode); + } + + case "light": + %this.setItemImages(%id, %this._imageLight, %this._imageLight); + + case "node": + // Check if this node will be ignored on import + if (strIsMatchMultipleExpr(%this._alwaysImport, %this.getItemText(%id)) || + !strIsMatchMultipleExpr(%this._neverImport, %this.getItemText(%id)) ) + { + %this.setItemTooltip(%id, ""); + %this.setItemImages(%id, %this._imageNode, %this._imageNode); + } + else + { + %this.setItemTooltip(%id, "This node will be ignored on import"); + %this.setItemImages(%id, %this._imageExNode, %this._imageExNode); + } + } + + // recurse through children and siblings + %this.refreshNode(%this.getChild(%id)); + %id = %this.getNextSibling(%id); + } +} + +function ColladaImportDlg::onCancel(%this) +{ + Canvas.popDialog(%this); + ColladaImportTreeView.clear(); +} + +function ColladaImportDlg::onOK(%this) +{ + Canvas.popDialog(%this); + ColladaImportTreeView.clear(); + + // Need to create a TSShapeConstructor object if any settings are not + // at the default values + if ((%this-->overrideUpAxis.getValue() != 0) || + (%this-->overrideScale.getValue() != 0) || + (%this-->lodType.getText() !$= "DetectDTS") || + (%this-->singleDetailSize.getText() !$= "2") || + (%this-->materialPrefix.getText() !$= "") || + (%this-->alwaysImport.getText() !$= "") || + (%this-->neverImport.getText() !$= "") || + (%this-->alwaysImportMesh.getText() !$= "") || + (%this-->neverImportMesh.getText() !$= "") || + (%this-->ignoreNodeScale.getValue() != 0) || + (%this-->adjustCenter.getValue() != 0) || + (%this-->adjustFloor.getValue() != 0) || + (%this-->forceUpdateMaterials.getValue() != 0) || + (%this-->loadLights.getValue() != 0)) + { + if (%this.constructor <= 0) + { + // Create a new TSShapeConstructor object + %this.constructor = ShapeEditor.createConstructor(%this.path); + } + } + + if (%this.constructor > 0) + { + // Store values from GUI + if (%this-->overrideUpAxis.getValue()) + %this.constructor.upAxis = %this-->upAxis.getText(); + else + %this.constructor.upAxis = "DEFAULT"; + + if (%this-->overrideScale.getValue()) + %this.constructor.unit = %this-->scale.getText(); + else + %this.constructor.unit = -1; + + %this.constructor.lodType = %this-->lodType.getText(); + %this.constructor.singleDetailSize = %this-->singleDetailSize.getText(); + %this.constructor.matNamePrefix = %this-->materialPrefix.getText(); + %this.constructor.alwaysImport = strreplace(%this-->alwaysImport.getText(), ";", "\t"); + %this.constructor.neverImport = strreplace(%this-->neverImport.getText(), ";", "\t"); + %this.constructor.alwaysImportMesh = strreplace(%this-->alwaysImportMesh.getText(), ";", "\t"); + %this.constructor.neverImportMesh = strreplace(%this-->neverImportMesh.getText(), ";", "\t"); + %this.constructor.ignoreNodeScale = %this-->ignoreNodeScale.getValue(); + %this.constructor.adjustCenter = %this-->adjustCenter.getValue(); + %this.constructor.adjustFloor = %this-->adjustFloor.getValue(); + %this.constructor.forceUpdateMaterials = %this-->forceUpdateMaterials.getValue(); + %this.constructor.loadLights = %this-->loadLights.getValue(); + + // Save new settings to file + ShapeEditor.saveConstructor( %this.constructor ); + } + + // Load the shape (always from the DAE) + $collada::forceLoadDAE = true; + eval(%this.cmd); + $collada::forceLoadDAE = false; + + // Optionally load the lights from the DAE as well (only if adding a new shape + // to the scene) + if (%this-->loadLights.getValue()) + %this.loadLights(); +} + +function ColladaImportDlg::loadLights(%this) +{ + // Get the ID of the last object added + %obj = MissionGroup.getObject(MissionGroup.getCount()-1); + + // Create a new SimGroup to hold the model and lights + %group = new SimGroup(); + loadColladaLights(%this.path, %group, %obj); + + // Delete the SimGroup if no lights were found. Otherwise, add the model to + // the group as well. + if (%group.getCount() > 0) + { + %group.add(%obj); + %group.bringToFront(%obj); + MissionGroup.add(%group); + if (EditorTree.isVisible()) + { + EditorTree.removeItem(EditorTree.findItemByObjectId(%obj)); + EditorTree.buildVisibleTree(true); + } + } + else + { + %group.delete(); + } +} + +function updateTSShapeLoadProgress(%progress, %msg) +{ + // Check if the loading GUI is visible and use that instead of the + // separate import progress GUI if possible + if ( isObject(LoadingGui) && LoadingGui.isAwake() ) + { + // Save/Restore load progress at the start/end of the import process + if ( %progress == 0 ) + { + ColladaImportProgress.savedProgress = LoadingProgress.getValue(); + ColladaImportProgress.savedText = LoadingProgressTxt.getValue(); + + ColladaImportProgress.msgPrefix = "Importing " @ %msg; + %msg = "Reading file into memory..."; + } + else if ( %progress == 1.0 ) + { + LoadingProgress.setValue( ColladaImportProgress.savedProgress ); + LoadingProgressTxt.setValue( ColladaImportProgress.savedText ); + } + + %msg = ColladaImportProgress.msgPrefix @ ": " @ %msg; + + %progressCtrl = LoadingProgress; + %textCtrl = LoadingProgressTxt; + } + else + { + // Show/Hide gui at the start/end of the import process + if ( %progress == 0 ) + { + ColladaImportProgress-->window.text = "Importing" SPC %msg; + %msg = "Reading file into memory..."; + Canvas.pushDialog(ColladaImportProgress); + } + else if ( %progress == 1.0 ) + { + Canvas.popDialog(ColladaImportProgress); + } + + %progressCtrl = ColladaImportProgress-->progressBar; + %textCtrl = ColladaImportProgress-->progressText; + } + + // Update progress indicators + if (%progress == 0) + { + %progressCtrl.setValue(0.001); + %textCtrl.setText(%msg); + } + else if (%progress != 1.0) + { + %progressCtrl.setValue(%progress); + %textCtrl.setText(%msg); + } + + Canvas.repaint(33); +} + + +// Convert all COLLADA models that match the given pattern (defaults to *) to DTS +function convertColladaModels(%pattern) +{ + // Force loading the COLLADA file (to ensure cached DTS is updated) + $collada::forceLoadDAE = true; + + %fullPath = findFirstFile("*.dae"); + while (%fullPath !$= "") + { + // Check if this file is inside the given path + %fullPath = makeRelativePath(%fullPath, getMainDotCSDir()); + if ((%pattern $= "") || strIsMatchMultipleExpr(%pattern, %fullPath)) + { + // Load the model by creating a temporary TSStatic + echo("Converting " @ %fullPath @ " to DTS..."); + %temp = new TSStatic() { + shapeName = %fullPath; + collisionType = "None"; + }; + %temp.delete(); + } + + %fullPath = findNextFile("*.dae"); + } + + $collada::forceLoadDAE = false; +} diff --git a/Templates/Empty/game/tools/gui/colorPicker.ed.gui b/Templates/Empty/game/tools/gui/colorPicker.ed.gui new file mode 100644 index 000000000..4c83ac3e7 --- /dev/null +++ b/Templates/Empty/game/tools/gui/colorPicker.ed.gui @@ -0,0 +1,523 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiColorPickerCtrl(ColorPickerDlg,EditorGuiGroup) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + DisplayMode = "Dropper"; // this makes the background visible + ActionOnMove = "1"; + + new GuiWindowCtrl(GuiPickerDlg) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + position = "170 100"; + Extent = "348 347"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Color Picker"; + maxLength = "255"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "DoColorPickerCancelCallback(); ColorPickerDlg.getRoot().popDialog(ColorPickerDlg);"; + + new GuiBitmapBorderCtrl(){ // color blend + Profile = "GuiGroupBorderProfile"; + position = "3 24"; + Extent = "255 258"; + }; + new GuiBitmapBorderCtrl(){ // Hue + Profile = "GuiGroupBorderProfile"; + position = "263 23"; + Extent = "25 261"; + }; + new GuiBitmapBorderCtrl(){ // new old color + Profile = "GuiGroupBorderProfile"; + position = "292 37"; + Extent = "52 99"; + }; + new GuiBitmapBorderCtrl(){ // rgb + Profile = "GuiGroupBorderProfile"; + position = "292 209"; + Extent = "52 75"; + }; + new GuiBitmapBorderCtrl(){ // alpha + Profile = "GuiGroupBorderProfile"; + position = "3 287"; + Extent = "341 24"; + }; + new GuiColorPickerCtrl(ColorBlendSelect) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "3 24"; + Extent = "255 258"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + command = "updateRGBValues(1);"; + hovertime = "1000"; + baseColor = "1 0 0 1"; + PickColor = "0 0 0 1"; + SelectorGap = "1"; + DisplayMode = "BlendColor"; + ActionOnMove = "1"; + }; + new GuiColorPickerCtrl(ColorRangeSelect) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "264 24"; + Extent = "21 257"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "updatePickerBaseColor(1);"; + hovertime = "1000"; + baseColor = "1 0 0 1"; + PickColor = "1 0 0 1"; + SelectorGap = "1"; + DisplayMode = "VertColor"; + ActionOnMove = "1"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "298 215"; + Extent = "8 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "R"; + maxLength = "255"; + }; + new GuiTextEditCtrl(Channel_R_Val) { // Red Channal + Profile = "GuiTextEditProfileNumbersOnly"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "307 215"; + Extent = "34 18"; + text = "0"; + maxLength = "4"; + altCommand = "setColorInfo();"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "297 238"; + Extent = "8 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "G"; + maxLength = "255"; + }; + new GuiTextEditCtrl(Channel_G_Val) { // Green Channal + Profile = "GuiTextEditProfileNumbersOnly"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "307 238"; + Extent = "34 18"; + text = "0"; + maxLength = "4"; + altCommand = "setColorInfo();"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "298 261"; + Extent = "8 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "B"; + maxLength = "255"; + }; + new GuiTextEditCtrl(Channel_B_Val) { // Blue Channal + Profile = "GuiTextEditProfileNumbersOnly"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "307 261"; + Extent = "34 18"; + text = "0"; + maxLength = "4"; + altCommand = "setColorInfo();"; + }; + + + new GuiControl() { + class = "AggregateControl"; + position = "2 290"; + Extent = "341 18"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "267 0"; + Extent = "29 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Alpha"; + maxLength = "255"; + }; + new GuiSliderCtrl(ColorAlphaSelect) { + internalName = "slider"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 3"; + Extent = "251 13"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); updateColorPickerAlpha( $ThisControl.getValue() );"; + hovertime = "1000"; + range = "0 1"; + ticks = "0"; + value = "1"; + }; + new GuiTextEditCtrl(Channel_A_Val) { // Alpha Channal + internalName = "textEdit"; + Profile = "GuiTextEditProfileNumbersOnly"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "305 0"; + Extent = "34 18"; + text = "0"; + maxLength = "4"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); updateColorPickerAlpha( $ThisControl.getValue() );"; + }; + }; + new GuiSwatchButtonCtrl(myColor){ // New Color // + Profile = "GuiDefaultProfile"; + position = "293 38"; + Extent = "50 50"; + }; + new GuiTextCtrl(){ + Profile = "GuiDefaultProfile"; + text = "New"; + position = "306 22"; + Extent = "26 14"; + }; + new GuiSwatchButtonCtrl(oldColor){ // Old Color // + Profile = "GuiDefaultProfile"; + position = "293 85"; + Extent = "50 50"; + }; + new GuiTextCtrl(){ + Profile = "GuiDefaultProfile"; + text = "Old"; + position = "310 138"; + Extent = "26 14"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "144 316"; + Extent = "115 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "DoColorPickerCallback();"; + hovertime = "1000"; + text = "Select"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "268 316"; + Extent = "73 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "DoColorPickerCancelCallback();"; + hovertime = "1000"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + +$ColorPickerCallback = ""; // Control that we need to update +$ColorPickerCancelCallback = ""; +$ColorPickerUpdateCallback = ""; +$ColorCallbackType = 1; // ColorI + +function ColorFloatToInt( %color ) +{ + %red = getWord( %color, 0 ); + %green = getWord( %color, 1 ); + %blue = getWord( %color, 2 ); + %alpha = getWord( %color, 3 ); + + return mCeil( %red * 255 ) SPC mCeil( %green * 255 ) SPC mCeil( %blue * 255 ) SPC mCeil( %alpha * 255 ); +} + +function ColorIntToFloat( %color ) +{ + %red = getWord( %color, 0 ); + %green = getWord( %color, 1 ); + %blue = getWord( %color, 2 ); + %alpha = getWord( %color, 3 ); + + return ( %red / 255 ) SPC ( %green / 255 ) SPC ( %blue / 255 ) SPC ( %alpha / 255 ); +} + +// This function pushes the color picker dialog and returns to a callback the selected value +function GetColorI( %currentColor, %callback, %root, %updateCallback, %cancelCallback ) +{ + $ColorPickerSignal = 1; + $ColorPickerCallback = %callback; + $ColorPickerCancelCallback = %cancelCallback; + $ColorPickerUpdateCallback = %updateCallback; + $ColorCallbackType = 1; // ColorI + + oldColor.color = ColorIntToFloat( %currentColor ); + myColor.color = ColorIntToFloat( %currentColor ); + + ColorRangeSelect.showReticle = true; + ColorBlendSelect.showReticle = true; + + // Set the range according to int + ColorAlphaSelect.range = "0 255"; + + // Set the RGBA displays accordingly + %red = getWord(%currentColor, 0) / 255; + %green = getWord(%currentColor, 1) / 255; + %blue = getWord(%currentColor, 2) / 255; + %alpha = getWord(%currentColor, 3); + + // set the initial range blend to correct color, no alpha needed + // this should also set the color blend select right now + ColorRangeSelect.baseColor = %red SPC %green SPC %blue SPC "1.0"; + ColorRangeSelect.updateColor(); + + if(!isObject(%root)) + %root = Canvas; + + %root.pushDialog(ColorPickerDlg); + + // update the alpha value first + ColorAlphaSelect.setValue( %alpha ); + Channel_A_Val.setText( %alpha ); +} + +function GetColorF( %currentColor, %callback, %root, %updateCallback, %cancelCallback ) +{ + $ColorPickerSignal = 1; + $ColorPickerCallback = %callback; + $ColorPickerCancelCallback = %cancelCallback; + $ColorPickerUpdateCallback = %updateCallback; + $ColorCallbackType = 2; // ColorF + + oldColor.color = %currentColor; + myColor.color = %currentColor; + + ColorRangeSelect.showReticle = true; + ColorBlendSelect.showReticle = true; + + // Set the range according to float + ColorAlphaSelect.range = "0 1"; + + // Set the RGBA displays accordingly + %red = getWord(%currentColor, 0); + %green = getWord(%currentColor, 1); + %blue = getWord(%currentColor, 2); + %alpha = getWord(%currentColor, 3); + + // set the initial range blend to correct color, no alpha needed + // this should also set the color blend select right now + ColorRangeSelect.baseColor = %red SPC %green SPC %blue SPC "1.0"; + ColorRangeSelect.updateColor(); + + if(!isObject(%root)) + %root = Canvas; + %root.pushDialog(ColorPickerDlg); + + // update the alpha value first + ColorAlphaSelect.setValue( %alpha ); + Channel_A_Val.setText( %alpha ); +} + +// This function is used to update the text controls at the top +function setColorInfo() +{ + %red = Channel_R_Val.getValue(); + %green = Channel_G_Val.getValue(); + %blue = Channel_B_Val.getValue(); + + if( $ColorCallbackType == 1) + { + %red = (%red / 255); + %green = (%green / 255); + %blue = (%blue / 255); + } + + $ColorPickerSignal = 1; + + ColorBlendSelect.baseColor = %red SPC %green SPC %blue SPC "1.0"; + ColorBlendSelect.updateColor(); +} + +// return mycolor.color +function DoColorPickerCallback() +{ + eval( $ColorPickerCallback @ "(\"" @ constructNewColor(mycolor.color, $ColorCallbackType) @"\");" ); + ColorPickerDlg.getRoot().popDialog(ColorPickerDlg); +} + +function DoColorPickerCancelCallback() +{ + ColorPickerDlg.getRoot().popDialog( ColorPickerDlg ); + if( $ColorPickerCancelCallback !$= "" ) + eval( $ColorPickerCancelCallback @ "(\"" @ constructNewColor( oldColor.color, $ColorCallbackType ) @ "\");" ); +} + +function DoColorPickerUpdateCallback() +{ + if( $ColorPickerUpdateCallback !$= "" ) + eval( $ColorPickerUpdateCallback @ "(\"" @ constructNewColor( myColor.color, $ColorCallbackType ) @ "\");" ); +} + +// this is called from ColorRangeSelect.updateColor +function updatePickerBaseColor( %location ) +{ + if( $ColorPickerSignal && %location ) + %pickColor = ColorRangeSelect.baseColor; + else + %pickColor = ColorRangeSelect.pickColor; + $ColorPickerSignal = 1; + + %red = getWord(%pickColor, 0); + %green = getWord(%pickColor, 1); + %blue = getWord(%pickColor, 2); + %alpha = getWord(%pickColor, 3); + + ColorBlendSelect.baseColor = %red SPC %green SPC %blue SPC "1.0"; + ColorBlendSelect.updateColor(); +} + +// this is called from ColorBlendSelect.updateColor +function updateRGBValues( %location ) +{ + //update the color based on where it came from + if( $ColorPickerSignal && %location ) + %pickColor = ColorBlendSelect.baseColor; + else + %pickColor = ColorBlendSelect.pickColor; + + //lets prepare the color + %red = getWord(%pickColor, 0); + %green = getWord(%pickColor, 1); + %blue = getWord(%pickColor, 2); + //the alpha should be grabbed from mycolor + %alpha = getWord(myColor.color, 3); + + // set the color! + myColor.color = %red SPC %green SPC %blue SPC %alpha ; + + DoColorPickerUpdateCallback(); + + //update differently depending on type + if( $ColorCallbackType == 1 ) + { + %red = mCeil(%red * 255); + %blue = mCeil(%blue * 255); + %green = mCeil(%green * 255); + } + else + { + %red = mFloatLength(%red, 3); + %blue = mFloatLength(%blue, 3); + %green = mFloatLength(%green, 3); + } + + // changes current color values + Channel_R_Val.setValue(%red); + Channel_G_Val.setValue(%green); + Channel_B_Val.setValue(%blue); + + $ColorPickerSignal = 0; +} + +function updateColorPickerAlpha( %alphaVal ) +{ + //lets prepare the color + %red = getWord(myColor.color, 0); + %green = getWord(myColor.color, 1); + %blue = getWord(myColor.color, 2); + %alpha = %alphaVal; + + if( $ColorCallbackType == 1 ) + %alpha = (%alpha / 255); + + myColor.color = %red SPC %green SPC %blue SPC %alpha ; + + DoColorPickerUpdateCallback(); +} + +function constructNewColor(%pickColor, %colorType ) +{ + %red = getWord(%pickColor, 0); + %green = getWord(%pickColor, 1); + %blue = getWord(%pickColor, 2); + %alpha = ColorAlphaSelect.getValue(); + + // Update the text controls to reflect new color + //setColorInfo(%red, %green, %blue, %alpha); + if ( %colorType == 1 ) // ColorI + return mCeil( %red * 255 ) SPC mCeil( %green * 255 ) SPC mCeil( %blue * 255 ) SPC %alpha; + else // ColorF + return %red SPC %green SPC %blue SPC %alpha; +} diff --git a/Templates/Empty/game/tools/gui/cursors.ed.cs b/Templates/Empty/game/tools/gui/cursors.ed.cs new file mode 100644 index 000000000..7e1ffbf7c --- /dev/null +++ b/Templates/Empty/game/tools/gui/cursors.ed.cs @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +new GuiCursor(LeftRightCursor) +{ + hotSpot = "0.5 0"; + renderOffset = "0.5 0"; + bitmapName = "./Images/leftRight"; +}; + +new GuiCursor(UpDownCursor) +{ + hotSpot = "1 1"; + renderOffset = "0 1"; + bitmapName = "./Images/upDown"; +}; + +new GuiCursor(NWSECursor) +{ + hotSpot = "1 1"; + renderOffset = "0.5 0.5"; + bitmapName = "./Images/NWSE"; +}; + +new GuiCursor(NESWCursor) +{ + hotSpot = "1 1"; + renderOffset = "0.5 0.5"; + bitmapName = "./Images/NESW"; +}; + +new GuiCursor(MoveCursor) +{ + hotSpot = "1 1"; + renderOffset = "0.5 0.5"; + bitmapName = "./Images/move"; +}; + +new GuiCursor(TextEditCursor) +{ + hotSpot = "1 1"; + renderOffset = "0.5 0.5"; + bitmapName = "./Images/textEdit"; +}; diff --git a/Templates/Empty/game/tools/gui/fileDialogBase.ed.cs b/Templates/Empty/game/tools/gui/fileDialogBase.ed.cs new file mode 100644 index 000000000..9d40e0434 --- /dev/null +++ b/Templates/Empty/game/tools/gui/fileDialogBase.ed.cs @@ -0,0 +1,331 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// File Dialog Base - Add to Sim Callback +// Purpose : Intitialize Variables and Setup State. +//----------------------------------------------------------------------------- +function FileDialogBase::onAdd( %this ) +{ + // Callback function Succeed + %this.SuccessCallback = 0; + // Callback function Cancel + %this.CancelCallback = 0; + + // Multiple Select Flag + %this.MultipleSelect = false; + + // File Extensions Group + %this.FileExtensions = new SimGroup(); + + %this.AddFilter("*.*","All Files"); +} + +//----------------------------------------------------------------------------- +// File Dialog Base - Remove from Sim Callback +// Purpose : Destroy Resources. +//----------------------------------------------------------------------------- +function FileDialogBase::onRemove( %this ) +{ + + // Remove FileExtensions Group + if ( isObject( %this.FileExtensions ) ) + %this.FileExtensions.delete(); + + // Remove Returned Files Group + if( isObject( %this.ReturnFiles ) ) + %this.ReturnFiles.delete(); +} + +//----------------------------------------------------------------------------- +// File Dialog Base - Show on Screen Callback +// Purpose : Destroy Resources. +//----------------------------------------------------------------------------- +function FileDialogBase::onWake( %this ) +{ + // Necessary + %dirTree = %this.findObjectByInternalName("DirectoryTree", true); + %fileList = %this.findObjectByInternalName("FileList", true); + %filterList = %this.findObjectByInternalName("FilterList", true); + %cancelButton = %this.findObjectByInternalName("CancelButton", true); + %okButton = %this.findObjectByInternalName("OkButton", true); + + // Optional + %fileName = %this.findObjectByInternalName("FileName", true); + + // Check for functionality Components. + if( !isObject( %dirTree ) || !isObject( %fileList ) || !isObject( %filterList ) ) + { + error("FileDialogBase::onWake - Unable to find NECESSARY child controls."); + return false; + } + + // Check for button components. + if( !isObject( %cancelButton ) || !isObject( %okButton ) ) + { + error("FileDialogBase::onWake - Unable to find accept and cancel buttons!"); + return false; + } + + // Tag controls so that they can navigate our dialog. + %dirTree.parent = %this; + %fileList.parent = %this; + %filterList.parent = %this; + %okButton.parent = %this; + %cancelButton.parent = %this; + + // Tag optionals + if( isObject( %fileName ) ) + %fileName.parent = %this; + + // Finally, make sure our ReturnFiles group is empty. + if( isObject( %this.ReturnFiles ) ) + %this.ReturnFiles.delete(); + + %this.ReturnFiles = new SimGroup(); + %this.add( %this.ReturnFiles ); + + // If no filters + if( %this.GetFilterCount() == 0 ) + %this.addfilter("*.*","All Files"); + + %this.PopulateFilters(); + +} + +//----------------------------------------------------------------------------- +// File Dialog Base - Add a file extension filter to the list +//----------------------------------------------------------------------------- +function FileDialogBase::AddFilter( %this, %extension, %caption ) +{ + if( !isObject( %this.FileExtensions ) ) + { + error("OpenFileDialog::AddFilter - FileExtensions Group does not exist!"); + return false; + } + + %filter = new ScriptObject() + { + extension = %extension; + caption = %caption; + }; + + // Add to filter list + %this.FileExtensions.add( %filter ); + + return %filter; +} + +//----------------------------------------------------------------------------- +// File Dialog Base - Clear filters by file extension +//----------------------------------------------------------------------------- +function FileDialogBase::ClearFilters( %this ) +{ + if( isObject( %this.FileExtensions ) ) + %this.FileExtensions.delete(); + + %this.FileExtensions = new SimGroup(); +} + + +//----------------------------------------------------------------------------- +// File Dialog Base - Get number of filters +//----------------------------------------------------------------------------- +function FileDialogBase::GetFilterCount( %this ) +{ + if( !isObject( %this.FileExtensions ) ) + return 0; + + // Return Count + return %this.FileExtensions.getCount(); + +} + +//----------------------------------------------------------------------------- +// File Dialog Base - Populate dropdown with filter options +//----------------------------------------------------------------------------- +function FileDialogBase::PopulateFilters( %this ) +{ + %fileExtensions = %this.FileExtensions; + if( !isObject( %fileExtensions ) ) + { + error("OpenFileDialog::PopulateFilters - FileExtensions Group does not exist!"); + return false; + } + + %filterList = %this.findObjectByInternalName("FilterList", true); + if( !isObject( %filterList ) ) + { + error("FileDialogBase::PopulateFilters - Filter List Dropdown not found!"); + return false; + } + + // Clear filter list + %filterList.clear(); + + // Populate List + for( %i = 0; %i < %fileExtensions.getCount(); %i++ ) + { + // Fetch Filter Script Object + %filter = %fileExtensions.getObject( %i ); + + // Add item to list + %filterList.add( %filter.Caption SPC "(" SPC %filter.Extension SPC ")", %filter.getID() ); + } + + // Set First Item to Selected. + %filterList.setFirstSelected(); + + +} + +function FileDialogOkButton::onClick( %this ) +{ + if( !isObject( %this.parent ) ) + { + error("FileDialogBase->FileDialogOkButton::onClick - Unable to find proper parent control! Functionality Compromised!"); + return; + } + + %dirTree = %this.parent.findObjectByInternalName("DirectoryTree", true); + %fileList = %this.parent.findObjectByInternalName("FileList", true); + %filterList = %this.parent.findObjectByInternalName("FilterList", true); + + // Check for functionality Components. + if( !isObject( %dirTree ) || !isObject( %fileList ) || !isObject( %filterList ) ) + { + error("FileDialogOkButton::onClick - Unable to find NECESSARY sibling controls."); + return; + } + + // + // Fetch Path + // + %path = %dirTree.getSelectedPath(); + + // + // Compose File Name + // + %fileNameCtrl = %this.parent.findObjectByInternalName("FileName", true); + + // FileName TextEdit? + if( isObject( %fileNameCtrl ) ) + { + // Get FileName from TextEdit + %fileName = %fileNameCtrl.getText(); + + // Get Filter Object from dropdown list + %filterObj = %filterList.getSelected(); + + // Validate File Extension + if( fileExt( %fileName ) $= "" && isObject( %filterObj ) ) + { + // Append Extension to FileName + %fileName = %fileName @ fileExt( %filterObj.Extension ); + } + } + else + %fileName = %fileList.getSelectedFile(); + + // + // Build Full Path + // + %fullPath = %path @ "/" @ %fileName; + + Canvas.popDialog( %this.parent ); + + // Callback + eval( %this.parent.SuccessCallback @ "(\"" @ %fullPath @"\");" ); + + %parent.SuccessCallback = 0; + + //error("Ok"); + +} + +function FileDialogCancelButton::onClick( %this ) +{ + Canvas.popDialog( %this.parent ); + //error("Cancel"); +} + + +function FileDialogDirectoryTree::onSelectPath( %this, %path ) +{ + %fileList = %this.parent.findObjectByInternalName("FileList", true); + %filterList = %this.parent.findObjectByInternalName("FilterList", true); + + + %filterObj = %filterList.getSelected(); + if( !isObject( %filterObj ) ) + %filter = "*.*"; + else + %filter = %filterObj.Extension; + + %fileList.setPath( %path, %filter ); +} + + +function FileDialogFilterList::onSelect( %this, %id, %text ) +{ + if( !isObject( %id ) ) + { + error("FileDialogFilterList::onSelect - Invalid Filter Object!"); + return; + } + + %fileList = %this.parent.findObjectByInternalName("FileList", true); + + %fileList.setFilter( %id.Extension ); + +} + + +function FileDialogFileList::onDoubleClick( %this ) +{ + //error("DoubleClick"); + %okButton = %this.parent.findObjectByInternalName("OkButton", true); + + if( isObject( %okButton ) ) + %okButton.performClick(); +} + +function FileDialogFileList::onSelect( %this, %listid, %file ) +{ + %fileNameCtrl = %this.parent.findObjectByInternalName("FileName", true); + + // FileName TextEdit? + if( !isObject( %fileNameCtrl ) ) + return; + + // Update our file name to the one selected + %fileNameCtrl.setText( %file ); +} + +function FileDialogFileName::onReturn( %this ) +{ + //error("onReturn"); + %okButton = %this.parent.findObjectByInternalName("OkButton", true); + + if( isObject( %okButton ) ) + %okButton.performClick(); +} diff --git a/Templates/Empty/game/tools/gui/guiDialogs.ed.cs b/Templates/Empty/game/tools/gui/guiDialogs.ed.cs new file mode 100644 index 000000000..a4e535abd --- /dev/null +++ b/Templates/Empty/game/tools/gui/guiDialogs.ed.cs @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +exec("./fileDialogBase.ed.cs"); +exec("./openFileDialog.ed.cs"); +exec("./saveFileDialog.ed.cs"); +exec("./saveChangesMBDlg.ed.gui"); +exec("./simViewDlg.ed.gui"); +exec("./colorPicker.ed.gui"); +exec("./materialSelector.ed.gui"); +exec("./scriptEditorDlg.ed.gui"); +exec("./colladaImport.ed.gui"); +exec("./EditorLoadingGui.gui"); +exec("./GuiEaseEditDlg.ed.gui"); +exec("./GuiEaseEditDlg.ed.cs"); +exec("./guiObjectInspector.ed.cs"); +exec("./uvEditor.ed.gui"); +exec("./objectSelection.ed.cs"); + +if (isDemo()) + exec("./messageBoxOKBuy.ed.gui"); diff --git a/Templates/Empty/game/tools/gui/guiObjectInspector.ed.cs b/Templates/Empty/game/tools/gui/guiObjectInspector.ed.cs new file mode 100644 index 000000000..33b65f6bd --- /dev/null +++ b/Templates/Empty/game/tools/gui/guiObjectInspector.ed.cs @@ -0,0 +1,248 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// The "Object Inspector" is a useful little window for browsing and editing SimObject +// hierarchies. Be aware that there is no undo in the inspector. + +//--------------------------------------------------------------------------------------------- + +/// Bring up a new inspector window on the given object. +function inspectObject( %object ) +{ + if( !isObject( %object ) ) + { + error( "inspectObject: no object '" @ %object @ "'" ); + return; + } + + // Create a new object inspector window. + exec( "./guiObjectInspector.ed.gui" ); + + if( !isObject( %guiContent) ) + { + error( "InspectObject: failed to create GUI from 'guiObjectInspector.ed.gui'" ); + return; + } + + // Initialize the inspector. + + %guiContent.init( %object ); + + Canvas.getContent().add( %guiContent ); +} + +//============================================================================================= +// GuiObjectInspector +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiObjectInspector::init( %this, %object ) +{ + if( !%object.isMemberOfClass( "SimSet" ) ) + { + // Complete deletely the splitter and the left-side part of the inspector + // leaving only the field inspector. + + %this.add( %this-->panel2 ); + %this-->splitter.delete(); + %this-->inspector.inspect( %object ); + %this-->methodList.init( %object ); + } + else + { + %treeView = %this-->treeView; + %treeView.inspectorCtrl = %this-->inspector; + %treeView.methodList = %this-->methodList; + + %treeView.open( %object ); + } + + // Set window caption. + + %caption = "Object Inspector - " @ %object.getId() @ " : " @ %object.getClassName(); + + %name = %object.getName(); + if( %name !$= "" ) + %caption = %caption @ " - " @ %name; + + %this.text = %caption; +} + +//--------------------------------------------------------------------------------------------- + +function GuiObjectInspector::onClose( %this ) +{ + // Delete us. + %this.schedule( 1, "delete" ); +} + +//============================================================================================= +// GuiObjectInspectorTree +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiObjectInspectorTree::onSelect( %this, %object ) +{ + if( isObject( %object ) ) + { + %this.inspectorCtrl.inspect( %object ); + %this.methodList.init( %object ); + } +} + +//--------------------------------------------------------------------------------------------- + +function GuiObjectInspectorTree::onRightMouseUp( %this, %itemId, %mousePos, %object ) +{ + if( !isObject( GuiObjectInspectorTreePopup ) ) + new PopupMenu( GuiObjectInspectorTreePopup ) + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Jump to Definition in Torsion" TAB "" TAB "EditorOpenDeclarationInTorsion( %this.object );"; + + object = ""; + }; + + GuiObjectInspectorTreePopup.object = %object; + GuiObjectInspectorTreePopup.showPopup( Canvas ); +} + +//============================================================================================= +// GuiObjectInspectorMethodList +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiObjectInspectorMethodList::init( %this, %object ) +{ + %this.clear(); + + %methods = %object.dumpMethods(); + %count = %methods.count(); + %methodsGroup = %this.insertItem( 0, "Methods" ); + %parentScripted = %this.insertItem( %methodsGroup, "Scripted" ); + %parentNative = %this.insertItem( %methodsGroup, "Native" ); + + for( %i = 0; %i < %count; %i ++ ) + { + %name = %methods.getKey( %i ); + %value = %methods.getValue( %i ); + %prototype = getRecord( %value, 2 ); + %fileName = getRecord( %value, 3 ); + %lineNumber = getRecord( %value, 4 ); + %usage = getRecords( %value, 5 ); + + %tooltip = %prototype; + if( isFile( %fileName ) ) + { + %parent = %parentScripted; + %tooltip = %tooltip NL "Declared in: " @ %fileName @ ":" @ %lineNumber; + } + else + %parent = %parentNative; + + %tooltip = %tooltip @ "\n\n" @ %usage; + + %id = %this.insertItem( %parent, %prototype, %fileName NL %lineNumber ); + %this.setItemTooltip( %id, %tooltip ); + } + + %methods.delete(); + + if( %object.isMethod( "getDebugInfo" ) ) + { + %debugInfo = %object.getDebugInfo(); + %count = %debugInfo.count(); + %parent = %this.insertItem( 0, "Debug Info" ); + + for( %i = 0; %i < %count; %i ++ ) + %id = %this.insertItem( %parent, %debugInfo.getKey( %i ) @ ": " @ %debugInfo.getValue( %i ) ); + + %debugInfo.delete(); + } + + %this.sort( 0, true ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiObjectInspectorMethodList::onRightMouseUp( %this, %item, %mousePos ) +{ + %value = %this.getItemValue( %item ); + if( %value $= "" ) + return; + + %fileName = getRecord( %value, 0 ); + %lineNumber = getRecord( %value, 1 ); + + if( isFile( %fileName ) ) + { + if( !isObject( GuiInspectorMethodListPopup ) ) + new PopupMenu( GuiInspectorMethodListPopup ) + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Jump to Definition in Torsion" TAB "" TAB "EditorOpenFileInTorsion( %this.jumpFileName, %this.jumpLineNumber );"; + + jumpFileName = ""; + jumpLineNumber = ""; + }; + + GuiInspectorMethodListPopup.jumpFileName = %fileName; + GuiInspectorMethodListPopup.jumpLineNumber = %lineNumber; + + GuiInspectorMethodListPopup.showPopup( Canvas ); + } +} + +//============================================================================================= +// GuiObjectInspectorTreeFilter +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiObjectInspectorTreeFilter::onWake( %this ) +{ + %treeView = %this.getParent()-->TreeView; + if( isObject( %treeView ) ) + %this.treeView = %treeView; + + Parent::onWake( %this ); +} + +//============================================================================================= +// GuiObjectInspectorTreeFilter +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiObjectInspectorTreeFilterClearButton::onWake( %this ) +{ + %filterText = %this.getParent()-->FilterText; + if( isObject( %filterText ) ) + %this.textCtrl = %filterText; +} diff --git a/Templates/Empty/game/tools/gui/guiObjectInspector.ed.gui b/Templates/Empty/game/tools/gui/guiObjectInspector.ed.gui new file mode 100644 index 000000000..3e73b9de0 --- /dev/null +++ b/Templates/Empty/game/tools/gui/guiObjectInspector.ed.gui @@ -0,0 +1,401 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiWindowCollapseCtrl() { + collapseGroup = "-1"; + collapseGroupNum = "-1"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "1"; + canMaximize = "1"; + minSize = "50 50"; + closeCommand = "$ThisControl.onClose();"; + edgeSnap = "1"; + text = "Object Inspector"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "GuiWindowProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "152 130"; + extent = "658 472"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "GuiObjectInspector"; + className = "GuiObjectInspector"; + + new GuiSplitContainer() { + orientation = "Vertical"; + splitterSize = "2"; + splitPoint = "300 100"; + fixedPanel = "None"; + fixedSize = "100"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "1 21"; + extent = "656 448"; + minExtent = "64 64"; + canSave = "1"; + visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "Splitter"; + canSaveDynamicFields = "0"; + + new GuiPanel() { + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "GuiDefaultProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "0 0"; + extent = "298 448"; + minExtent = "16 16"; + canSave = "1"; + visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "Panel1"; + canSaveDynamicFields = "0"; + + new GuiTextEditCtrl() { + position = "2 3"; + extent = "278 18"; + profile = "GuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + superClass = "GuiTreeViewFilterText"; + class = "GuiObjectInspectorTreeFilter"; + internalName = "FilterText"; + }; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/clear-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "281 4"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + superClass = "GuiTreeViewFilterClearButton"; + class = "GuiObjectInspectorTreeFilterClearButton"; + }; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "GuiScrollProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "1 22"; + extent = "297 426"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTreeViewCtrl() { + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "0"; + mouseDragging = "0"; + multipleSelections = "0"; + deleteObjectAllowed = "0"; + dragToItemAllowed = "0"; + clearAllOnSingleSelection = "1"; + showRoot = "1"; + internalNamesOnly = "0"; + objectNamesOnly = "0"; + useInspectorTooltips = "0"; + tooltipOnWidthOnly = "0"; + compareToObjectID = "1"; + canRenameObjects = "1"; + renameInternal = "0"; + isContainer = "1"; + profile = "GuiTreeViewProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "1 1"; + extent = "166 21"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "TreeView"; + canSaveDynamicFields = "0"; + class = "GuiObjectInspectorTree"; + }; + }; + }; + new GuiPanel() { + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "302 0"; + extent = "354 448"; + minExtent = "16 16"; + canSave = "1"; + visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "panel2"; + canSaveDynamicFields = "0"; + + new GuiSplitContainer() { + orientation = "Horizontal"; + splitterSize = "2"; + splitPoint = "100 300"; + fixedPanel = "None"; + fixedSize = "100"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 2"; + extent = "354 448"; + minExtent = "64 64"; + canSave = "1"; + visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiPanel() { + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "354 298"; + minExtent = "16 16"; + canSave = "1"; + visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "Panel1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "GuiScrollProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "354 298"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiInspector() { + dividerMargin = "5"; + showCustomFields = "1"; + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "1"; + dynamicSize = "1"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + isContainer = "1"; + profile = "GuiInspectorProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "1 1"; + extent = "337 16"; + minExtent = "16 16"; + canSave = "1"; + visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "inspector"; + canSaveDynamicFields = "0"; + class = "GuiObjectInspectorFields"; + className = "GuiObjectInspectorFields"; + superClass = "EditorInspectorBase"; + }; + }; + }; + new GuiPanel() { + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 302"; + extent = "354 146"; + minExtent = "16 50"; + canSave = "1"; + visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "panel2"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "GuiScrollProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "354 146"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTreeViewCtrl() { + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + mouseDragging = "0"; + multipleSelections = "0"; + deleteObjectAllowed = "0"; + dragToItemAllowed = "0"; + clearAllOnSingleSelection = "1"; + showRoot = "1"; + internalNamesOnly = "0"; + objectNamesOnly = "0"; + useInspectorTooltips = "0"; + tooltipOnWidthOnly = "0"; + compareToObjectID = "1"; + canRenameObjects = "1"; + renameInternal = "0"; + isContainer = "1"; + profile = "GuiTreeViewProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "1 1"; + extent = "109 42"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "methodList"; + canSaveDynamicFields = "0"; + class = "GuiObjectInspectorMethodList"; + className = "GuiObjectInspectorMethodList"; + }; + }; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/gui/images/ColladaImport/iconAnimation.png b/Templates/Empty/game/tools/gui/images/ColladaImport/iconAnimation.png new file mode 100644 index 000000000..480dfce70 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/ColladaImport/iconAnimation.png differ diff --git a/Templates/Empty/game/tools/gui/images/ColladaImport/iconExistingMaterial.png b/Templates/Empty/game/tools/gui/images/ColladaImport/iconExistingMaterial.png new file mode 100644 index 000000000..a7e472232 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/ColladaImport/iconExistingMaterial.png differ diff --git a/Templates/Empty/game/tools/gui/images/ColladaImport/iconIgnoreNode.png b/Templates/Empty/game/tools/gui/images/ColladaImport/iconIgnoreNode.png new file mode 100644 index 000000000..744df795a Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/ColladaImport/iconIgnoreNode.png differ diff --git a/Templates/Empty/game/tools/gui/images/ColladaImport/iconLight.png b/Templates/Empty/game/tools/gui/images/ColladaImport/iconLight.png new file mode 100644 index 000000000..bd47c6187 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/ColladaImport/iconLight.png differ diff --git a/Templates/Empty/game/tools/gui/images/ColladaImport/iconMaterial.png b/Templates/Empty/game/tools/gui/images/ColladaImport/iconMaterial.png new file mode 100644 index 000000000..e5c83d942 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/ColladaImport/iconMaterial.png differ diff --git a/Templates/Empty/game/tools/gui/images/ColladaImport/iconMesh.png b/Templates/Empty/game/tools/gui/images/ColladaImport/iconMesh.png new file mode 100644 index 000000000..e0b7e7f94 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/ColladaImport/iconMesh.png differ diff --git a/Templates/Empty/game/tools/gui/images/ColladaImport/iconNode.png b/Templates/Empty/game/tools/gui/images/ColladaImport/iconNode.png new file mode 100644 index 000000000..a24d6052d Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/ColladaImport/iconNode.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/align-bottom_d.png b/Templates/Empty/game/tools/gui/images/GUI-editor/align-bottom_d.png new file mode 100644 index 000000000..57abbf499 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/align-bottom_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/align-bottom_h.png b/Templates/Empty/game/tools/gui/images/GUI-editor/align-bottom_h.png new file mode 100644 index 000000000..f506cda5a Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/align-bottom_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/align-bottom_n.png b/Templates/Empty/game/tools/gui/images/GUI-editor/align-bottom_n.png new file mode 100644 index 000000000..38fcc753d Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/align-bottom_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/align-left_d.png b/Templates/Empty/game/tools/gui/images/GUI-editor/align-left_d.png new file mode 100644 index 000000000..585cee321 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/align-left_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/align-left_h.png b/Templates/Empty/game/tools/gui/images/GUI-editor/align-left_h.png new file mode 100644 index 000000000..88ad2882a Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/align-left_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/align-left_n.png b/Templates/Empty/game/tools/gui/images/GUI-editor/align-left_n.png new file mode 100644 index 000000000..a86581d31 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/align-left_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/align-right_d.png b/Templates/Empty/game/tools/gui/images/GUI-editor/align-right_d.png new file mode 100644 index 000000000..7ac9b2eb4 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/align-right_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/align-right_h.png b/Templates/Empty/game/tools/gui/images/GUI-editor/align-right_h.png new file mode 100644 index 000000000..7ae17f933 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/align-right_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/align-right_n.png b/Templates/Empty/game/tools/gui/images/GUI-editor/align-right_n.png new file mode 100644 index 000000000..4ba926e19 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/align-right_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/align-top_d.png b/Templates/Empty/game/tools/gui/images/GUI-editor/align-top_d.png new file mode 100644 index 000000000..5380df5c4 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/align-top_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/align-top_h.png b/Templates/Empty/game/tools/gui/images/GUI-editor/align-top_h.png new file mode 100644 index 000000000..368fcab20 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/align-top_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/align-top_n.png b/Templates/Empty/game/tools/gui/images/GUI-editor/align-top_n.png new file mode 100644 index 000000000..be9738647 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/align-top_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/bring-to-front_d.png b/Templates/Empty/game/tools/gui/images/GUI-editor/bring-to-front_d.png new file mode 100644 index 000000000..a98c192dd Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/bring-to-front_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/bring-to-front_h.png b/Templates/Empty/game/tools/gui/images/GUI-editor/bring-to-front_h.png new file mode 100644 index 000000000..c8289f7a0 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/bring-to-front_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/bring-to-front_n.png b/Templates/Empty/game/tools/gui/images/GUI-editor/bring-to-front_n.png new file mode 100644 index 000000000..0f768fbc6 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/bring-to-front_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/centersnap_d.png b/Templates/Empty/game/tools/gui/images/GUI-editor/centersnap_d.png new file mode 100644 index 000000000..fc95fc3e6 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/centersnap_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/centersnap_h.png b/Templates/Empty/game/tools/gui/images/GUI-editor/centersnap_h.png new file mode 100644 index 000000000..b6a4015a3 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/centersnap_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/centersnap_n.png b/Templates/Empty/game/tools/gui/images/GUI-editor/centersnap_n.png new file mode 100644 index 000000000..189932ef9 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/centersnap_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/distribute-horizontal_d.png b/Templates/Empty/game/tools/gui/images/GUI-editor/distribute-horizontal_d.png new file mode 100644 index 000000000..204b03d47 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/distribute-horizontal_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/distribute-horizontal_h.png b/Templates/Empty/game/tools/gui/images/GUI-editor/distribute-horizontal_h.png new file mode 100644 index 000000000..886496372 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/distribute-horizontal_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/distribute-horizontal_n.png b/Templates/Empty/game/tools/gui/images/GUI-editor/distribute-horizontal_n.png new file mode 100644 index 000000000..5025483b5 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/distribute-horizontal_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/distribute-vertical_d.png b/Templates/Empty/game/tools/gui/images/GUI-editor/distribute-vertical_d.png new file mode 100644 index 000000000..205af2b98 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/distribute-vertical_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/distribute-vertical_h.png b/Templates/Empty/game/tools/gui/images/GUI-editor/distribute-vertical_h.png new file mode 100644 index 000000000..1dc903759 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/distribute-vertical_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/distribute-vertical_n.png b/Templates/Empty/game/tools/gui/images/GUI-editor/distribute-vertical_n.png new file mode 100644 index 000000000..fd4de0f1a Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/distribute-vertical_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/edgesnap_d.png b/Templates/Empty/game/tools/gui/images/GUI-editor/edgesnap_d.png new file mode 100644 index 000000000..a368096d8 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/edgesnap_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/edgesnap_h.png b/Templates/Empty/game/tools/gui/images/GUI-editor/edgesnap_h.png new file mode 100644 index 000000000..ad60be2bf Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/edgesnap_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/edgesnap_n.png b/Templates/Empty/game/tools/gui/images/GUI-editor/edgesnap_n.png new file mode 100644 index 000000000..b39ed929b Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/edgesnap_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/gui-library_d.png b/Templates/Empty/game/tools/gui/images/GUI-editor/gui-library_d.png new file mode 100644 index 000000000..0aaa49872 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/gui-library_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/gui-library_h.png b/Templates/Empty/game/tools/gui/images/GUI-editor/gui-library_h.png new file mode 100644 index 000000000..aeb7e4b5e Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/gui-library_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/gui-library_n.png b/Templates/Empty/game/tools/gui/images/GUI-editor/gui-library_n.png new file mode 100644 index 000000000..abeaba153 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/gui-library_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/horizontal-center_d.png b/Templates/Empty/game/tools/gui/images/GUI-editor/horizontal-center_d.png new file mode 100644 index 000000000..554647640 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/horizontal-center_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/horizontal-center_h.png b/Templates/Empty/game/tools/gui/images/GUI-editor/horizontal-center_h.png new file mode 100644 index 000000000..e02673324 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/horizontal-center_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/horizontal-center_n.png b/Templates/Empty/game/tools/gui/images/GUI-editor/horizontal-center_n.png new file mode 100644 index 000000000..0233a804c Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/horizontal-center_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/send-to-back_d.png b/Templates/Empty/game/tools/gui/images/GUI-editor/send-to-back_d.png new file mode 100644 index 000000000..4c405c57e Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/send-to-back_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/send-to-back_h.png b/Templates/Empty/game/tools/gui/images/GUI-editor/send-to-back_h.png new file mode 100644 index 000000000..d25111b61 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/send-to-back_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/send-to-back_n.png b/Templates/Empty/game/tools/gui/images/GUI-editor/send-to-back_n.png new file mode 100644 index 000000000..70721965f Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/send-to-back_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/snap-grid_d.png b/Templates/Empty/game/tools/gui/images/GUI-editor/snap-grid_d.png new file mode 100644 index 000000000..e97dd429d Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/snap-grid_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/snap-grid_h.png b/Templates/Empty/game/tools/gui/images/GUI-editor/snap-grid_h.png new file mode 100644 index 000000000..fa681e049 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/snap-grid_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/snap-grid_n.png b/Templates/Empty/game/tools/gui/images/GUI-editor/snap-grid_n.png new file mode 100644 index 000000000..ca97f4e92 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/snap-grid_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/vertical-center_d.png b/Templates/Empty/game/tools/gui/images/GUI-editor/vertical-center_d.png new file mode 100644 index 000000000..9b580ad5b Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/vertical-center_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/vertical-center_h.png b/Templates/Empty/game/tools/gui/images/GUI-editor/vertical-center_h.png new file mode 100644 index 000000000..a2d561142 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/vertical-center_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/GUI-editor/vertical-center_n.png b/Templates/Empty/game/tools/gui/images/GUI-editor/vertical-center_n.png new file mode 100644 index 000000000..d0f6c45e5 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/GUI-editor/vertical-center_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/NESW.png b/Templates/Empty/game/tools/gui/images/NESW.png new file mode 100644 index 000000000..2f73696c8 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/NESW.png differ diff --git a/Templates/Empty/game/tools/gui/images/NWSE.png b/Templates/Empty/game/tools/gui/images/NWSE.png new file mode 100644 index 000000000..c952a3e45 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/NWSE.png differ diff --git a/Templates/Empty/game/tools/gui/images/add-simgroup-btn_ctrl_d.png b/Templates/Empty/game/tools/gui/images/add-simgroup-btn_ctrl_d.png new file mode 100644 index 000000000..c8a9417b4 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/add-simgroup-btn_ctrl_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/add-simgroup-btn_ctrl_h.png b/Templates/Empty/game/tools/gui/images/add-simgroup-btn_ctrl_h.png new file mode 100644 index 000000000..fa7c424b7 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/add-simgroup-btn_ctrl_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/add-simgroup-btn_ctrl_n.png b/Templates/Empty/game/tools/gui/images/add-simgroup-btn_ctrl_n.png new file mode 100644 index 000000000..47842cd61 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/add-simgroup-btn_ctrl_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/add-simgroup-btn_d.png b/Templates/Empty/game/tools/gui/images/add-simgroup-btn_d.png new file mode 100644 index 000000000..c8a9417b4 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/add-simgroup-btn_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/add-simgroup-btn_h.png b/Templates/Empty/game/tools/gui/images/add-simgroup-btn_h.png new file mode 100644 index 000000000..fa7c424b7 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/add-simgroup-btn_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/add-simgroup-btn_n.png b/Templates/Empty/game/tools/gui/images/add-simgroup-btn_n.png new file mode 100644 index 000000000..68252b834 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/add-simgroup-btn_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/axis-icon_-x.png b/Templates/Empty/game/tools/gui/images/axis-icon_-x.png new file mode 100644 index 000000000..6f52027b7 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/axis-icon_-x.png differ diff --git a/Templates/Empty/game/tools/gui/images/axis-icon_-y.png b/Templates/Empty/game/tools/gui/images/axis-icon_-y.png new file mode 100644 index 000000000..613dcc43f Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/axis-icon_-y.png differ diff --git a/Templates/Empty/game/tools/gui/images/axis-icon_-z.png b/Templates/Empty/game/tools/gui/images/axis-icon_-z.png new file mode 100644 index 000000000..6bdc9cb91 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/axis-icon_-z.png differ diff --git a/Templates/Empty/game/tools/gui/images/axis-icon_x.png b/Templates/Empty/game/tools/gui/images/axis-icon_x.png new file mode 100644 index 000000000..305caf6b5 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/axis-icon_x.png differ diff --git a/Templates/Empty/game/tools/gui/images/axis-icon_y.png b/Templates/Empty/game/tools/gui/images/axis-icon_y.png new file mode 100644 index 000000000..6f7988bdf Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/axis-icon_y.png differ diff --git a/Templates/Empty/game/tools/gui/images/axis-icon_z.png b/Templates/Empty/game/tools/gui/images/axis-icon_z.png new file mode 100644 index 000000000..1b3c12f80 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/axis-icon_z.png differ diff --git a/Templates/Empty/game/tools/gui/images/camera-btn_d.png b/Templates/Empty/game/tools/gui/images/camera-btn_d.png new file mode 100644 index 000000000..6029aa915 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/camera-btn_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/camera-btn_h.png b/Templates/Empty/game/tools/gui/images/camera-btn_h.png new file mode 100644 index 000000000..a088f2213 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/camera-btn_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/camera-btn_n.png b/Templates/Empty/game/tools/gui/images/camera-btn_n.png new file mode 100644 index 000000000..372a267bb Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/camera-btn_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/clear-icon_d.png b/Templates/Empty/game/tools/gui/images/clear-icon_d.png new file mode 100644 index 000000000..ffca76c89 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/clear-icon_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/clear-icon_h.png b/Templates/Empty/game/tools/gui/images/clear-icon_h.png new file mode 100644 index 000000000..e424b7e0e Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/clear-icon_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/clear-icon_n.png b/Templates/Empty/game/tools/gui/images/clear-icon_n.png new file mode 100644 index 000000000..a82689274 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/clear-icon_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/copy-btn_d.png b/Templates/Empty/game/tools/gui/images/copy-btn_d.png new file mode 100644 index 000000000..4212ecae0 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/copy-btn_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/copy-btn_h.png b/Templates/Empty/game/tools/gui/images/copy-btn_h.png new file mode 100644 index 000000000..3de0ae110 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/copy-btn_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/copy-btn_i.png b/Templates/Empty/game/tools/gui/images/copy-btn_i.png new file mode 100644 index 000000000..528d6bf93 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/copy-btn_i.png differ diff --git a/Templates/Empty/game/tools/gui/images/copy-btn_n.png b/Templates/Empty/game/tools/gui/images/copy-btn_n.png new file mode 100644 index 000000000..b2e88b654 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/copy-btn_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/delete_d.png b/Templates/Empty/game/tools/gui/images/delete_d.png new file mode 100644 index 000000000..6ffdf6d2e Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/delete_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/delete_h.png b/Templates/Empty/game/tools/gui/images/delete_h.png new file mode 100644 index 000000000..7a1ac2e31 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/delete_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/delete_n.png b/Templates/Empty/game/tools/gui/images/delete_n.png new file mode 100644 index 000000000..1cbe067cf Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/delete_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/folderUp.png b/Templates/Empty/game/tools/gui/images/folderUp.png new file mode 100644 index 000000000..c188909a1 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/folderUp.png differ diff --git a/Templates/Empty/game/tools/gui/images/folderUp_d.png b/Templates/Empty/game/tools/gui/images/folderUp_d.png new file mode 100644 index 000000000..c329f0372 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/folderUp_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/folderUp_h.png b/Templates/Empty/game/tools/gui/images/folderUp_h.png new file mode 100644 index 000000000..953fe8b40 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/folderUp_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/iconAccept.png b/Templates/Empty/game/tools/gui/images/iconAccept.png new file mode 100644 index 000000000..a24d6052d Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/iconAccept.png differ diff --git a/Templates/Empty/game/tools/gui/images/iconAdd.png b/Templates/Empty/game/tools/gui/images/iconAdd.png new file mode 100644 index 000000000..323edb029 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/iconAdd.png differ diff --git a/Templates/Empty/game/tools/gui/images/iconCancel.png b/Templates/Empty/game/tools/gui/images/iconCancel.png new file mode 100644 index 000000000..744df795a Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/iconCancel.png differ diff --git a/Templates/Empty/game/tools/gui/images/iconCollada.png b/Templates/Empty/game/tools/gui/images/iconCollada.png new file mode 100644 index 000000000..0f4017014 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/iconCollada.png differ diff --git a/Templates/Empty/game/tools/gui/images/iconDelete.png b/Templates/Empty/game/tools/gui/images/iconDelete.png new file mode 100644 index 000000000..3ba9615b4 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/iconDelete.png differ diff --git a/Templates/Empty/game/tools/gui/images/iconIcon.png b/Templates/Empty/game/tools/gui/images/iconIcon.png new file mode 100644 index 000000000..e5c83d942 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/iconIcon.png differ diff --git a/Templates/Empty/game/tools/gui/images/iconInformation.png b/Templates/Empty/game/tools/gui/images/iconInformation.png new file mode 100644 index 000000000..a7e472232 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/iconInformation.png differ diff --git a/Templates/Empty/game/tools/gui/images/iconList.png b/Templates/Empty/game/tools/gui/images/iconList.png new file mode 100644 index 000000000..39b80d238 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/iconList.png differ diff --git a/Templates/Empty/game/tools/gui/images/iconLocked.png b/Templates/Empty/game/tools/gui/images/iconLocked.png new file mode 100644 index 000000000..2e72d2fb2 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/iconLocked.png differ diff --git a/Templates/Empty/game/tools/gui/images/iconNew.png b/Templates/Empty/game/tools/gui/images/iconNew.png new file mode 100644 index 000000000..2446ae662 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/iconNew.png differ diff --git a/Templates/Empty/game/tools/gui/images/iconOpen.png b/Templates/Empty/game/tools/gui/images/iconOpen.png new file mode 100644 index 000000000..29e80d77a Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/iconOpen.png differ diff --git a/Templates/Empty/game/tools/gui/images/iconRefresh.png b/Templates/Empty/game/tools/gui/images/iconRefresh.png new file mode 100644 index 000000000..cce137ba5 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/iconRefresh.png differ diff --git a/Templates/Empty/game/tools/gui/images/iconSave.png b/Templates/Empty/game/tools/gui/images/iconSave.png new file mode 100644 index 000000000..50e70bd70 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/iconSave.png differ diff --git a/Templates/Empty/game/tools/gui/images/iconUnlocked.png b/Templates/Empty/game/tools/gui/images/iconUnlocked.png new file mode 100644 index 000000000..a471765ff Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/iconUnlocked.png differ diff --git a/Templates/Empty/game/tools/gui/images/iconVisible.png b/Templates/Empty/game/tools/gui/images/iconVisible.png new file mode 100644 index 000000000..92c857866 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/iconVisible.png differ diff --git a/Templates/Empty/game/tools/gui/images/layers-btn_d.png b/Templates/Empty/game/tools/gui/images/layers-btn_d.png new file mode 100644 index 000000000..6694b71eb Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/layers-btn_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/layers-btn_h.png b/Templates/Empty/game/tools/gui/images/layers-btn_h.png new file mode 100644 index 000000000..ec27d03ce Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/layers-btn_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/layers-btn_n.png b/Templates/Empty/game/tools/gui/images/layers-btn_n.png new file mode 100644 index 000000000..eb0f253ed Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/layers-btn_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/leftRight.png b/Templates/Empty/game/tools/gui/images/leftRight.png new file mode 100644 index 000000000..c29b7a9f8 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/leftRight.png differ diff --git a/Templates/Empty/game/tools/gui/images/lock_d.png b/Templates/Empty/game/tools/gui/images/lock_d.png new file mode 100644 index 000000000..b7177a257 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/lock_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/lock_h.png b/Templates/Empty/game/tools/gui/images/lock_h.png new file mode 100644 index 000000000..b4eac3fcd Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/lock_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/lock_n.png b/Templates/Empty/game/tools/gui/images/lock_n.png new file mode 100644 index 000000000..91ec2a444 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/lock_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/arrow_d.png b/Templates/Empty/game/tools/gui/images/menubar/arrow_d.png new file mode 100644 index 000000000..783480242 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/arrow_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/arrow_h.png b/Templates/Empty/game/tools/gui/images/menubar/arrow_h.png new file mode 100644 index 000000000..2afa04469 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/arrow_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/arrow_n.png b/Templates/Empty/game/tools/gui/images/menubar/arrow_n.png new file mode 100644 index 000000000..9f924edf1 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/arrow_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/bounds-center_d.png b/Templates/Empty/game/tools/gui/images/menubar/bounds-center_d.png new file mode 100644 index 000000000..e063a47cd Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/bounds-center_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/bounds-center_h.png b/Templates/Empty/game/tools/gui/images/menubar/bounds-center_h.png new file mode 100644 index 000000000..898ccfffb Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/bounds-center_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/bounds-center_n.png b/Templates/Empty/game/tools/gui/images/menubar/bounds-center_n.png new file mode 100644 index 000000000..3bcbcf525 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/bounds-center_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/delete-btn_d.png b/Templates/Empty/game/tools/gui/images/menubar/delete-btn_d.png new file mode 100644 index 000000000..4d1d130b3 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/delete-btn_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/delete-btn_h.png b/Templates/Empty/game/tools/gui/images/menubar/delete-btn_h.png new file mode 100644 index 000000000..90709bd63 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/delete-btn_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/delete-btn_i.png b/Templates/Empty/game/tools/gui/images/menubar/delete-btn_i.png new file mode 100644 index 000000000..49af5bf83 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/delete-btn_i.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/delete-btn_n.png b/Templates/Empty/game/tools/gui/images/menubar/delete-btn_n.png new file mode 100644 index 000000000..b5c09a25d Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/delete-btn_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/explode-prefab_d.png b/Templates/Empty/game/tools/gui/images/menubar/explode-prefab_d.png new file mode 100644 index 000000000..8e27bfefd Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/explode-prefab_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/explode-prefab_h.png b/Templates/Empty/game/tools/gui/images/menubar/explode-prefab_h.png new file mode 100644 index 000000000..2ff2bf46a Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/explode-prefab_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/explode-prefab_i.png b/Templates/Empty/game/tools/gui/images/menubar/explode-prefab_i.png new file mode 100644 index 000000000..54e78d5c1 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/explode-prefab_i.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/explode-prefab_n.png b/Templates/Empty/game/tools/gui/images/menubar/explode-prefab_n.png new file mode 100644 index 000000000..09a7ddb22 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/explode-prefab_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/fit-selection_d.png b/Templates/Empty/game/tools/gui/images/menubar/fit-selection_d.png new file mode 100644 index 000000000..75159d266 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/fit-selection_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/fit-selection_h.png b/Templates/Empty/game/tools/gui/images/menubar/fit-selection_h.png new file mode 100644 index 000000000..a2c39cff4 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/fit-selection_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/fit-selection_n.png b/Templates/Empty/game/tools/gui/images/menubar/fit-selection_n.png new file mode 100644 index 000000000..5b159dd02 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/fit-selection_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/object-center_d.png b/Templates/Empty/game/tools/gui/images/menubar/object-center_d.png new file mode 100644 index 000000000..284165852 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/object-center_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/object-center_h.png b/Templates/Empty/game/tools/gui/images/menubar/object-center_h.png new file mode 100644 index 000000000..bc725fd9b Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/object-center_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/object-center_n.png b/Templates/Empty/game/tools/gui/images/menubar/object-center_n.png new file mode 100644 index 000000000..b8ea86567 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/object-center_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/object-node-icon_d.png b/Templates/Empty/game/tools/gui/images/menubar/object-node-icon_d.png new file mode 100644 index 000000000..d005211cc Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/object-node-icon_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/object-node-icon_h.png b/Templates/Empty/game/tools/gui/images/menubar/object-node-icon_h.png new file mode 100644 index 000000000..e0b74fe41 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/object-node-icon_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/object-node-icon_n.png b/Templates/Empty/game/tools/gui/images/menubar/object-node-icon_n.png new file mode 100644 index 000000000..b50616a38 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/object-node-icon_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/object-node-lable_d.png b/Templates/Empty/game/tools/gui/images/menubar/object-node-lable_d.png new file mode 100644 index 000000000..765d60e8c Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/object-node-lable_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/object-node-lable_h.png b/Templates/Empty/game/tools/gui/images/menubar/object-node-lable_h.png new file mode 100644 index 000000000..6202e4083 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/object-node-lable_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/object-node-lable_n.png b/Templates/Empty/game/tools/gui/images/menubar/object-node-lable_n.png new file mode 100644 index 000000000..3bcc5e3d0 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/object-node-lable_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/object-transform_d.png b/Templates/Empty/game/tools/gui/images/menubar/object-transform_d.png new file mode 100644 index 000000000..88aa68825 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/object-transform_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/object-transform_h.png b/Templates/Empty/game/tools/gui/images/menubar/object-transform_h.png new file mode 100644 index 000000000..46d471f2d Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/object-transform_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/object-transform_n.png b/Templates/Empty/game/tools/gui/images/menubar/object-transform_n.png new file mode 100644 index 000000000..065cb1fc7 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/object-transform_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/orbit-cam_d.png b/Templates/Empty/game/tools/gui/images/menubar/orbit-cam_d.png new file mode 100644 index 000000000..48b686e75 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/orbit-cam_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/orbit-cam_h.png b/Templates/Empty/game/tools/gui/images/menubar/orbit-cam_h.png new file mode 100644 index 000000000..34f5439d1 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/orbit-cam_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/orbit-cam_n.png b/Templates/Empty/game/tools/gui/images/menubar/orbit-cam_n.png new file mode 100644 index 000000000..0e34db316 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/orbit-cam_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/rotate_d.png b/Templates/Empty/game/tools/gui/images/menubar/rotate_d.png new file mode 100644 index 000000000..597c85dcb Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/rotate_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/rotate_h.png b/Templates/Empty/game/tools/gui/images/menubar/rotate_h.png new file mode 100644 index 000000000..8f0535f8f Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/rotate_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/rotate_n.png b/Templates/Empty/game/tools/gui/images/menubar/rotate_n.png new file mode 100644 index 000000000..65530d3a9 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/rotate_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/scale_d.png b/Templates/Empty/game/tools/gui/images/menubar/scale_d.png new file mode 100644 index 000000000..eae3c8394 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/scale_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/scale_h.png b/Templates/Empty/game/tools/gui/images/menubar/scale_h.png new file mode 100644 index 000000000..c43e55ff5 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/scale_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/scale_n.png b/Templates/Empty/game/tools/gui/images/menubar/scale_n.png new file mode 100644 index 000000000..fee27ffe0 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/scale_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/select-bounds_d.png b/Templates/Empty/game/tools/gui/images/menubar/select-bounds_d.png new file mode 100644 index 000000000..7c39417de Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/select-bounds_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/select-bounds_h.png b/Templates/Empty/game/tools/gui/images/menubar/select-bounds_h.png new file mode 100644 index 000000000..4fdd99e3b Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/select-bounds_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/select-bounds_n.png b/Templates/Empty/game/tools/gui/images/menubar/select-bounds_n.png new file mode 100644 index 000000000..8a322ce89 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/select-bounds_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/selection-to-prefab_d.png b/Templates/Empty/game/tools/gui/images/menubar/selection-to-prefab_d.png new file mode 100644 index 000000000..94016aa37 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/selection-to-prefab_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/selection-to-prefab_h.png b/Templates/Empty/game/tools/gui/images/menubar/selection-to-prefab_h.png new file mode 100644 index 000000000..4448d3393 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/selection-to-prefab_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/selection-to-prefab_i.png b/Templates/Empty/game/tools/gui/images/menubar/selection-to-prefab_i.png new file mode 100644 index 000000000..9f9b1c55b Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/selection-to-prefab_i.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/selection-to-prefab_n.png b/Templates/Empty/game/tools/gui/images/menubar/selection-to-prefab_n.png new file mode 100644 index 000000000..d30c67f4f Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/selection-to-prefab_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/show-grid_d.png b/Templates/Empty/game/tools/gui/images/menubar/show-grid_d.png new file mode 100644 index 000000000..e149a7e99 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/show-grid_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/show-grid_h.png b/Templates/Empty/game/tools/gui/images/menubar/show-grid_h.png new file mode 100644 index 000000000..5a3f34518 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/show-grid_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/show-grid_n.png b/Templates/Empty/game/tools/gui/images/menubar/show-grid_n.png new file mode 100644 index 000000000..618f71d52 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/show-grid_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/show-preview_d.png b/Templates/Empty/game/tools/gui/images/menubar/show-preview_d.png new file mode 100644 index 000000000..56d08e5d3 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/show-preview_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/show-preview_h.png b/Templates/Empty/game/tools/gui/images/menubar/show-preview_h.png new file mode 100644 index 000000000..39df58c9d Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/show-preview_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/show-preview_n.png b/Templates/Empty/game/tools/gui/images/menubar/show-preview_n.png new file mode 100644 index 000000000..4571767ae Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/show-preview_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/smooth-cam-rot_d.png b/Templates/Empty/game/tools/gui/images/menubar/smooth-cam-rot_d.png new file mode 100644 index 000000000..8c8e2c69c Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/smooth-cam-rot_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/smooth-cam-rot_h.png b/Templates/Empty/game/tools/gui/images/menubar/smooth-cam-rot_h.png new file mode 100644 index 000000000..3af52d968 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/smooth-cam-rot_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/smooth-cam-rot_n.png b/Templates/Empty/game/tools/gui/images/menubar/smooth-cam-rot_n.png new file mode 100644 index 000000000..a6f3081fd Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/smooth-cam-rot_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/smooth-cam_d.png b/Templates/Empty/game/tools/gui/images/menubar/smooth-cam_d.png new file mode 100644 index 000000000..7b0bb6d3a Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/smooth-cam_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/smooth-cam_h.png b/Templates/Empty/game/tools/gui/images/menubar/smooth-cam_h.png new file mode 100644 index 000000000..b7988511c Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/smooth-cam_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/smooth-cam_n.png b/Templates/Empty/game/tools/gui/images/menubar/smooth-cam_n.png new file mode 100644 index 000000000..6168a6613 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/smooth-cam_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/snap-bounds_d.png b/Templates/Empty/game/tools/gui/images/menubar/snap-bounds_d.png new file mode 100644 index 000000000..3da4ee311 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/snap-bounds_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/snap-bounds_h.png b/Templates/Empty/game/tools/gui/images/menubar/snap-bounds_h.png new file mode 100644 index 000000000..b0f4346a0 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/snap-bounds_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/snap-bounds_n.png b/Templates/Empty/game/tools/gui/images/menubar/snap-bounds_n.png new file mode 100644 index 000000000..4c6d83529 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/snap-bounds_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/snap-grid_d.png b/Templates/Empty/game/tools/gui/images/menubar/snap-grid_d.png new file mode 100644 index 000000000..e97dd429d Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/snap-grid_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/snap-grid_h.png b/Templates/Empty/game/tools/gui/images/menubar/snap-grid_h.png new file mode 100644 index 000000000..fa681e049 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/snap-grid_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/snap-grid_n.png b/Templates/Empty/game/tools/gui/images/menubar/snap-grid_n.png new file mode 100644 index 000000000..ca97f4e92 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/snap-grid_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/snap-objects_d.png b/Templates/Empty/game/tools/gui/images/menubar/snap-objects_d.png new file mode 100644 index 000000000..934fd5013 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/snap-objects_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/snap-objects_h.png b/Templates/Empty/game/tools/gui/images/menubar/snap-objects_h.png new file mode 100644 index 000000000..07f0aea50 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/snap-objects_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/snap-objects_n.png b/Templates/Empty/game/tools/gui/images/menubar/snap-objects_n.png new file mode 100644 index 000000000..22e45dc64 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/snap-objects_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/snap-terrain_d.png b/Templates/Empty/game/tools/gui/images/menubar/snap-terrain_d.png new file mode 100644 index 000000000..13dfc2e1e Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/snap-terrain_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/snap-terrain_h.png b/Templates/Empty/game/tools/gui/images/menubar/snap-terrain_h.png new file mode 100644 index 000000000..47cc46b21 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/snap-terrain_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/snap-terrain_n.png b/Templates/Empty/game/tools/gui/images/menubar/snap-terrain_n.png new file mode 100644 index 000000000..4d8534c5e Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/snap-terrain_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/snapping-settings_d.png b/Templates/Empty/game/tools/gui/images/menubar/snapping-settings_d.png new file mode 100644 index 000000000..a879682d1 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/snapping-settings_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/snapping-settings_h.png b/Templates/Empty/game/tools/gui/images/menubar/snapping-settings_h.png new file mode 100644 index 000000000..d11d45932 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/snapping-settings_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/snapping-settings_n.png b/Templates/Empty/game/tools/gui/images/menubar/snapping-settings_n.png new file mode 100644 index 000000000..caac7467d Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/snapping-settings_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/translate_d.png b/Templates/Empty/game/tools/gui/images/menubar/translate_d.png new file mode 100644 index 000000000..39a3487bd Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/translate_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/translate_h.png b/Templates/Empty/game/tools/gui/images/menubar/translate_h.png new file mode 100644 index 000000000..b6e08379f Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/translate_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/translate_n.png b/Templates/Empty/game/tools/gui/images/menubar/translate_n.png new file mode 100644 index 000000000..17f197247 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/translate_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/visibility-toggle_d.png b/Templates/Empty/game/tools/gui/images/menubar/visibility-toggle_d.png new file mode 100644 index 000000000..14e658f0c Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/visibility-toggle_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/visibility-toggle_h.png b/Templates/Empty/game/tools/gui/images/menubar/visibility-toggle_h.png new file mode 100644 index 000000000..0f2fb1f02 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/visibility-toggle_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/visibility-toggle_n.png b/Templates/Empty/game/tools/gui/images/menubar/visibility-toggle_n.png new file mode 100644 index 000000000..25a2d20d8 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/visibility-toggle_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/world-transform_d.png b/Templates/Empty/game/tools/gui/images/menubar/world-transform_d.png new file mode 100644 index 000000000..bafcde2ba Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/world-transform_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/world-transform_h.png b/Templates/Empty/game/tools/gui/images/menubar/world-transform_h.png new file mode 100644 index 000000000..2a34b9071 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/world-transform_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/menubar/world-transform_n.png b/Templates/Empty/game/tools/gui/images/menubar/world-transform_n.png new file mode 100644 index 000000000..0aa45e46c Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/menubar/world-transform_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/move.png b/Templates/Empty/game/tools/gui/images/move.png new file mode 100644 index 000000000..70f9cd540 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/move.png differ diff --git a/Templates/Empty/game/tools/gui/images/new-folder-btn_d.png b/Templates/Empty/game/tools/gui/images/new-folder-btn_d.png new file mode 100644 index 000000000..c8a9417b4 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/new-folder-btn_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/new-folder-btn_h.png b/Templates/Empty/game/tools/gui/images/new-folder-btn_h.png new file mode 100644 index 000000000..fa7c424b7 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/new-folder-btn_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/new-folder-btn_n.png b/Templates/Empty/game/tools/gui/images/new-folder-btn_n.png new file mode 100644 index 000000000..68252b834 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/new-folder-btn_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/open-file_d.png b/Templates/Empty/game/tools/gui/images/open-file_d.png new file mode 100644 index 000000000..00b709b86 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/open-file_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/open-file_h.png b/Templates/Empty/game/tools/gui/images/open-file_h.png new file mode 100644 index 000000000..daf4b14c9 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/open-file_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/open-file_n.png b/Templates/Empty/game/tools/gui/images/open-file_n.png new file mode 100644 index 000000000..8e84251c5 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/open-file_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/reset-icon_d.png b/Templates/Empty/game/tools/gui/images/reset-icon_d.png new file mode 100644 index 000000000..6c9c08a87 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/reset-icon_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/reset-icon_h.png b/Templates/Empty/game/tools/gui/images/reset-icon_h.png new file mode 100644 index 000000000..c0dc85cd6 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/reset-icon_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/reset-icon_n.png b/Templates/Empty/game/tools/gui/images/reset-icon_n.png new file mode 100644 index 000000000..f34269670 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/reset-icon_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/retarget-btn_d.png b/Templates/Empty/game/tools/gui/images/retarget-btn_d.png new file mode 100644 index 000000000..a8854b3f8 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/retarget-btn_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/retarget-btn_h.png b/Templates/Empty/game/tools/gui/images/retarget-btn_h.png new file mode 100644 index 000000000..1cc9a078d Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/retarget-btn_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/retarget-btn_i.png b/Templates/Empty/game/tools/gui/images/retarget-btn_i.png new file mode 100644 index 000000000..60f8b3d4a Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/retarget-btn_i.png differ diff --git a/Templates/Empty/game/tools/gui/images/retarget-btn_n.png b/Templates/Empty/game/tools/gui/images/retarget-btn_n.png new file mode 100644 index 000000000..2a25e1288 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/retarget-btn_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/save-all_d.png b/Templates/Empty/game/tools/gui/images/save-all_d.png new file mode 100644 index 000000000..c2c272de5 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/save-all_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/save-all_h.png b/Templates/Empty/game/tools/gui/images/save-all_h.png new file mode 100644 index 000000000..220cc9313 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/save-all_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/save-all_i.png b/Templates/Empty/game/tools/gui/images/save-all_i.png new file mode 100644 index 000000000..1bc06998f Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/save-all_i.png differ diff --git a/Templates/Empty/game/tools/gui/images/save-all_n.png b/Templates/Empty/game/tools/gui/images/save-all_n.png new file mode 100644 index 000000000..36f0d1553 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/save-all_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/save-as_d.png b/Templates/Empty/game/tools/gui/images/save-as_d.png new file mode 100644 index 000000000..a1905924d Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/save-as_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/save-as_h.png b/Templates/Empty/game/tools/gui/images/save-as_h.png new file mode 100644 index 000000000..e36c98a3b Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/save-as_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/save-as_i.png b/Templates/Empty/game/tools/gui/images/save-as_i.png new file mode 100644 index 000000000..1f52b6499 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/save-as_i.png differ diff --git a/Templates/Empty/game/tools/gui/images/save-as_n.png b/Templates/Empty/game/tools/gui/images/save-as_n.png new file mode 100644 index 000000000..e60ceaef4 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/save-as_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/save-icon_d.png b/Templates/Empty/game/tools/gui/images/save-icon_d.png new file mode 100644 index 000000000..bbb28701f Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/save-icon_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/save-icon_h.png b/Templates/Empty/game/tools/gui/images/save-icon_h.png new file mode 100644 index 000000000..3803ec01e Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/save-icon_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/save-icon_i.png b/Templates/Empty/game/tools/gui/images/save-icon_i.png new file mode 100644 index 000000000..7da2c6fdf Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/save-icon_i.png differ diff --git a/Templates/Empty/game/tools/gui/images/save-icon_n.png b/Templates/Empty/game/tools/gui/images/save-icon_n.png new file mode 100644 index 000000000..9c6a959a7 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/save-icon_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/textEdit.png b/Templates/Empty/game/tools/gui/images/textEdit.png new file mode 100644 index 000000000..cc3da5f85 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/textEdit.png differ diff --git a/Templates/Empty/game/tools/gui/images/upDown.png b/Templates/Empty/game/tools/gui/images/upDown.png new file mode 100644 index 000000000..377217897 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/upDown.png differ diff --git a/Templates/Empty/game/tools/gui/images/uv-editor-btn_d.png b/Templates/Empty/game/tools/gui/images/uv-editor-btn_d.png new file mode 100644 index 000000000..ad481414d Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/uv-editor-btn_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/uv-editor-btn_h.png b/Templates/Empty/game/tools/gui/images/uv-editor-btn_h.png new file mode 100644 index 000000000..0de6d9ebb Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/uv-editor-btn_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/uv-editor-btn_n.png b/Templates/Empty/game/tools/gui/images/uv-editor-btn_n.png new file mode 100644 index 000000000..5ae9ded23 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/uv-editor-btn_n.png differ diff --git a/Templates/Empty/game/tools/gui/images/visible_d.png b/Templates/Empty/game/tools/gui/images/visible_d.png new file mode 100644 index 000000000..329dc6a58 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/visible_d.png differ diff --git a/Templates/Empty/game/tools/gui/images/visible_h.png b/Templates/Empty/game/tools/gui/images/visible_h.png new file mode 100644 index 000000000..5125d50ef Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/visible_h.png differ diff --git a/Templates/Empty/game/tools/gui/images/visible_i.png b/Templates/Empty/game/tools/gui/images/visible_i.png new file mode 100644 index 000000000..eb5e3b267 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/visible_i.png differ diff --git a/Templates/Empty/game/tools/gui/images/visible_n.png b/Templates/Empty/game/tools/gui/images/visible_n.png new file mode 100644 index 000000000..77d302629 Binary files /dev/null and b/Templates/Empty/game/tools/gui/images/visible_n.png differ diff --git a/Templates/Empty/game/tools/gui/materialSelector.ed.gui b/Templates/Empty/game/tools/gui/materialSelector.ed.gui new file mode 100644 index 000000000..84e9f7213 --- /dev/null +++ b/Templates/Empty/game/tools/gui/materialSelector.ed.gui @@ -0,0 +1,2003 @@ +new GuiControl(MaterialSelectorOverlay, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Profile = "GuiOverlayProfile"; + Enabled = "1"; + isContainer = "1"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl(MaterialSelector){ + profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + resizeWidth = "1"; + resizeHeight = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + position = "72 98"; + extent =" 766 550"; + MinExtent = "383 274"; + text = "Material Selector"; + closeCommand = "MaterialSelector::hideDialog();"; + EdgeSnap = "0"; + canCollapse = "0"; + visible = "0"; + + new GuiContainer(){ + isContainer = "1"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "4 22"; + Extent = "120 31"; + Profile = "inspectorStyleRolloutDarkProfile"; + }; + new GuiTextCtrl(){ + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 23"; + extent = "30 16"; + text = "Filters"; + }; + new GuiContainer(){ + profile = "GuiDefaultProfile"; + Position = "4 39"; + Extent = "120 507"; + HorizSizing = "right"; + VertSizing = "height"; + isContainer = "1"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "128 355"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiDefaultProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = true; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + + new GuiDynamicCtrlArrayControl() { + canSaveDynamicFields = "0"; + internalName = "filterArray"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "18 0"; + Extent = "128 195"; + MinExtent = "8 8"; + dynamicSize = "1"; + rowSpacing = "2"; + colSize = "128"; + rowSize = "18"; + }; + }; + }; + new GuiContainer(){ + Profile = "inspectorStyleRolloutDarkProfile"; + Position = "128 22"; + Extent = "480 31"; + HorizSizing = "width"; + VertSizing = "bottom"; + isContainer = "1"; + }; + new GuiTextCtrl(){ + profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "133 23"; + extent = "53 16"; + text = "Materials"; + }; + // Create New Material + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "594 24"; + Extent = "15 15"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialSelector.createNewMaterial();"; + hovertime = "1000"; + tooltip = "Create New Unmapped Material"; + bitmap = "core/art/gui/images/new"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "578 24"; + Extent = "15 15"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialSelector.showDeleteDialog();"; + hovertime = "1000"; + tooltip = "Delete Material"; + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiContainer(){ // Materials + profile = "GuiDefaultProfile"; + Position = "128 39"; + Extent = "480 507"; + HorizSizing = "width"; + VertSizing = "height"; + isContainer = "1"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "480 507"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiDefaultProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiStackControl(){ + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "128 0"; + changeChildPosition = 0; + changeChildSizeToFit = 1; + + new GuiControl(){ + Extent = "0 4"; + }; + new GuiDynamicCtrlArrayControl() { + canSaveDynamicFields = "0"; + internalName = "materialSelection"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "3 0"; + Extent = "128 0"; + MinExtent = "8 8"; + dynamicSize = "1"; + autoCellSize = "1"; + rowSpacing = "2"; + colSpacing = "2"; + margin = "2"; + }; + }; + }; + + new GuiContainer(){ + internalName = "materialPreviewControlContainer"; + profile = "GuiDefaultProfile"; + Position = "0 0"; + Extent = "480 20"; + HorizSizing = "width"; + VertSizing = "height"; + isContainer = "1"; + Docking = "Bottom"; + + new GuiTextCtrl(){ + profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 2"; + extent = "100 16"; + text = "Thumbnails per Page:"; + }; + new GuiPopupMenuCtrlEx(){ + internalName = "materialPreviewCountPopup"; + Profile = "GuiPopupMenuProfile"; + Position = "104 2"; + Extent = "40 18"; + HorizSizing = "right"; + VertSizing = "bottom"; + Command = "MaterialSelector.thumbnailCountUpdate();"; + reverseTextList = "0"; + Text = "16"; + }; + + new GuiStackControl(){ + internalName = "materialPreviewButtonStack"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "480 2"; + Extent = "0 16"; + dynamic = 1; + dynamicPos = 1; + stackingType = "Horizontal"; + changeChildPosition = 1; + changeChildSizeToFit = 1; + padding = 2; + + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "20 16"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "MaterialSelector::firstPage();"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "First"; + hovertime = "1000"; + text = "|<"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "20 16"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "MaterialSelector::previousPage();"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Previous"; + hovertime = "1000"; + text = "<"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + }; + new GuiStackControl(){ + internalName = "materialPreviewPagesStack"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "0 16"; + dynamic = 1; + stackingType = "Horizontal"; + changeChildPosition = 1; + changeChildSizeToFit = 1; + padding = 2; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "20 16"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "MaterialSelector::nextPage();"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Next"; + hovertime = "1000"; + text = ">"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "20 16"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "MaterialSelector::lastPage();"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Last"; + hovertime = "1000"; + text = ">|"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + }; + + }; + }; + }; + new GuiContainer(){ + Profile = "inspectorStyleRolloutDarkProfile"; + Position = "612 206"; + Extent = "150 31"; + HorizSizing = "left"; + VertSizing = "bottom"; + isContainer = "1"; + }; + new GuiTextCtrl(){ + profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "618 207"; + extent = "84 16"; + text = "Material Tags"; + }; + new GuiContainer(){ // Filter Selection + profile = "GuiDefaultProfile"; + Position = "612 223"; + Extent = "150 295"; + HorizSizing = "left"; + VertSizing = "height"; + isContainer = "1"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "128 195"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiDefaultProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiDynamicCtrlArrayControl() { + canSaveDynamicFields = "0"; + internalName = "materialCategories"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "128 195"; + MinExtent = "8 8"; + dynamicSize = "1"; + rowSpacing = "2"; + colSize = "128"; + rowSize = "18"; + }; + }; + }; + new GuiContainer(){ + Profile = "inspectorStyleRolloutDarkProfile"; + Position = "612 22"; + Extent = "150 167"; + HorizSizing = "left"; + VertSizing = "bottom"; + isContainer = "1"; + + new GuiBitmapCtrl(){ + internalName = "previewSelection"; + HorizSizing = "left"; + VertSizing = "bottom"; + profile = "GuiDefaultProfile"; + position = "1 18"; + extent = "148 148"; + bitmap = ""; + }; + }; + new GuiTextCtrl(){ + profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "618 23"; + extent = "84 16"; + text = "Diffuse Preview"; + }; + + new GuiBitmapCtrl(){ + HorizSizing = "left"; + VertSizing = "bottom"; + profile = "GuiDefaultProfile"; + position = "612 39"; + extent = "150 150"; + bitmap = "tools/worldEditor/images/terrainpainter/terrain-painter-border-large"; + visible = false; + }; + new GuiTextCtrl(){ + internalName = "previewSelectionText"; + HorizSizing = "left"; + VertSizing = "bottom"; + profile = "GuiTextProfile"; + position = "613 189"; + extent = "149 16"; + text = ""; + }; + new GuiButtonCtrl(){ + internalName = "SelectButton"; + HorizSizing = "left"; + VertSizing = "top"; + profile = "GuiButtonProfile"; + position = "612 522"; + extent = "94 24"; + text = "Select"; + command = "MaterialSelector.selectMaterial( MaterialSelector.selectedMaterial );"; + }; + new GuiButtonCtrl(){ + HorizSizing = "left"; + VertSizing = "top"; + profile = "GuiButtonProfile"; + position = "710 522"; + extent = "52 24"; + text = "Cancel"; + command = "MaterialSelector.hideDialog();"; + }; + }; + + new GuiWindowCtrl(MaterialSelector_addFilterWindow) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "362 333"; + Extent = "272 99"; + MinExtent = "48 92"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Create New Tag"; + + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "tagName"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "64 35"; + Extent = "196 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "12 35"; + Extent = "52 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + text = "Tag Name"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "64 68"; + Extent = "126 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + text = "Create"; + Command = "MaterialSelector.createFilter( MaterialSelector_addFilterWindow-->tagName.getText() );MaterialSelector_addFilterWindow.setVisible(0);"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "196 68"; + Extent = "64 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + text = "Cancel"; + Command = "MaterialSelector_addFilterWindow.setVisible(0);"; + }; + }; +}; + +$Pref::MaterialSelector::CurrentStaticFilter = "MaterialFilterAllArray"; +$Pref::MaterialSelector::CurrentFilter = ""; //ALL +$Pref::MaterialSelector::ThumbnailCountIndex = 0; + +new PersistenceManager(MaterialSelectorPerMan); + +new ArrayObject(UnlistedMaterials); +UnlistedMaterials.add( "unlistedMaterials", WarningMaterial ); +UnlistedMaterials.add( "unlistedMaterials", materialEd_previewMaterial ); +UnlistedMaterials.add( "unlistedMaterials", notDirtyMaterial ); +UnlistedMaterials.add( "unlistedMaterials", materialEd_cubemapEd_cubeMapPreview ); +UnlistedMaterials.add( "unlistedMaterials", matEdCubeMapPreviewMat ); +UnlistedMaterials.add( "unlistedMaterials", materialEd_justAlphaMaterial ); +UnlistedMaterials.add( "unlistedMaterials", materialEd_justAlphaShader ); + +function MaterialSelector::selectMaterial( %this, %material ) +{ + %name = ""; + + if( MaterialSelector.terrainMaterials ) + { + %name = %material; + %material = TerrainMaterialSet.findObjectByInternalName( %material ); + } + else + { + %name = %material.getName(); + } + + // The callback function should be ready to intake the returned material + //eval("materialEd_previewMaterial." @ %propertyField @ " = " @ %value @ ";"); + if( MaterialSelector.returnType $= "name" ) + eval( "" @ MaterialSelector.selectCallback @ "(" @ %name @ ");"); + else if( MaterialSelector.returnType $= "index" ) + { + %index = -1; + if( MaterialSelector.terrainMaterials ) + { + // Obtain the index into the terrain's material list + %mats = ETerrainEditor.getMaterials(); + for(%i = 0; %i < getRecordCount( %mats ); %i++) + { + %matInternalName = getRecord( %mats, %i ); + if( %matInternalName $= %name ) + { + %index = %i; + break; + } + } + } + else + { + // Obtain the index into the material set + for(%i = 0; %i < materialSet.getCount(); %i++) + { + %obj = materialSet.getObject(%i); + if( %obj.getName() $= %name ) + { + %index = %i; + break; + } + } + } + + eval( "" @ MaterialSelector.selectCallback @ "(" @ %index @ ");"); + } + else + eval( "" @ MaterialSelector.selectCallback @ "(" @ %material.getId() @ ");"); + MaterialSelector.hideDialog(); +} + +function MaterialSelector::showDialog( %this, %selectCallback, %returnType) +{ + if( MaterialSelector.isVisible() ) + return; + + %this.showDialogBase(%selectCallback, %returnType, false); +} + +function MaterialSelector::showTerrainDialog( %this, %selectCallback, %returnType) +{ + %this.showDialogBase(%selectCallback, %returnType, true); +} + +function MaterialSelector::showDialogBase( %this, %selectCallback, %returnType, %useTerrainMaterials) +{ + // Set the select callback + MaterialSelector.selectCallback = %selectCallback; + MaterialSelector.returnType = %returnType; + + MaterialSelector.currentStaticFilter = $Pref::MaterialSelector::CurrentStaticFilter; + MaterialSelector.currentFilter = $Pref::MaterialSelector::CurrentFilter; + + MaterialSelector.terrainMaterials = %useTerrainMaterials; + + MaterialSelector-->materialPreviewCountPopup.clear(); + MaterialSelector-->materialPreviewCountPopup.add( "10", 0 ); + MaterialSelector-->materialPreviewCountPopup.add( "15", 1 ); + MaterialSelector-->materialPreviewCountPopup.add( "25", 2 ); + MaterialSelector-->materialPreviewCountPopup.add( "50", 3 ); + MaterialSelector-->materialPreviewCountPopup.add( "75", 4 ); + MaterialSelector-->materialPreviewCountPopup.add( "100", 5 ); + MaterialSelector-->materialPreviewCountPopup.setSelected( $Pref::MaterialSelector::ThumbnailCountIndex ); + + Canvas.pushDialog(MaterialSelectorOverlay); + MaterialSelector.setVisible(1); + MaterialSelector.buildStaticFilters(); + + MaterialSelector.selectedMaterial = ""; + MaterialSelector.loadMaterialFilters(); +} + +function MaterialSelector::hideDialog( %this ) +{ + MaterialSelector.breakdown(); + MaterialSelector.setVisible(0); + Canvas.popDialog(MaterialSelectorOverlay); +} + +function MaterialSelector::breakdown( %this ) +{ + $Pref::MaterialSelector::CurrentStaticFilter = MaterialSelector.currentStaticFilter; + $Pref::MaterialSelector::CurrentFilter = MaterialSelector.currentFilter; + + MaterialSelector-->filterArray.deleteAllObjects(); + MaterialSelector-->materialSelection.deleteAllObjects(); + MatEdPreviewArray.delete(); + + MaterialSelector-->materialCategories.deleteAllObjects(); + MaterialFilterAllArray.delete(); + MaterialFilterMappedArray.delete(); + MaterialFilterUnmappedArray.delete(); + +} + +function MaterialSelector::buildStaticFilters( %this ) +{ + // if you want to add any more containers to staticFilterObjects, here's + // where to do it + + %staticFilterContainer = new GuiControl (){ + new GuiContainer(){ + profile = "GuiDefaultProfile"; + Position = "0 0"; + Extent = "128 18"; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + parentGroup = %filterArray; + + new GuiContainer(){ + profile = "inspectorStyleRolloutDarkProfile"; + Position = "-1 0"; + Extent = "128 32"; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + }; + new GuiTextCtrl(){ + Profile = "EditorTextProfile"; + position = "5 0"; + Extent = "118 18"; + text = "Types"; + }; + }; + new GuiContainer(){ // All + profile = "GuiDefaultProfile"; + Position = "415 191"; + Extent = "128 18"; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + parentGroup = %filterArray; + + new GuiCheckBoxCtrl(MaterialFilterAllArrayCheckbox){ + Profile = "GuiCheckboxListProfile"; + position = "5 2"; + Extent = "118 18"; + text = "All"; + Command = "MaterialSelector.switchStaticFilters(\"MaterialFilterAllArray\");"; + }; + }; + new GuiContainer(){ // Mapped + profile = "GuiDefaultProfile"; + Position = "415 191"; + Extent = "128 18"; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + parentGroup = %filterArray; + + new GuiCheckBoxCtrl(MaterialFilterMappedArrayCheckbox){ + Profile = "GuiCheckboxListProfile"; + position = "5 2"; + Extent = "118 18"; + text = "Mapped"; + Command = "MaterialSelector.switchStaticFilters(\"MaterialFilterMappedArray\");"; + }; + }; + new GuiContainer(){ // Unmapped + profile = "GuiDefaultProfile"; + Position = "415 191"; + Extent = "128 18"; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + parentGroup = %filterArray; + + new GuiCheckBoxCtrl(MaterialFilterUnmappedArrayCheckbox){ + Profile = "GuiCheckboxListProfile"; + position = "5 2"; + Extent = "118 18"; + text = "Unmapped"; + Command = "MaterialSelector.switchStaticFilters(\"MaterialFilterUnmappedArray\");"; + }; + }; + new GuiContainer(){ + profile = "GuiDefaultProfile"; + Position = "0 0"; + Extent = "128 18"; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + parentGroup = %filterArray; + + new GuiContainer(){ + profile = "inspectorStyleRolloutDarkProfile"; + Position = "-1 0"; + Extent = "128 32"; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + }; + + new GuiTextCtrl(){ + Profile = "EditorTextProfile"; + position = "5 0"; + Extent = "118 18"; + text = "Tags"; + }; + // Create New Tag + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "105 2"; + Extent = "15 15"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialSelector_addFilterWindow.setVisible(1); MaterialSelectorOverlay.pushToBack(MaterialSelector_addFilterWindow);"; + hovertime = "1000"; + tooltip = "Create New Tag"; + bitmap = "core/art/gui/images/new"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "89 2"; + Extent = "13 13"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialSelector.clearMaterialFilters();"; + hovertime = "1000"; + tooltip = "Clear Selected Tag"; + bitmap = "core/art/gui/images/clear-btn"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; + }; + + %i = %staticFilterContainer.getCount(); + for( ; %i != 0; %i--) + MaterialSelector-->filterArray.addGuiControl(%staticFilterContainer.getObject(0)); + + MaterialSelector.staticFilterObjects = MaterialSelector-->filterArray.getCount(); + + %staticFilterContainer.delete(); + + // Create our category array used in the selector, this code should be taken out + // in order to make the material selector agnostic + new ArrayObject(MaterialFilterAllArray); + new ArrayObject(MaterialFilterMappedArray); + new ArrayObject(MaterialFilterUnmappedArray); + + %mats = ""; + %count = 0; + if( MaterialSelector.terrainMaterials ) + { + %mats = ETerrainEditor.getTerrainBlocksMaterialList(); + %count = getRecordCount( %mats ); + } + else + { + %count = materialSet.getCount(); + } + + for(%i = 0; %i < %count; %i++) + { + // Process terrain materials + if( MaterialSelector.terrainMaterials ) + { + %matInternalName = getRecord( %mats, %i ); + %material = TerrainMaterialSet.findObjectByInternalName( %matInternalName ); + + // Is there no material info for this slot? + if ( !isObject( %material ) ) + continue; + + // Add to the appropriate filters + MaterialFilterMappedArray.add( "", %material ); + MaterialFilterAllArray.add( "", %material ); + + continue; + } + + // Process regular materials here + %material = materialSet.getObject(%i); + + for( %k = 0; %k < UnlistedMaterials.count(); %k++ ) + { + %unlistedFound = 0; + if( UnlistedMaterials.getValue(%k) $= %material.name ) + { + %unlistedFound = 1; + break; + } + } + + if( %unlistedFound ) + continue; + + if( %material.mapTo $= "" || %material.mapTo $= "unmapped_mat" ) + { + MaterialFilterUnmappedArray.add( "", %material.name ); + //running through the existing tag names + for( %j = 0; %material.getFieldValue("materialTag" @ %j) !$= ""; %j++ ) + MaterialFilterUnmappedArray.add( %material.getFieldValue("materialTag" @ %j), %material.name ); + } + else + { + MaterialFilterMappedArray.add( "", %material.name ); + for( %j = 0; %material.getFieldValue("materialTag" @ %j) !$= ""; %j++ ) + MaterialFilterMappedArray.add( %material.getFieldValue("materialTag" @ %j), %material.name ); + } + + MaterialFilterAllArray.add( "", %material.name ); + for( %j = 0; %material.getFieldValue("materialTag" @ %j) !$= ""; %j++ ) + MaterialFilterAllArray.add( %material.getFieldValue("materialTag" @ %j), %material.name ); + + } + + MaterialFilterAllArrayCheckbox.setText("All ( " @ MaterialFilterAllArray.count() @" ) "); + MaterialFilterMappedArrayCheckbox.setText("Mapped ( " @ MaterialFilterMappedArray.count() @" ) "); + MaterialFilterUnmappedArrayCheckbox.setText("Unmapped ( " @ MaterialFilterUnmappedArray.count() @" ) "); +} + +function MaterialSelector::preloadFilter( %this ) +{ + %selectedFilter = ""; + for( %i = MaterialSelector.staticFilterObjects; %i < MaterialSelector-->filterArray.getCount(); %i++ ) + { + if( MaterialSelector-->filterArray.getObject(%i).getObject(0).getValue() == 1 ) + { + if( %selectedFilter $= "" ) + %selectedFilter = MaterialSelector-->filterArray.getObject(%i).getObject(0).filter; + else + %selectedFilter = %selectedFilter @ " " @ MaterialSelector-->filterArray.getObject(%i).getObject(0).filter; + } + } + MaterialSelector.loadFilter( %selectedFilter ); +} + +function MaterialSelector::loadFilter( %this, %selectedFilter, %staticFilter ) +{ + // manage schedule array properly + if(!isObject(MatEdScheduleArray)) + new ArrayObject(MatEdScheduleArray); + + // if we select another list... delete all schedules that were created by + // previous load + for( %i = 0; %i < MatEdScheduleArray.count(); %i++ ) + cancel(MatEdScheduleArray.getKey(%i)); + + // we have to empty out the list; so when we create new schedules, these dont linger + MatEdScheduleArray.empty(); + + // manage preview array + if(!isObject(MatEdPreviewArray)) + new ArrayObject(MatEdPreviewArray); + + // we have to empty out the list; so when we create new guicontrols, these dont linger + MatEdPreviewArray.empty(); + MaterialSelector-->materialSelection.deleteAllObjects(); + MaterialSelector-->materialPreviewPagesStack.deleteAllObjects(); + + // changed to accomadate tagging. dig through the array for each tag name, + // call unique value, sort, and we have a perfect set of materials + if( %staticFilter !$= "" ) + MaterialSelector.currentStaticFilter = %staticFilter; + + MaterialSelector.currentFilter = %selectedFilter; + + %filteredObjectsArray = new ArrayObject(); + + %previewsPerPage = MaterialSelector-->materialPreviewCountPopup.getTextById( MaterialSelector-->materialPreviewCountPopup.getSelected() ); + + %tagCount = getWordCount( MaterialSelector.currentFilter ); + if( %tagCount != 0 ) + { + for( %j = 0; %j < %tagCount; %j++ ) + { + for( %i = 0; %i < MaterialSelector.currentStaticFilter.count(); %i++ ) + { + %currentTag = getWord( MaterialSelector.currentFilter, %j ); + if( MaterialSelector.currentStaticFilter.getKey(%i) $= %currentTag) + %filteredObjectsArray.add( MaterialSelector.currentStaticFilter.getKey(%i), MaterialSelector.currentStaticFilter.getValue(%i) ); + } + } + + %filteredObjectsArray.uniqueValue(); + %filteredObjectsArray.sortd(); + + MaterialSelector.totalPages = mCeil( %filteredObjectsArray.count() / %previewsPerPage ); + + //Can we maintain the current preview page, or should we go to page 1? + if( (MaterialSelector.currentPreviewPage * %previewsPerPage) >= %filteredObjectsArray.count() ) + MaterialSelector.currentPreviewPage = 0; + + // Build out the pages buttons + MaterialSelector.buildPagesButtons( MaterialSelector.currentPreviewPage, MaterialSelector.totalPages ); + + %previewCount = %previewsPerPage; + %possiblePreviewCount = %filteredObjectsArray.count() - MaterialSelector.currentPreviewPage * %previewsPerPage; + if( %possiblePreviewCount < %previewCount ) + %previewCount = %possiblePreviewCount; + + %start = MaterialSelector.currentPreviewPage * %previewsPerPage; + for( %i = %start; %i < %start + %previewCount; %i++ ) + MaterialSelector.buildPreviewArray( %filteredObjectsArray.getValue(%i) ); + + %filteredObjectsArray.delete(); + } + else + { + MaterialSelector.currentStaticFilter.sortd(); + + // Rebuild the static filter list without tagged materials + %noTagArray = new ArrayObject(); + for( %i = 0; %i < MaterialSelector.currentStaticFilter.count(); %i++ ) + { + if( MaterialSelector.currentStaticFilter.getKey(%i) !$= "") + continue; + + %material = MaterialSelector.currentStaticFilter.getValue(%i); + + // CustomMaterials are not available for selection + if ( !isObject( %material ) || %material.isMemberOfClass( "CustomMaterial" ) ) + continue; + + %noTagArray.add( "", %material ); + } + + MaterialSelector.totalPages = mCeil( %noTagArray.count() / %previewsPerPage ); + + //Can we maintain the current preview page, or should we go to page 1? + if( (MaterialSelector.currentPreviewPage * %previewsPerPage) >= %noTagArray.count() ) + MaterialSelector.currentPreviewPage = 0; + + // Build out the pages buttons + MaterialSelector.buildPagesButtons( MaterialSelector.currentPreviewPage, MaterialSelector.totalPages ); + + %previewCount = %previewsPerPage; + %possiblePreviewCount = %noTagArray.count() - MaterialSelector.currentPreviewPage * %previewsPerPage; + if( %possiblePreviewCount < %previewCount ) + %previewCount = %possiblePreviewCount; + + %start = MaterialSelector.currentPreviewPage * %previewsPerPage; + for( %i = %start; %i < %start + %previewCount; %i++ ) + { + MaterialSelector.buildPreviewArray( %noTagArray.getValue(%i) ); + } + } + + + MaterialSelector.loadImages( 0 ); +} + + + +function MaterialSelector::buildPreviewArray( %this, %material ) +{ + %matName = ""; + + // CustomMaterials are not available for selection + if ( !isObject( %material ) || %material.isMemberOfClass( "CustomMaterial" ) ) + return; + + if( %material.isMemberOfClass("TerrainMaterial") ) + { + %matName = %material.getInternalName(); + + if( %material.diffuseMap $= "") + %previewImage = "core/art/warnmat"; + else + %previewImage = %material.diffuseMap; + } + else if( %material.toneMap[0] $= "" && %material.diffuseMap[0] $= "" && !isObject(%material.cubemap) ) + { + %matName = %material.name; + %previewImage = "core/art/warnmat"; + } + else + { + %matName = %material.name; + + if( %material.toneMap[0] !$= "" ) + %previewImage = %material.toneMap[0]; + else if( %material.diffuseMap[0] !$= "" ) + %previewImage = %material.diffuseMap[0]; + else if( %material.cubemap.cubeFace[0] !$= "" ) + %previewImage = %material.cubemap.cubeFace[0]; + + //%previewImage = MaterialEditorGui.searchForTexture( %material, %previewImage ); + + // were going to use a couple of string commands in order to properly + // find out what the img src path is + // **NEW** this needs to be updated with the above, but has some timing issues + %materialDiffuse = %previewImage; + %materialPath = %material.getFilename(); + + if( strchr( %materialDiffuse, "/") $= "" ) + { + %k = 0; + while( strpos( %materialPath, "/", %k ) != -1 ) + { + %foo = strpos( %materialPath, "/", %k ); + %k = %foo + 1; + } + + %foobar = getSubStr( %materialPath , %k , 99 ); + %previewImage = strreplace( %materialPath, %foobar, %previewImage ); + } + else + %previewImage = strreplace( %materialPath, %materialPath, %previewImage ); + } + + // it may seem goofy why the checkbox can't be instanciated inside the container + // reason being its because we need to store the checkbox ctrl in order to make changes + // on it later in the function. + + %container = new GuiControl(){ + profile = "GuiDefaultProfile"; + Position = "0 0"; + Extent = "74 87"; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + + new GuiTextCtrl(){ + position = "7 71"; + profile = "GuiTextCenterProfile"; + extent = "64 16"; + text = %matName; + }; + }; + + %previewButton = new GuiBitmapButtonCtrl(){ + internalName = %matName; + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "GuiButtonProfile"; + position = "7 4"; + extent = "64 64"; + buttonType = "PushButton"; + bitmap = ""; + Command = ""; + text = "Loading..."; + useStates = false; + + new GuiBitmapButtonCtrl(){ + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "GuiButtonProfile"; + position = "0 0"; + extent = "64 64"; + Variable = ""; + buttonType = "toggleButton"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + groupNum = "0"; + text = ""; + }; + }; + + %previewBorder = new GuiButtonCtrl(){ + internalName = %matName@"Border"; + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "GuiThumbHighlightButtonProfile"; + position = "3 0"; + extent = "72 88"; + Variable = ""; + buttonType = "toggleButton"; + tooltip = %matName; + Command = "MaterialSelector.updateSelection( $ThisControl.getParent().getObject(1).internalName, $ThisControl.getParent().getObject(1).bitmap );"; + groupNum = "0"; + text = ""; + }; + + %container.add(%previewButton); + %container.add(%previewBorder); + // add to the gui control array + MaterialSelector-->materialSelection.add(%container); + + // add to the array object for reference later + MatEdPreviewArray.add( %previewButton, %previewImage ); +} + +function MaterialSelector::loadImages( %this, %materialNum ) +{ + // this will save us from spinning our wheels in case we don't exist + if( !MaterialSelector.visible ) + return; + + // this schedule is here to dynamically load images + %previewButton = MatEdPreviewArray.getKey(%materialNum); + %previewImage = MatEdPreviewArray.getValue(%materialNum); + + %previewButton.setBitmap(%previewImage); + %previewButton.setText(""); + + %materialNum++; + + if( %materialNum < MatEdPreviewArray.count() ) + { + %tempSchedule = %this.schedule(64, "loadImages", %materialNum); + MatEdScheduleArray.add( %tempSchedule, %materialNum ); + } +} + +function MaterialSelector::clearMaterialFilters( %this ) +{ + for( %i = MaterialSelector.staticFilterObjects; %i < MaterialSelector-->filterArray.getCount(); %i++ ) + MaterialSelector-->filterArray.getObject(%i).getObject(0).setStateOn(0); + + MaterialSelector.loadFilter( "", "" ); +} + +function MaterialSelector::loadMaterialFilters( %this ) +{ + %filteredTypesArray = new ArrayObject(); + + %filteredTypesArray.duplicate( MaterialFilterAllArray ); + %filteredTypesArray.uniqueKey(); + + // sort the the keys before we do anything + %filteredTypesArray.sortkd(); + + eval( MaterialSelector.currentStaticFilter @ "Checkbox.setStateOn(1);" ); + // it may seem goofy why the checkbox can't be instanciated inside the container + // reason being its because we need to store the checkbox ctrl in order to make changes + // on it later in the function. + %selectedFilter = ""; + for( %i = 0; %i < %filteredTypesArray.count(); %i++ ) + { + %filter = %filteredTypesArray.getKey(%i); + if(%filter $= "") + continue; + + %container = new GuiControl(){ + profile = "GuiDefaultProfile"; + Position = "0 0"; + Extent = "128 18"; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + }; + + %checkbox = new GuiCheckBoxCtrl(){ + Profile = "GuiCheckBoxListProfile"; + position = "5 1"; + Extent = "118 18"; + Command = ""; + groupNum = "0"; + buttonType = "ToggleButton"; + text = %filter @ " ( " @ MaterialFilterAllArray.countKey(%filter) @ " )"; + filter = %filter; + Command = "MaterialSelector.preloadFilter();"; + }; + %container.add( %checkbox ); + MaterialSelector-->filterArray.add( %container ); + + %tagCount = getWordCount( MaterialSelector.currentFilter ); + for( %j = 0; %j < %tagCount; %j++ ) + { + if( %filter $= getWord( MaterialSelector.currentFilter, %j ) ) + { + if( %selectedFilter $= "" ) + %selectedFilter = %filter; + else + %selectedFilter = %selectedFilter @ " " @ %filter; + + %checkbox.setStateOn(1); + } + } + } + + MaterialSelector.loadFilter( %selectedFilter ); + + %filteredTypesArray.delete(); +} + +// create category and update current material if there is one +function MaterialSelector::createFilter( %this, %filter ) +{ + if( %filter $= %existingFilters ) + { + MessageBoxOK( "Error", "Can not create blank filter."); + return; + } + + for( %i = MaterialSelector.staticFilterObjects; %i < MaterialSelector-->filterArray.getCount() ; %i++ ) + { + %existingFilters = MaterialSelector-->filterArray.getObject(%i).getObject(0).filter; + if( %filter $= %existingFilters ) + { + MessageBoxOK( "Error", "Can not create two filters of the same name."); + return; + } + } + %container = new GuiControl(){ + profile = "GuiDefaultProfile"; + Position = "0 0"; + Extent = "128 18"; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + + new GuiCheckBoxCtrl(){ + Profile = "GuiCheckBoxListProfile"; + position = "5 1"; + Extent = "118 18"; + Command = ""; + groupNum = "0"; + buttonType = "ToggleButton"; + text = %filter @ " ( " @ MaterialFilterAllArray.countKey(%filter) @ " )"; + filter = %filter; + Command = "MaterialSelector.preloadFilter();"; + }; + }; + + MaterialSelector-->filterArray.add( %container ); + + // if selection exists, lets reselect it to refresh it + if( isObject(MaterialSelector.selectedMaterial) ) + MaterialSelector.updateSelection( MaterialSelector.selectedMaterial, MaterialSelector.selectedPreviewImagePath ); + + // material category text field to blank + MaterialSelector_addFilterWindow-->tagName.setText(""); +} + +function MaterialSelector::updateSelection( %this, %material, %previewImagePath ) +{ + // the material selector will visually update per material information + // after we move away from the material. eg: if we remove a field from the material, + // the empty checkbox will still be there until you move fro and to the material again + + %isMaterialBorder = 0; + eval("%isMaterialBorder = isObject(MaterialSelector-->"@%material@"Border);"); + if( %isMaterialBorder ) + { + eval( "MaterialSelector-->"@%material@"Border.setStateOn(1);"); + } + + %isMaterialBorderPrevious = 0; + eval("%isMaterialBorderPrevious = isObject(MaterialSelector-->"@$prevSelectedMaterialHL@"Border);"); + if( %isMaterialBorderPrevious ) + { + eval( "MaterialSelector-->"@$prevSelectedMaterialHL@"Border.setStateOn(0);"); + } + + MaterialSelector-->materialCategories.deleteAllObjects(); + MaterialSelector.selectedMaterial = %material; + MaterialSelector.selectedPreviewImagePath = %previewImagePath; + MaterialSelector-->previewSelectionText.setText( %material ); + MaterialSelector-->previewSelection.setBitmap( %previewImagePath ); + + // running through the existing list of categorynames in the left, so yes + // some might exist on the left only temporary if not given a home + for( %i = MaterialSelector.staticFilterObjects; %i < MaterialSelector-->filterArray.getCount() ; %i++ ) + { + %filter = MaterialSelector-->filterArray.getObject(%i).getObject(0).filter; + + %checkbox = new GuiCheckBoxCtrl(){ + materialName = %material.name; + Profile = "GuiCheckBoxListProfile"; + position = "5 2"; + Extent = "118 18"; + Command = "MaterialSelector.updateMaterialTags( $ThisControl.materialName, $ThisControl.getText(), $ThisControl.getValue() );"; + text = %filter; + }; + + MaterialSelector-->materialCategories.add( %checkbox ); + // crawl through material for categories in order to check or not + %filterFound = 0; + for( %j = 0; %material.getFieldValue("materialTag" @ %j) !$= ""; %j++ ) + { + %tag = %material.getFieldValue("materialTag" @ %j); + + if( %tag $= %filter ) + { + %filterFound = 1; + break; + } + } + + if( %filterFound ) + %checkbox.setStateOn(1); + else + %checkbox.setStateOn(0); + } + + $prevSelectedMaterialHL = %material; +} + +function MaterialSelector::updateMaterialTags( %this, %material, %tag, %tagValue ) +{ + if( %tagValue == 1 ) + { + MaterialFilterAllArray.add( %tag, %material ); + if( %material.mapTo $= "" || %material.mapTo $= "unmapped_mat" ) + %secondStaticFilter = MaterialFilterUnmappedArray; + else + %secondStaticFilter = MaterialFilterMappedArray; + + %secondStaticFilter.add( %tag, %material ); + + %createdTag = 0; + for( %i = 0; %createdTag == 0; %i++ ) + { + %materialTag = %material.getFieldValue("materialTag" @ %i); + if( %materialTag $= "" ) + { + eval( %material @ ".materialTag" @ %i @ "=" @ %tag @ ";" ); + %createdTag = 1; + + for( %j = MaterialSelector.staticFilterObjects; %j < MaterialSelector-->filterArray.getCount() ; %j++ ) + { + if( %tag $= MaterialSelector-->filterArray.getObject(%j).getObject(0).filter ) + { + %count = getWord( MaterialSelector-->filterArray.getObject(%j).getObject(0).getText(), 2 ); + %count++; + MaterialSelector-->filterArray.getObject(%j).getObject(0).setText( %tag @ " ( "@ %count @ " )"); + } + } + + break; + } + } + + } + else + { + // Remove the material from the "all" category + for( %i = 0; %i < MaterialFilterAllArray.count(); %i++ ) + { + if( MaterialFilterAllArray.getKey(%i) $= %tag ) + { + if( MaterialFilterAllArray.getValue(%i) $= %material ) + { + MaterialFilterAllArray.erase(%i); + break; + } + } + } + + // Figure out what the material's other category is + if( %material.mapTo $= "" || %material.mapTo $= "unmapped_mat" ) + %secondStaticFilter = MaterialFilterUnmappedArray; + else + %secondStaticFilter = MaterialFilterMappedArray; + + // Remove the material from its other category + for( %i = 0; %i < %secondStaticFilter.count(); %i++ ) + { + if( %secondStaticFilter.getKey(%i) $= %tag ) + { + if( %secondStaticFilter.getValue(%i) $= %material ) + { + %secondStaticFilter.erase( %i ); + break; + } + } + } + + + MaterialSelector.updateFilterCount( %tag, false ); + + %tagField = MaterialSelector.getTagField( %material, %tag ); + %lastTagField = MaterialSelector.getLastTagField( %material ); + %lastValidTagField = MaterialSelector.getLastValidTagField( %material, %tag ); + + if( %tagField $= %lastValidTagField || %lastValidTagField $= "" ) + { + MaterialSelectorPerMan.removeField( %material, %tagField ); + } + else + { + // Replace the current tagFieldValue with the last tagFieldValue + %lastValidTag = %material.getFieldValue( %lastValidTagField ); + %material.setFieldValue( %tagField, %lastValidTag ); + + // Remove the last tagFieldValue + MaterialSelectorPerMan.removeField( %material, %lastTagField ); + } + } + + // so were not going to save materials that dont current exist... + // technically all the data is stored in dynamic fields if the user feels like saving + // their auto-generated or new material + if( %material.getFilename() !$= "" && + %material.getFilename() !$= "tools/gui/MaterialSelector.ed.gui" && + %material.getFilename() !$= "tools/materialEditor/scripts/materialEditor.ed.cs" ) + { + MaterialSelectorPerMan.setDirty( %material ); + MaterialSelectorPerMan.saveDirty(); + MaterialSelectorPerMan.removeDirty( %material ); + + if(!%tagValue) + %material.setFieldValue( %lastTagField, "" ); + } +} + +function MaterialSelector::updateFilterCount( %this, %tag, %add ) +{ + for( %i = MaterialSelector.staticFilterObjects; %i < MaterialSelector-->filterArray.getCount() ; %i++ ) + { + if( %tag $= MaterialSelector-->filterArray.getObject(%i).getObject(0).filter ) + { + // Get the filter count and apply the operation + %idx = getWord( MaterialSelector-->filterArray.getObject(%i).getObject(0).getText(), 2 ); + + if( %add ) + %idx++; + else + %idx--; + + MaterialSelector-->filterArray.getObject(%i).getObject(0).setText( %tag @ " ( "@ %idx @ " )"); + } + } +} + +// this should create a new material pretty nicely +function MaterialSelector::createNewMaterial( %this ) +{ + // look for a newMaterial name to grab + %material = getUniqueName( "newMaterial" ); + + new Material(%material) + { + diffuseMap[0] = "core/art/warnMat"; + mapTo = "unmapped_mat"; + parentGroup = RootGroup; + }; + + // add one to All filter + MaterialFilterAllArray.add( "", %material.name ); + MaterialFilterAllArrayCheckbox.setText("All ( " @ MaterialFilterAllArray.count() + 1 @ " ) "); + + MaterialFilterUnmappedArray.add( "", %material.name ); + MaterialFilterUnmappedArrayCheckbox.setText("Unmapped ( " @ MaterialFilterUnmappedArray.count() + 1 @ " ) "); + + if( MaterialSelector.currentStaticFilter !$= "MaterialFilterMappedArray" ) + { + // create the new material gui + %container = new GuiControl(){ + profile = "GuiDefaultProfile"; + Position = "0 0"; + Extent = "74 85"; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + new GuiTextCtrl(){ + position = "10 70"; + profile = "GuiTextCenterProfile"; + extent = "64 16"; + text = %material.name; + }; + }; + + %previewButton = new GuiBitmapButtonCtrl(){ + internalName = %material.name; + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "GuiButtonProfile"; + position = "7 4"; + extent = "64 64"; + buttonType = "PushButton"; + bitmap = "core/art/warnMat"; + Command = ""; + text = "Loading..."; + useStates = false; + + new GuiBitmapButtonCtrl(){ + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "GuiButtonProfile"; + position = "0 0"; + extent = "64 64"; + Variable = ""; + buttonType = "toggleButton"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + groupNum = "0"; + text = ""; + }; + }; + + %previewBorder = new GuiButtonCtrl(){ + internalName = %material.name@"Border"; + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "GuiThumbHighlightButtonProfile"; + position = "3 0"; + extent = "72 88"; + Variable = ""; + buttonType = "toggleButton"; + tooltip = %material.name; + Command = "MaterialSelector.updateSelection( $ThisControl.getParent().getObject(1).internalName, $ThisControl.getParent().getObject(1).bitmap );"; + groupNum = "0"; + text = ""; + }; + + %container.add(%previewButton); + %container.add(%previewBorder); + // add to the gui control array + MaterialSelector-->materialSelection.add(%container); + } + + // select me + MaterialSelector.updateSelection( %material, "core/art/warnMat.png" ); +} + +//needs to be deleted with the persistence manager and needs to be blanked out of the matmanager +//also need to update instances... i guess which is the tricky part.... +function MaterialSelector::showDeleteDialog( %this ) +{ + %material = MaterialSelector.selectedMaterial; + %secondFilter = "MaterialFilterMappedArray"; + %secondFilterName = "Mapped"; + + for( %i = 0; %i < MaterialFilterUnmappedArray.count(); %i++ ) + { + if( MaterialFilterUnmappedArray.getValue(%i) $= %material ) + { + %secondFilter = "MaterialFilterUnmappedArray"; + %secondFilterName = "Unmapped"; + break; + } + } + + if( isObject( %material ) ) + { + MessageBoxYesNoCancel("Delete Material?", + "Are you sure you want to delete<br><br>" @ %material.getName() @ "<br><br> Material deletion won't take affect until the engine is quit.", + "MaterialSelector.deleteMaterial( " @ %material @ ", " @ %secondFilter @ ", " @ %secondFilterName @" );", + "", + "" ); + } +} + +function MaterialSelector::deleteMaterial( %this, %materialName, %secondFilter, %secondFilterName ) +{ + if( !isObject( %materialName ) ) + return; + + for( %i = 0; %i <= MaterialFilterAllArray.countValue( %materialName ); %i++) + { + %index = MaterialFilterAllArray.getIndexFromValue( %materialName ); + MaterialFilterAllArray.erase( %index ); + } + MaterialFilterAllArrayCheckbox.setText("All ( " @ MaterialFilterAllArray.count() - 1 @ " ) "); + + %checkbox = %secondFilter @ "Checkbox"; + for( %k = 0; %k <= %secondFilter.countValue( %materialName ); %k++) + { + %index = %secondFilter.getIndexFromValue( %materialName ); + %secondFilter.erase( %index ); + } + %checkbox.setText( %secondFilterName @ " ( " @ %secondFilter.count() - 1 @ " ) "); + + for( %i = 0; %materialName.getFieldValue("materialTag" @ %i) !$= ""; %i++ ) + { + %materialTag = %materialName.getFieldValue("materialTag" @ %i); + + for( %j = MaterialSelector.staticFilterObjects; %j < MaterialSelector-->filterArray.getCount() ; %j++ ) + { + if( %materialTag $= MaterialSelector-->filterArray.getObject(%j).getObject(0).filter ) + { + %count = getWord( MaterialSelector-->filterArray.getObject(%j).getObject(0).getText(), 2 ); + %count--; + MaterialSelector-->filterArray.getObject(%j).getObject(0).setText( %materialTag @ " ( "@ %count @ " )"); + } + } + + } + + UnlistedMaterials.add( "unlistedMaterials", %materialName ); + + if( %materialName.getFilename() !$= "" && + %materialName.getFilename() !$= "tools/gui/MaterialSelector.ed.gui" && + %materialName.getFilename() !$= "tools/materialEditor/scripts/materialEditor.ed.cs" ) + { + MaterialSelectorPerMan.removeObjectFromFile(%materialName); + MaterialSelectorPerMan.saveDirty(); + } + + MaterialSelector.preloadFilter(); + //MaterialSelector.selectMaterial( "WarningMaterial" ); +} + +function MaterialSelector::switchStaticFilters( %this, %staticFilter) +{ + switch$(%staticFilter) + { + case "MaterialFilterAllArray": + MaterialFilterAllArrayCheckbox.setStateOn(1); + + MaterialFilterMappedArrayCheckbox.setStateOn(0); + MaterialFilterUnmappedArrayCheckbox.setStateOn(0); + case "MaterialFilterMappedArray": + MaterialFilterMappedArrayCheckbox.setStateOn(1); + + MaterialFilterAllArrayCheckbox.setStateOn(0); + MaterialFilterUnmappedArrayCheckbox.setStateOn(0); + case "MaterialFilterUnmappedArray": + MaterialFilterUnmappedArrayCheckbox.setStateOn(1); + + MaterialFilterAllArrayCheckbox.setStateOn(0); + MaterialFilterMappedArrayCheckbox.setStateOn(0); + } + + // kinda goofy were passing a class variable... we can't do an empty check right now + // on load filter because we actually pass "" as a filter... + MaterialSelector.loadFilter( MaterialSelector.currentFilter, %staticFilter ); +} + +// Tagging Functionality + +function MaterialSelector::getTagField( %this, %material, %tag ) +{ + for( %i = 0; %material.getFieldValue("materialTag" @ %i) !$= ""; %i++ ) + { + %loopTag = %material.getFieldValue("materialTag" @ %i); + if( %tag $= %loopTag ) + { + %tagField = "materialTag" @ %i; + break; + } + } + + return %tagField; +} + +function MaterialSelector::getLastTagField( %this, %material ) +{ + for( %i = 0; %material.getFieldValue("materialTag" @ %i) !$= ""; %i++ ) + { + %tagField = "materialTag" @ %i; + } + + return %tagField; +} + +function MaterialSelector::getLastValidTagField( %this, %material, %invalidTag ) +{ + for( %i = 0; %material.getFieldValue("materialTag" @ %i) !$= ""; %i++ ) + { + %tag = %material.getFieldValue("materialTag" @ %i); + // Can't equal our invalid tag + if( %tag $= %invalidTag ) + continue; + + // Set our last found tag + %tagField = "materialTag" @ %i; + } + + return %tagField; +} + +// Preview Page Navigation + +function MaterialSelector::firstPage(%this) +{ + MaterialSelector.currentPreviewPage = 0; + MaterialSelector.LoadFilter( MaterialSelector.currentFilter, MaterialSelector.currentStaticFilter ); +} + +function MaterialSelector::previousPage(%this) +{ + MaterialSelector.currentPreviewPage--; + if( MaterialSelector.currentPreviewPage < 0) + MaterialSelector.currentPreviewPage = 0; + + MaterialSelector.LoadFilter( MaterialSelector.currentFilter, MaterialSelector.currentStaticFilter ); +} + +function MaterialSelector::nextPage(%this) +{ + MaterialSelector.currentPreviewPage++; + if( MaterialSelector.currentPreviewPage >= MaterialSelector.totalPages) + MaterialSelector.currentPreviewPage = MaterialSelector.totalPages - 1; + if( MaterialSelector.currentPreviewPage < 0) + MaterialSelector.currentPreviewPage = 0; + + MaterialSelector.LoadFilter( MaterialSelector.currentFilter, MaterialSelector.currentStaticFilter ); +} + +function MaterialSelector::lastPage(%this) +{ + MaterialSelector.currentPreviewPage = MaterialSelector.totalPages - 1; + if( MaterialSelector.currentPreviewPage < 0) + MaterialSelector.currentPreviewPage = 0; + + MaterialSelector.LoadFilter( MaterialSelector.currentFilter, MaterialSelector.currentStaticFilter ); +} + +function MaterialSelector::selectPage(%this, %page) +{ + MaterialSelector.currentPreviewPage = %page; + MaterialSelector.LoadFilter( MaterialSelector.currentFilter, MaterialSelector.currentStaticFilter ); +} + +function MaterialSelector::thumbnailCountUpdate(%this) +{ + $Pref::MaterialSelector::ThumbnailCountIndex = MaterialSelector-->materialPreviewCountPopup.getSelected(); + MaterialSelector.LoadFilter( MaterialSelector.currentFilter, MaterialSelector.currentStaticFilter ); +} + +function MaterialSelector::buildPagesButtons(%this, %currentPage, %totalPages) +{ + // We don't want any more than 8 pages at a time. + if( %totalPages > 8 ) + { + // We attempt to display up to 2 pages before the current page + %start = %currentPage - 2; + if( %start <= 0 ) + { + %start = 0; + %startbracket = false; + } + else + { + %startbracket = true; + } + + if( (%totalPages - %start) < 8 ) + { + // Move %start closer to the beginning to maintain 8 pages + %start = %totalPages - 8; + } + + %end = %start + 8; + if( %end >= %totalPages ) + { + %end = %totalPages; + %endbracket = false; + } + else + { + %endbracket = true; + } + } + else + { + %start = 0; + %end = %totalPages; + %startbracket = false; + %endbracket = false; + } + + if( %startbracket ) + { + %control = new GuiTextCtrl(){ + profile = "GuiTextCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 2"; + extent = "14 16"; + MinExtent = "8 8"; + text = "..."; + }; + MaterialSelector-->materialPreviewPagesStack.add( %control ); + } + + for( %i = %start; %i < %end; %i++ ) + { + if( %i != %currentPage ) + { + %control = new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "14 16"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "MaterialSelector.schedule(0, selectPage, " @ %i @ ");"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = %i+1; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + }; + } + else + { + %control = new GuiTextCtrl(){ + profile = "GuiTextBoldCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 2"; + extent = "14 16"; + MinExtent = "8 8"; + text = %i+1; + }; + } + + MaterialSelector-->materialPreviewPagesStack.add( %control ); + } + + if( %endbracket ) + { + %control = new GuiTextCtrl(){ + profile = "GuiTextCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 2"; + extent = "14 16"; + MinExtent = "8 8"; + text = "..."; + }; + MaterialSelector-->materialPreviewPagesStack.add( %control ); + } +} diff --git a/Templates/Empty/game/tools/gui/messageBoxOKBuy.ed.gui b/Templates/Empty/game/tools/gui/messageBoxOKBuy.ed.gui new file mode 100644 index 000000000..0fb0eb982 --- /dev/null +++ b/Templates/Empty/game/tools/gui/messageBoxOKBuy.ed.gui @@ -0,0 +1,85 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(MessageBoxOKBuyDlg) { + profile = "GuiDefaultProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new GuiWindowCtrl(MBOKBuyFrame) { + profile = "GuiWindowProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "170 175"; + extent = "300 100"; + minExtent = "48 92"; + visible = "1"; + helpTag = "0"; + maxLength = "255"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + text = ""; + closeCommand = "MessageCallback(MessageBoxOKBuyDlg,MessageBoxOKBuyDlg.noCallback);"; + + new GuiMLTextCtrl(MBOKBuyText) { + profile = "GuiMLTextProfile"; + horizSizing = "center"; + vertSizing = "bottom"; + position = "11 38"; + extent = "280 14"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "70 68"; + extent = "80 22"; + minExtent = "8 8"; + visible = "1"; + command = "MessageCallback(MessageBoxOKBuyDlg,MessageBoxOKBuyDlg.OKCallback);"; + accelerator = "return"; + helpTag = "0"; + text = "OK"; + simpleStyle = "0"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "167 68"; + extent = "80 22"; + minExtent = "8 8"; + visible = "1"; + command = "MessageCallback(MessageBoxOKBuyDlg,MessageBoxOKBuyDlg.BuyCallback);"; + accelerator = "escape"; + helpTag = "0"; + text = "Buy Now!"; + simpleStyle = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + +function MessageBoxOKBuy(%title, %message, %OKCallback, %BuyCallback) +{ + MBOKBuyFrame.text = %title; + MessageBoxOKBuyDlg.profile = "GuiOverlayProfile"; + Canvas.pushDialog(MessageBoxOKBuyDlg); + MBSetText(MBOKBuyText, MBOKBuyFrame, %message); + MessageBoxOKBuyDlg.OKCallback = %OKCallback; + MessageBoxOKBuyDlg.BuyCallback = %BuyCallback; +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/gui/objectSelection.ed.cs b/Templates/Empty/game/tools/gui/objectSelection.ed.cs new file mode 100644 index 000000000..43e361168 --- /dev/null +++ b/Templates/Empty/game/tools/gui/objectSelection.ed.cs @@ -0,0 +1,368 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Common code for object selection dialogs. + + +//============================================================================================= +// Initialization. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function EObjectSelection::init( %this ) +{ + // Initialize the class list. + + %classList = %this-->classList; + if( isObject( %classList ) ) + %this.initClassList(); + + // Initialize the filter list. + + %filterList = %this-->filterList; + if( isObject( %filterList ) ) + %this.initFilterList(); + + // Initialize the group list. + + %groupList = %this-->groupList; + if( isObject( %groupList ) ) + %this.initGroupList(); +} + +//--------------------------------------------------------------------------------------------- + +function EObjectSelection::cleanup( %this ) +{ + // Clear the class list. + + %classList = %this-->classList; + if( isObject( %classList ) ) + %classList.clear(); + + // Clear the filter list. + + %filterList = %this-->filterList; + if( isObject( %filterList ) ) + %filterList.clear(); + + // Clear the group list. + + %groupList = %this-->groupList; + if( isObject( %groupList ) ) + %groupList.clear(); + + // Delete the class array. + + if( isObject( %this.classArray ) ) + %this.classArray.delete(); +} + +//============================================================================================= +// Methods to override in a subclass. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +/// Return the group object where onSelectObjects should begin searching for objects. +function EObjectSelection::getRootGroup( %this ) +{ + return RootGroup; +} + +//--------------------------------------------------------------------------------------------- + +/// Return a set that contains all filter objects to include in the filter list. +/// Returning 0 will leave the filter list empty. +function EObjectSelection::getFilterSet( %this ) +{ + return 0; +} + +//--------------------------------------------------------------------------------------------- + +/// Return true if the given class should be included in the class list. +function EObjectSelection::includeClass( %this, %className ) +{ + return true; +} + +//--------------------------------------------------------------------------------------------- + +/// The object has met the given criteria. Select or deselect it depending on %val. +function EObjectSelection::selectObject( %this, %object, %val ) +{ +} + +//============================================================================================= +// Events. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function EObjectSelection::onSelectObjects( %this, %val ) +{ + // Get the root group to search in. + + %groupList = %this-->groupList; + if( !isObject( %groupList ) ) + %root = %this.getRootGroup(); + else + %root = %groupList.getSelected(); + + if( !isObject( %root ) ) + return; + + // Fetch the object name pattern. + + %namePatternField = %this-->namePattern; + if( isObject( %namePatternField ) ) + %this.namePattern = %namePatternField.getText(); + else + %this.namePattern = ""; + + // Clear current selection first, if need be. + + if( %val ) + { + %retainSelectionBox = %this-->retainSelection; + if( isObject( %retainSelectionBox ) && !%retainSelectionBox.isStateOn() ) + %this.clearSelection(); + } + + // (De)Select all matching objects in it. + + %this.selectObjectsIn( %root, %val, true ); +} + +//============================================================================================= +// Selection. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function EObjectSelection::selectObjectsIn( %this, %group, %val, %excludeGroup ) +{ + // Match to the group itself. + + if( !%excludeGroup && %this.objectMatchesCriteria( %group ) ) + %this.selectObject( %group, %val ); + + // Recursively match all children. + + foreach( %obj in %group ) + { + if( %obj.isMemberOfClass( "SimSet" ) ) + %this.selectObjectsIn( %obj, %val ); + else if( %this.objectMatchesCriteria( %obj ) ) + %this.selectObject( %obj, %val ); + } +} + +//--------------------------------------------------------------------------------------------- + +function EObjectSelection::objectMatchesCriteria( %this, %object ) +{ + // Check name. + + if( %this.namePattern !$= "" && !strIsMatchExpr( %this.namePattern, %object.getName() ) ) + return false; + + // Check class. + + if( !%this.isClassEnabled( %object.getClassName() ) ) + return false; + + return true; +} + +//============================================================================================= +// Groups. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function EObjectSelection::initGroupList( %this ) +{ + %groupList = %this-->groupList; + + %selected = 0; + if( %groupList.size() > 0 ) + %selected = %groupList.getSelected(); + + %groupList.clear(); + + %root = %this.getRootGroup(); + if( !isObject( %root ) ) + return; + + // Add all non-empty groups. + + %this.scanGroup( %root, %groupList, 0 ); + + // Select initial group. + + if( %selected != 0 && isObject( %selected ) ) + %groupList.setSelected( %selected ); + else + %groupList.setSelected( %root.getId() ); +} + +//--------------------------------------------------------------------------------------------- + +function EObjectSelection::scanGroup( %this, %group, %list, %indentLevel ) +{ + // Create a display name for the group. + + %text = %group.getName(); + if( %text $= "" ) + %text = %group.getClassName(); + + %internalName = %group.getInternalName(); + if( %internalName !$= "" ) + %text = %text @ " [" @ %internalName @ "]"; + + // Indent the name according to the depth in the hierarchy. + + if( %indentLevel > 0 ) + %text = strrepeat( " ", %indentLevel ) @ %text; + + // Add it to the list. + + %list.add( %text, %group.getId() ); + + // Recurse into SimSets with at least one child. + + foreach ( %obj in %group ) + { + if( !%obj.isMemberOfClass( "SimSet" ) + || %obj.getCount() == 0 ) + continue; + + %this.scanGroup( %obj, %list, %indentLevel + 1 ); + } +} + +//============================================================================================= +// Filters. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function EObjectSelection::initFilterList( %this ) +{ + %filterList = %this-->filterList; +} + +//============================================================================================= +// Classes. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +/// Initialize the list of class toggles. +function EObjectSelection::initClassList( %this ) +{ + %classArray = new ArrayObject(); + %this.classArray = %classArray; + + // Add all classes to the array. + + %classes = enumerateConsoleClasses(); + foreach$( %className in %classes ) + { + if( !%this.includeClass( %className ) ) + continue; + + %classArray.push_back( %className, true ); + } + + // Sort the class list. + + %classArray.sortk( true ); + + // Add checkboxes for all classes to the list. + + %classList = %this-->classList; + %count = %classArray.count(); + for( %i = 0; %i < %count; %i ++ ) + { + %className = %classArray.getKey( %i ); + %textLength = strlen( %className ); + %text = " " @ %className; + + %checkBox = new GuiCheckBoxCtrl() + { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiCheckBoxListFlipedProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = ( %textLength * 4 ) @ " 18"; + MinExtent = "8 2"; + canSave = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Include/exclude all " @ %className @ " objects."; + text = %text; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + command = %classArray @ ".setValue( $ThisControl.getValue(), " @ %i @ " );"; + }; + + %checkBox.setStateOn( true ); + %classList.addGuiControl( %checkBox ); + } +} + +//--------------------------------------------------------------------------------------------- + +function EObjectSelection::selectAllInClassList( %this, %state ) +{ + %classList = %this-->classList; + + foreach( %ctrl in %classList ) + { + if( %ctrl.getValue() == %state ) + %ctrl.performClick(); + } +} + +//--------------------------------------------------------------------------------------------- + +function EObjectSelection::isClassEnabled( %this, %className ) +{ + // Look up the class entry in the array. + + %index = %this.classArray.getIndexFromKey( %className ); + if( %index == -1 ) + return false; + + // Return the flag. + + return %this.classArray.getValue( %index ); +} diff --git a/Templates/Empty/game/tools/gui/openFileDialog.ed.cs b/Templates/Empty/game/tools/gui/openFileDialog.ed.cs new file mode 100644 index 000000000..00a388789 --- /dev/null +++ b/Templates/Empty/game/tools/gui/openFileDialog.ed.cs @@ -0,0 +1,44 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function getLoadFilename(%filespec, %callback, %currentFile) +{ + %dlg = new OpenFileDialog() + { + Filters = %filespec; + DefaultFile = %currentFile; + ChangePath = false; + MustExist = true; + MultipleFiles = false; + }; + + if ( filePath( %currentFile ) !$= "" ) + %dlg.DefaultPath = filePath(%currentFile); + + if ( %dlg.Execute() ) + { + eval(%callback @ "(\"" @ %dlg.FileName @ "\");"); + $Tools::FileDialogs::LastFilePath = filePath( %dlg.FileName ); + } + + %dlg.delete(); +} diff --git a/Templates/Empty/game/tools/gui/profiles.ed.cs b/Templates/Empty/game/tools/gui/profiles.ed.cs new file mode 100644 index 000000000..cbf704d97 --- /dev/null +++ b/Templates/Empty/game/tools/gui/profiles.ed.cs @@ -0,0 +1,454 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function execEditorProfilesCS() +{ + exec("./profiles.ed.cs"); +} + +$Gui::clipboardFile = expandFilename("./clipboard.gui"); + +singleton GuiControlProfile( GuiEditorClassProfile ) +{ + opaque = true; + fillColor = "232 232 232"; + border = 1; + borderColor = "40 40 40 140"; + borderColorHL = "127 127 127"; + fontColor = "0 0 0"; + fontColorHL = "50 50 50"; + fixedExtent = true; + justify = "center"; + bitmap = "core/art/gui/images/scrollBar"; + hasBitmapArray = true; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiBackFillProfile ) +{ + opaque = true; + fillColor = "0 94 94"; + border = true; + borderColor = "255 128 128"; + fontType = "Arial"; + fontSize = 12; + fontColor = "0 0 0"; + fontColorHL = "50 50 50"; + fixedExtent = true; + justify = "center"; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiControlListPopupProfile ) +{ + opaque = true; + fillColor = "255 255 255"; + fillColorHL = "204 203 202"; + border = false; + //borderColor = "0 0 0"; + fontColor = "0 0 0"; + fontColorHL = "0 0 0"; + fontColorNA = "50 50 50"; + textOffset = "0 2"; + autoSizeWidth = false; + autoSizeHeight = true; + tab = true; + canKeyFocus = true; + bitmap = "core/art/gui/images/scrollBar"; + hasBitmapArray = true; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiSceneGraphEditProfile ) +{ + canKeyFocus = true; + tab = true; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorButtonProfile : GuiButtonProfile ) +{ + //border = 1; + justify = "Center"; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorSwatchButtonProfile ) +{ + borderColor = "100 100 100 255"; + borderColorNA = "200 200 200 255"; + fillColorNA = "255 255 255 0"; + borderColorHL = "0 0 0 255"; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorTextEditProfile ) +{ + // Transparent Background + opaque = true; + fillColor = "0 0 0 0"; + fillColorHL = "255 255 255"; + + // No Border (Rendered by field control) + border = false; + + tab = true; + canKeyFocus = true; + + // font + fontType = "Arial"; + fontSize = 14; + + fontColor = "0 0 0"; + fontColorSEL = "43 107 206"; + fontColorHL = "244 244 244"; + fontColorNA = "100 100 100"; + category = "Editor"; +}; +singleton GuiControlProfile( GuiDropdownTextEditProfile : GuiTextEditProfile ) +{ + bitmap = "core/art/gui/images/dropdown-textEdit"; + category = "Editor"; +}; +singleton GuiControlProfile( GuiInspectorTextEditRightProfile : GuiInspectorTextEditProfile ) +{ + justify = "right"; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorGroupProfile ) +{ + fontType = "Arial"; + fontSize = "14"; + + fontColor = "0 0 0 150"; + fontColorHL = "25 25 25 220"; + fontColorNA = "128 128 128"; + + justify = "left"; + opaque = false; + border = false; + + bitmap = "tools/editorclasses/gui/images/rollout"; + + textOffset = "20 0"; + + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorFieldProfile) +{ + // fill color + opaque = false; + fillColor = "255 255 255"; + fillColorHL = "204 203 202"; + fillColorNA = "244 244 244"; + + // border color + border = false; + borderColor = "190 190 190"; + borderColorHL = "156 156 156"; + borderColorNA = "200 200 200"; + + //bevelColorHL = "255 255 255"; + //bevelColorLL = "0 0 0"; + + // font + fontType = "Arial"; + fontSize = 14; + + fontColor = "32 32 32"; + fontColorHL = "50 50 50"; + fontColorNA = "190 190 190"; + textOffset = "10 0"; + + tab = true; + canKeyFocus = true; + category = "Editor"; +}; + +/* +singleton GuiControlProfile( GuiInspectorMultiFieldProfile : GuiInspectorFieldProfile ) +{ + opaque = true; + fillColor = "50 50 230 30"; +}; +*/ + +singleton GuiControlProfile( GuiInspectorMultiFieldDifferentProfile : GuiInspectorFieldProfile ) +{ + border = true; + borderColor = "190 100 100"; +}; + +singleton GuiControlProfile( GuiInspectorDynamicFieldProfile : GuiInspectorFieldProfile ) +{ + // Transparent Background + opaque = true; + fillColor = "0 0 0 0"; + fillColorHL = "255 255 255"; + + // No Border (Rendered by field control) + border = false; + + tab = true; + canKeyFocus = true; + + // font + fontType = "Arial"; + fontSize = 14; + + fontColor = "0 0 0"; + fontColorSEL = "43 107 206"; + fontColorHL = "244 244 244"; + fontColorNA = "100 100 100"; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiRolloutProfile ) +{ + border = 1; + borderColor = "200 200 200"; + + hasBitmapArray = true; + bitmap = "tools/editorClasses/gui/images/rollout"; + + textoffset = "17 0"; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorRolloutProfile0 ) +{ + // font + fontType = "Arial"; + fontSize = 14; + + fontColor = "32 32 32"; + fontColorHL = "32 100 100"; + fontColorNA = "0 0 0"; + + justify = "left"; + opaque = false; + + border = 0; + borderColor = "190 190 190"; + borderColorHL = "156 156 156"; + borderColorNA = "64 64 64"; + + bitmap = "tools/editorclasses/gui/images/rollout_plusminus_header"; + + textOffset = "20 0"; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorStackProfile ) +{ + opaque = false; + border = false; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorProfile : GuiInspectorFieldProfile ) +{ + opaque = true; + fillColor = "255 255 255 255"; + border = 0; + cankeyfocus = true; + tab = true; + category = "Editor"; +}; +singleton GuiControlProfile( GuiInspectorInfoProfile : GuiInspectorFieldProfile ) +{ + opaque = true; + fillColor = "242 241 240"; + border = 0; + cankeyfocus = true; + tab = true; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorBackgroundProfile : GuiInspectorFieldProfile ) +{ + border = 0; + cankeyfocus=true; + tab = true; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorTypeFileNameProfile ) +{ + // Transparent Background + opaque = false; + + // No Border (Rendered by field control) + border = 0; + + tab = true; + canKeyFocus = true; + + // font + fontType = "Arial"; + fontSize = 14; + + // Center text + justify = "center"; + + fontColor = "32 32 32"; + fontColorHL = "50 50 50"; + fontColorNA = "0 0 0"; + + fillColor = "255 255 255"; + fillColorHL = "204 203 202"; + fillColorNA = "244 244 244"; + + borderColor = "190 190 190"; + borderColorHL = "156 156 156"; + borderColorNA = "64 64 64"; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorColumnCtrlProfile : GuiInspectorFieldProfile ) +{ + opaque = true; + fillColor = "210 210 210"; + border = 0; + category = "Editor"; +}; + +singleton GuiControlProfile( InspectorTypeEnumProfile : GuiInspectorFieldProfile ) +{ + mouseOverSelected = true; + bitmap = "core/art/gui/images/scrollBar"; + hasBitmapArray = true; + opaque=true; + border=true; + textOffset = "4 0"; + category = "Editor"; +}; + +singleton GuiControlProfile( InspectorTypeCheckboxProfile : GuiInspectorFieldProfile ) +{ + bitmap = "core/art/gui/images/checkBox"; + hasBitmapArray = true; + opaque=false; + border=false; + textOffset = "4 0"; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiToolboxButtonProfile : GuiButtonProfile ) +{ + justify = "center"; + fontColor = "0 0 0"; + border = 0; + textOffset = "0 0"; + category = "Editor"; +}; + +singleton GuiControlProfile( T2DDatablockDropDownProfile : GuiPopUpMenuProfile ) +{ + category = "Editor"; +}; + +singleton GuiControlProfile( GuiDirectoryTreeProfile : GuiTreeViewProfile ) +{ + fontColor = "40 40 40"; + fontColorSEL= "250 250 250 175"; + fillColorHL = "0 60 150"; + fontColorNA = "240 240 240"; + fontType = "Arial"; + fontSize = 14; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiDirectoryFileListProfile ) +{ + fontColor = "40 40 40"; + fontColorSEL= "250 250 250 175"; + fillColorHL = "0 60 150"; + fontColorNA = "240 240 240"; + fontType = "Arial"; + fontSize = 14; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiDragAndDropProfile ) +{ + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorFieldInfoPaneProfile ) +{ + opaque = false; + fillcolor = GuiInspectorBackgroundProfile.fillColor; + borderColor = GuiDefaultProfile.borderColor; + border = 1; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorFieldInfoMLTextProfile : GuiMLTextProfile ) +{ + opaque = false; + border = 0; + textOffset = "5 0"; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiEditorScrollProfile ) +{ + opaque = true; + fillcolor = GuiInspectorBackgroundProfile.fillColor; + borderColor = GuiDefaultProfile.borderColor; + border = 1; + bitmap = "core/art/gui/images/scrollBar"; + hasBitmapArray = true; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiCreatorIconButtonProfile ) +{ + opaque = true; + fillColor = "225 243 252 255"; + fillColorHL = "225 243 252 0"; + fillColorNA = "225 243 252 0"; + fillColorSEL = "225 243 252 0"; + + //tab = true; + //canKeyFocus = true; + + fontType = "Arial"; + fontSize = 14; + + fontColor = "0 0 0"; + fontColorSEL = "43 107 206"; + fontColorHL = "244 244 244"; + fontColorNA = "100 100 100"; + + border = 1; + borderColor = "153 222 253 255"; + borderColorHL = "156 156 156"; + borderColorNA = "153 222 253 0"; + + //bevelColorHL = "255 255 255"; + //bevelColorLL = "0 0 0"; + category = "Editor"; +}; diff --git a/Templates/Empty/game/tools/gui/saveChangesMBDlg.ed.gui b/Templates/Empty/game/tools/gui/saveChangesMBDlg.ed.gui new file mode 100644 index 000000000..b578b7f02 --- /dev/null +++ b/Templates/Empty/game/tools/gui/saveChangesMBDlg.ed.gui @@ -0,0 +1,180 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(MessageBoxSaveChangesDlg, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl(MBSaveChangesFrame) { + canSaveDynamicFields = "0"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "362 274"; + Extent = "340 164"; + MinExtent = "48 92"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Save Changes"; + maxLength = "255"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + + new GuiIconButtonCtrl(mbSaveDlgSaveButton) { + canSaveDynamicFields = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "240 117"; + Extent = "83 25"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Save"; + groupNum = "-1"; + buttonType = "PushButton"; + iconBitmap = "~/levelEditor/gui/images/iconAccept.png"; + sizeIconToButton = "0"; + textLocation = "Center"; + textMargin = "4"; + buttonMargin = "4 4"; + }; + new GuiIconButtonCtrl(mbSaveDlgCancelButton) { + canSaveDynamicFields = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "158 117"; + Extent = "83 25"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + iconBitmap = "~/levelEditor/gui/images/iconCancel.png"; + sizeIconToButton = "0"; + textLocation = "Center"; + textMargin = "4"; + buttonMargin = "4 4"; + }; + new GuiIconButtonCtrl(mbSaveDlgDontButton) { + canSaveDynamicFields = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "14 117"; + Extent = "124 25"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Don\'t Save"; + groupNum = "-1"; + buttonType = "PushButton"; + sizeIconToButton = "0"; + textLocation = "Center"; + textMargin = "4"; + buttonMargin = "4 4"; + }; + new GuiControl() { + canSaveDynamicFields = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "13 31"; + Extent = "310 73"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Profile = "EditorTextHLBoldLeft"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "15 9"; + Extent = "281 26"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Do you want to save changes to this document?"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "15 38"; + Extent = "258 21"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "If you don\'t save, your changes may be lost."; + maxLength = "1024"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- + +function MessageBoxSaveChangesDlg::onWake( %this ) +{ + MBSaveChangesFrame.setText( %this.Data ); +} + +function mbSaveDlgSaveButton::onClick( %this ) +{ + if( MessageBoxSaveChangesDlg.SaveCallback !$= "" ) + eval( MessageBoxSaveChangesDlg.SaveCallback @ "(" @ MessageBoxSaveChangesDlg.Data @ ");" ); + Canvas.popDialog( MessageBoxSaveChangesDlg ); +} + +function mbSaveDlgCancelButton::onClick( %this ) +{ + Canvas.popDialog( MessageBoxSaveChangesDlg ); +} + +function mbSaveDlgDontButton::onClick( %this ) +{ + if( MessageBoxSaveChangesDlg.DontSaveCallback !$= "" ) + eval( MessageBoxSaveChangesDlg.DontSaveCallback @ "(" @ MessageBoxSaveChangesDlg.Data @ ");" ); + Canvas.popDialog( MessageBoxSaveChangesDlg ); +} + +// Deprecated when platform layers are all sufficient +function checkSaveChangesOld( %data, %saveCallback, %dontSaveCallback ) +{ + // Sanity Check + if( MessageBoxSaveChangesDlg.isAwake() ) + { + warn("Save Changes Dialog already Awake, NOT creating second instance."); + return; + } + + // Set Proper State + MessageBoxSaveChangesDlg.SaveCallback = %saveCallback; + MessageBoxSaveChangesDlg.DontSaveCallback = %dontSaveCallback; + MessageBoxSaveChangesDlg.Data = %data; + + // Show Dialog + Canvas.pushDialog( MessageBoxSaveChangesDlg ); +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/gui/saveFileDialog.ed.cs b/Templates/Empty/game/tools/gui/saveFileDialog.ed.cs new file mode 100644 index 000000000..8756c2eab --- /dev/null +++ b/Templates/Empty/game/tools/gui/saveFileDialog.ed.cs @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function getSaveFilename( %filespec, %callback, %currentFile, %overwrite ) +{ + if( %overwrite $= "" ) + %overwrite = true; + + %dlg = new SaveFileDialog() + { + Filters = %filespec; + DefaultFile = %currentFile; + ChangePath = false; + OverwritePrompt = %overwrite; + }; + + if( filePath( %currentFile ) !$= "" ) + %dlg.DefaultPath = filePath( %currentFile ); + else + %dlg.DefaultPath = getMainDotCSDir(); + + if( %dlg.Execute() ) + { + %filename = %dlg.FileName; + eval( %callback @ "(\"" @ %filename @ "\");" ); + } + + %dlg.delete(); +} diff --git a/Templates/Empty/game/tools/gui/scriptEditorDlg.ed.gui b/Templates/Empty/game/tools/gui/scriptEditorDlg.ed.gui new file mode 100644 index 000000000..29f925915 --- /dev/null +++ b/Templates/Empty/game/tools/gui/scriptEditorDlg.ed.gui @@ -0,0 +1,210 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ScriptEditorDlg,EditorGuiGroup) { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiWindowCtrl() { + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "1"; + canMaximize = "1"; + minSize = "50 50"; + closeCommand = "ScriptEditorDlg.close();"; + EdgeSnap = "1"; + text = "Text Pad"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "176 120"; + Extent = "656 464"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ScriptEditorDlg.close();"; + Accelerator = "escape"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiControl() { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "8 24"; + Extent = "640 392"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiControl() { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "8 7"; + Extent = "627 380"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "0"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "1 1"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "627 380"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiMLTextEditCtrl() { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + isContainer = "0"; + Profile = "GuiTextPadProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "2 2"; + Extent = "623 380"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "TextPad"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; + new GuiIconButtonCtrl() { + buttonMargin = "4 4"; + iconBitmap = "tools/gui/images/iconCancel.png"; + iconLocation = "Left"; + sizeIconToButton = "0"; + makeIconSquare = "0"; + textLocation = "Center"; + textMargin = "4"; + autoSize = "0"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + position = "460 424"; + Extent = "80 25"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ScriptEditorDlg.close();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiIconButtonCtrl() { + buttonMargin = "4 4"; + iconBitmap = "tools/gui/images/iconAccept.png"; + iconLocation = "Left"; + sizeIconToButton = "0"; + makeIconSquare = "0"; + textLocation = "Center"; + textMargin = "4"; + autoSize = "0"; + text = "Ok"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + position = "560 424"; + Extent = "80 25"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "_TextPadOnOk();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + +function TextPad(%text, %callback, %root) +{ + ScriptEditorDlg-->textpad.setText(%text); + ScriptEditorDlg.callback = %callback; + + if(!isObject(%root)) + %root = Canvas; + + %root.pushDialog(ScriptEditorDlg); +} + +function _TextPadOnOk() +{ + if(ScriptEditorDlg.callback !$= "") + { + %text = ScriptEditorDlg-->textpad.getText(); + %command = ScriptEditorDlg.callback @ "( %text );"; + eval(%command); + } + ScriptEditorDlg.callback = ""; + ScriptEditorDlg.getRoot().popDialog(ScriptEditorDlg); +} + +function ScriptEditorDlg::close(%this) +{ + %this.getRoot().popDialog(%this); +} diff --git a/Templates/Empty/game/tools/gui/simViewDlg.ed.gui b/Templates/Empty/game/tools/gui/simViewDlg.ed.gui new file mode 100644 index 000000000..69440d194 --- /dev/null +++ b/Templates/Empty/game/tools/gui/simViewDlg.ed.gui @@ -0,0 +1,348 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(simViewDlg, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl() { + canSaveDynamicFields = "0"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "70 43"; + Extent = "685 489"; + MinExtent = "602 440"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Torque SimView"; + maxLength = "1024"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "1"; + canMaximize = "1"; + minSize = "50 50"; + closeCommand = "Canvas.popDialog(simViewDlg);"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "10 28"; + Extent = "255 448"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "alwaysOn"; + lockHorizScroll = "false"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiTreeViewCtrl(InspectTreeView) { + canSaveDynamicFields = "0"; + Profile = "GuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "2 2"; + Extent = "212 21"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "1"; + MultipleSelections = "1"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "1"; + }; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Profile = "GuiScrollProfile"; + HorizSizing = "left"; + VertSizing = "height"; + position = "272 96"; + Extent = "404 380"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "alwaysOn"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiInspector(InspectFields) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + canSaveDynamicFields = "0"; + Profile = "GuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "2 2"; + Extent = "382 8"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + }; + }; + new GuiControl() { + canSaveDynamicFields = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "272 28"; + Extent = "403 61"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextEditCtrl(InspectObjectName) { + canSaveDynamicFields = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "121 8"; + Extent = "195 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Profile = "EditorTextHLRight"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "217 35"; + Extent = "44 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Sim ID:"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Profile = "EditorTextHLRight"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 35"; + Extent = "106 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Internal Name:"; + maxLength = "1024"; + }; + new GuiTextEditCtrl(InspectObjectInternalName) { + canSaveDynamicFields = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "121 35"; + Extent = "93 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Profile = "EditorTextHLBoldRight"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 8"; + Extent = "106 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Selected Object:"; + maxLength = "1024"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "321 33"; + Extent = "76 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "InspectApply();"; + hovertime = "1000"; + text = "Refresh"; + groupNum = "-1"; + buttonType = "PushButton"; + iconBitmap = "./images/iconRefresh.png"; + sizeIconToButton = "0"; + textLocation = "Right"; + textMargin = "4"; + buttonMargin = "4 4"; + }; + new GuiTextCtrl(InspectObjectSimID) { + canSaveDynamicFields = "0"; + Profile = "EditorTextHLBoldCenter"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "265 35"; + Extent = "51 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "0"; + maxLength = "1024"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "321 6"; + Extent = "76 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "InspectDelete();"; + hovertime = "1000"; + text = "Delete"; + groupNum = "-1"; + buttonType = "PushButton"; + iconBitmap = "./images/iconDelete.png"; + sizeIconToButton = "0"; + textLocation = "Right"; + textMargin = "4"; + buttonMargin = "4 4"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- + +function Inspect(%obj) +{ + // Don't inspect the root group. + if( %obj == -1 ) + return; + + InspectFields.inspect(%obj); + + // Update selected object properties + InspectObjectName.setValue(%obj.getName()); + InspectObjectInternalName.setValue( %obj.getInternalName() ); + InspectObjectSimID.setValue( %obj.getId() ); + + // Store Object Reference + InspectObjectName.refObj = %obj; + +} + +function InspectApply() +{ + %obj = InspectObjectName.refObj; + if( !isObject( %obj ) ) + return; + + // Update name and internal name + %obj.setName( InspectObjectName.getValue() ); + %obj.setInternalName( InspectObjectInternalName.getValue() ); + + // Update inspected object information. + InspectFields.inspect( %obj ); +} + +function InspectDelete() +{ + %obj = InspectObjectName.refObj; + if( !isObject( %obj ) ) + return; + + %obj.delete(); + + // Update inspected object information. + InspectFields.inspect( 0 ); + + // Update selected object properties + InspectObjectName.setValue(""); + InspectObjectInternalName.setValue( "" ); + InspectObjectSimID.setValue( 0 ); + + +} + + +function InspectTreeView::onSelect(%this, %obj) +{ + Inspect(%obj); +} + +function Tree(%obj) +{ + Canvas.popDialog("simViewDlg"); + Canvas.pushDialog("simViewDlg", 20); + InspectTreeView.open(%obj); +} + +// MM: Added Dynamic group toggle support. +function GuiInspector::toggleDynamicGroupScript(%this, %obj) +{ + %this.toggleDynamicGroupExpand(); + %this.inspect(%obj); +} +// MM: Added group toggle support. +function GuiInspector::toggleGroupScript(%this, %obj, %fieldName) +{ + %this.toggleGroupExpand(%obj, %fieldName); + %this.inspect(%obj); +} + +// MM: Set All Group State support. +function GuiInspector::setAllGroupStateScript(%this, %obj, %groupState) +{ + %this.setAllGroupState(%groupState); + %this.inspect(%obj); +} diff --git a/Templates/Empty/game/tools/gui/uvEditor.ed.gui b/Templates/Empty/game/tools/gui/uvEditor.ed.gui new file mode 100644 index 000000000..c5f4b3b06 --- /dev/null +++ b/Templates/Empty/game/tools/gui/uvEditor.ed.gui @@ -0,0 +1,645 @@ +new GuiControl(UVEditorOverlay, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Profile = "GuiOverlayProfile"; + Enabled = "1"; + isContainer = "1"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl(UVEditor){ + profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + resizeWidth = "0"; + resizeHeight = "0"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + position = "72 98"; + extent =" 453 340"; + MinExtent = "453 340"; + text = "UV Editor"; + closeCommand = "UVEditor.hideDialog();"; + EdgeSnap = "0"; + canCollapse = "0"; + visible = "0"; + + new GuiTextCtrl() { + text = "0.0"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "26 24"; + Extent = "32 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "U"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "138 24"; + Extent = "32 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "1.0"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "250 24"; + Extent = "32 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + + new GuiTextCtrl() { + text = "0.0"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "4 36"; + Extent = "18 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "V"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "4 159"; + Extent = "18 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "1.0"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "4 282"; + Extent = "18 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + + new GuiControl(){ + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "GuiSolidDefaultProfile"; + position = "25 37"; + extent = "258 258"; + }; + + new GuiBitmapCtrl(){ + internalName = "bitmapPreview"; + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "GuiDefaultProfile"; + position = "26 38"; + extent = "256 256"; + wrap = "0"; + bitmap = ""; + }; + new GuiRectHandles(){ + internalName = "uvHandles"; + class = "UVEditorRectHandles"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "26 38"; + extent = "256 256"; + }; + + new GuiBitmapBorderCtrl() { + profile = "GuiGroupBorderProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "26 300"; + extent = "256 30"; + minExtent = "0 0"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + + new GuiTextCtrl() { + text = "Handle Color:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 7"; + Extent = "70 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiPopupMenuCtrlEx(){ + internalName = "colorPopup"; + Profile = "GuiPopupMenuProfile"; + Position = "80 5"; + Extent = "126 20"; + HorizSizing = "right"; + VertSizing = "bottom"; + Command = "UVEditor.onColorSelect();"; + reverseTextList = "0"; + }; + }; + + new GuiBitmapBorderCtrl() { + profile = "GuiGroupBorderProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "292 38"; + extent = "151 256"; + minExtent = "0 0"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + + new GuiTextCtrl() { + text = "U:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 12"; + Extent = "32 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + internalName = "UVX"; + class = "UVEditorUVTextEdit"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditNumericProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "44 10"; + Extent = "64 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiTextCtrl() { + text = "V:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 32"; + Extent = "32 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + internalName = "UVY"; + class = "UVEditorUVTextEdit"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditNumericProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "44 30"; + Extent = "64 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiTextCtrl() { + text = "Width:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 52"; + Extent = "32 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + internalName = "UVW"; + class = "UVEditorUVTextEdit"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditNumericProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "44 50"; + Extent = "64 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiTextCtrl() { + text = "Height:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 72"; + Extent = "32 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + internalName = "UVH"; + class = "UVEditorUVTextEdit"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditNumericProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "44 70"; + Extent = "64 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiButtonCtrl(){ + HorizSizing = "right"; + VertSizing = "top"; + profile = "GuiButtonProfile"; + position = "44 94"; + extent = "64 20"; + text = "Reset"; + command = "UVEditor.reset();"; + tooltip = "Reset the UV fields to their original values."; + }; + }; + new GuiButtonCtrl(){ + internalName = "OKButton"; + HorizSizing = "left"; + VertSizing = "top"; + profile = "GuiButtonProfile"; + position = "292 306"; + extent = "94 24"; + text = "OK"; + command = "UVEditor.apply();"; + Accelerator = "return"; + }; + new GuiButtonCtrl(){ + HorizSizing = "left"; + VertSizing = "top"; + profile = "GuiButtonProfile"; + position = "391 306"; + extent = "52 24"; + text = "Cancel"; + command = "UVEditor.hideDialog();"; + Accelerator = "escape"; + }; + }; +}; + +//----------------------------------------------------------------------------- + +function UVEditor::showDialog( %this, %applyCallback, %obj, %uv) +{ + // Set the select callback + UVEditor.applyCallback = %applyCallback; + + // Set the initial UV coordinates + UVEditor.originalUV = %uv; + UVEditor-->uvHandles.handleRect = %uv; + UVEditor.setTextValues(%uv); + + // Get the preview bitmap. Code copied from Material Selector. + %material = %obj.material; + if( %material.toneMap[0] $= "" && %material.diffuseMap[0] $= "" && !isObject(%material.cubemap) ) + { + %previewImage = "core/art/warnmat"; + } + else + { + if( %material.toneMap[0] !$= "" ) + %previewImage = %material.toneMap[0]; + else if( %material.diffuseMap[0] !$= "" ) + %previewImage = %material.diffuseMap[0]; + else if( %material.cubemap.cubeFace[0] !$= "" ) + %previewImage = %material.cubemap.cubeFace[0]; + + %materialDiffuse = %previewImage; + %materialPath = %material.getFilename(); + if( strchr( %materialDiffuse, "/") $= "" ) + { + %k = 0; + while( strpos( %materialPath, "/", %k ) != -1 ) + { + %foo = strpos( %materialPath, "/", %k ); + %k = %foo + 1; + } + + %foobar = getSubStr( %materialPath , %k , 99 ); + %previewImage = strreplace( %materialPath, %foobar, %previewImage ); + } + else + %previewImage = strreplace( %materialPath, %materialPath, %previewImage ); + } + + UVEditor-->bitmapPreview.setBitmap(%previewImage); + + // Set up the color popup + %popup = UVEditor-->colorPopup; + %popup.clear(); + %popup.add("Default1|255|134|0"); + %popup.add("Default2|0|121|255"); + %popup.add("Black|0|0|0"); + %popup.add("Gray|100|100|100"); + %popup.add("White|255|255|255"); + %popup.add("Red|255|0|0"); + %popup.add("Green|0|255|0"); + %popup.add("Blue|0|0|255"); + %popup.add("Yellow|255|255|0"); + %popup.add("Magenta|255|0|255"); + %popup.add("Cyan|0|255|255"); + %popup.setSelected(EditorSettings.value("WorldEditor/Color/uvEditorHandleColor")); + UVEditor-->uvHandles.useCustomColor = true; + UVEditor-->uvHandles.handleColor = %popup.getColorById(%popup.getSelected()); + + Canvas.pushDialog(UVEditorOverlay); + UVEditor.setVisible(1); +} + +function UVEditor::hideDialog( %this ) +{ + UVEditor.setVisible(0); + Canvas.popDialog(UVEditorOverlay); +} + +function UVEditor::apply( %this ) +{ + eval( "" @ UVEditor.applyCallback @ "(\"" @ UVEditor-->uvHandles.handleRect @ "\");"); + UVEditor.hideDialog(); +} + +function UVEditor::reset( %this ) +{ + UVEditor-->uvHandles.handleRect = UVEditor.originalUV; + UVEditor.setTextValues(UVEditor.originalUV); +} + +function UVEditor::setTextValues( %this, %uv ) +{ + UVEditor-->UVX.setText( getWord(%uv, 0) ); + UVEditor-->UVY.setText( getWord(%uv, 1) ); + UVEditor-->UVW.setText( getWord(%uv, 2) ); + UVEditor-->UVH.setText( getWord(%uv, 3) ); +} + +function UVEditor::onColorSelect( %this ) +{ + UVEditor-->uvHandles.useCustomColor = true; + %sel = $ThisControl.getSelected(); + UVEditor-->uvHandles.handleColor = $ThisControl.getColorById(%sel); + EditorSettings.setValue( "WorldEditor/Color/uvEditorHandleColor", %sel ); +} + +//----------------------------------------------------------------------------- + +function UVEditorRectHandles::onHandleRectChange( %this ) +{ + %uv = UVEditor-->uvHandles.handleRect; + UVEditor.setTextValues(%uv); +} + +//----------------------------------------------------------------------------- + +function UVEditorUVTextEdit::onValidate( %this ) +{ + %u = UVEditor-->UVX.getValue(); + %v = UVEditor-->UVY.getValue(); + %w = UVEditor-->UVW.getValue(); + %h = UVEditor-->UVH.getValue(); + + // Check limits + + if(%u < 0) + %u = 0; + if(%u > 1) + %u = 1; + if(%v < 0) + %v = 0; + if(%v > 1) + %v = 1; + + if(%w < 0) + %w = 0; + if(%w > 1) + %w = 1; + if(%h < 0) + %h = 0; + if(%h > 1) + %h = 1; + + if((%u+%w) > 1) + %w = 1 - %u; + if((%v+%h) > 1) + %h = 1 - %v; + + // Apply values + UVEditor-->UVX.setText( %u ); + UVEditor-->UVY.setText( %v ); + UVEditor-->UVW.setText( %w ); + UVEditor-->UVH.setText( %h ); + + UVEditor-->uvHandles.handleRect = %u SPC %v SPC %w SPC %h; +} + +function UVEditorUVTextEdit::onGainFirstResponder( %this ) +{ + %this.selectAllText(); +} diff --git a/Templates/Empty/game/tools/guiEditor/gui/EditorChooseGUI.ed.gui b/Templates/Empty/game/tools/guiEditor/gui/EditorChooseGUI.ed.gui new file mode 100644 index 000000000..27b5737b4 --- /dev/null +++ b/Templates/Empty/game/tools/guiEditor/gui/EditorChooseGUI.ed.gui @@ -0,0 +1,229 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiChunkedBitmapCtrl(EditorChooseGUI, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiContentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = "art/gui/background"; + useVariable = "0"; + tile = "0"; + + new GuiWindowCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + Position = "476 191"; + Extent = "211 351"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "GUI Selector"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "10 23"; + Extent = "188 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "1: Edit an Existing GUI"; + maxLength = "255"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "46 317"; + Extent = "120 23"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "GE_ReturnToMainMenu();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Play Game"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "10 41"; + Extent = "192 200"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "alwaysOn"; + lockHorizScroll = "false"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "4 0"; + + new GuiMLTextCtrl(GE_GUIList) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiMLTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 1"; + Extent = "169 560"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "1"; + }; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "112 267"; + Extent = "90 23"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GE_OpenGUIFile();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Browse"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "9 244"; + Extent = "183 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "2: Create New or Open Existing GUI"; + maxLength = "255"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "10 267"; + Extent = "93 23"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GuiEditorNewGuiDialog.init( \"NewGui\", \"GuiControl\" );" @ "Canvas.pushdialog(GuiEditorNewGuiDialog);"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "New GUI"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "9 294"; + Extent = "183 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "3: Play Game from Start"; + maxLength = "255"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/guiEditor/gui/gridTiny2.PNG b/Templates/Empty/game/tools/guiEditor/gui/gridTiny2.PNG new file mode 100644 index 000000000..8a2d1bd89 Binary files /dev/null and b/Templates/Empty/game/tools/guiEditor/gui/gridTiny2.PNG differ diff --git a/Templates/Empty/game/tools/guiEditor/gui/guiEditor.ed.gui b/Templates/Empty/game/tools/guiEditor/gui/guiEditor.ed.gui new file mode 100644 index 000000000..7056a931b --- /dev/null +++ b/Templates/Empty/game/tools/guiEditor/gui/guiEditor.ed.gui @@ -0,0 +1,1535 @@ +//--------------------------------------------------------------------------------------------- +// Torque Game Builder +// Copyright (C) GarageGames.com, Inc. +//--------------------------------------------------------------------------------------------- + +%guiContent = new GuiControl(GuiEditorGui, EditorGuiGroup) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiFrameSetCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiFrameSetProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 583"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + columns = "0 631"; + rows = "0"; + borderWidth = "1"; + border = "0"; + borderEnable = "dynamic"; + borderMovable = "dynamic"; + autoBalance = "1"; + fudgeFactor = "3"; + + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "627 583"; + MinExtent = "64 64"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiContainer(GHToolBar) { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "menubarProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "16000 32"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiBitmapButtonCtrl(GHWorldEditor) { + bitmap = "tools/worldEditor/images/toolbar/world"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 3"; + extent = "29 27"; + minExtent = "8 8"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.switchToWorldEditor();"; + tooltipProfile = "GuiToolTipProfile"; + ToolTip = "World Editor"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl(GHGuiEditor) { + bitmap = "tools/worldEditor/images/toolbar/gui"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "34 3"; + extent = "29 27"; + minExtent = "8 8"; + canSave = "1"; + visible = "1"; + tooltipProfile = "GuiToolTipProfile"; + ToolTip = "Gui Editor"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/worldEditor/images/toolbar/playbutton"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "64 3"; + extent = "29 27"; + minExtent = "8 8"; + canSave = "1"; + visible = "1"; + command = "GuiEdit(); Editor.close(\"PlayGui\");"; + tooltipProfile = "GuiToolTipProfile"; + ToolTip = "Play Game"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapCtrl() { + bitmap = "core/art/gui/images/separator-h.png"; + wrap = "0"; + isContainer = "0"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "98 3"; + extent = "2 26"; + minExtent = "1 1"; + canSave = "1"; + visible = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + isContainer = "1"; + profile = "GuiDefaultProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "99 0"; + extent = "723 32"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiPopUpMenuCtrl(GuiEditorContentList) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "NewGui - 8844"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiPopUpMenuProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "8 7"; + extent = "145 18"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(GuiEditorResList) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "1024 x 768 (XGA, 4:3)"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiPopUpMenuProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "161 7"; + extent = "136 18"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapCtrl() { + bitmap = "core/art/gui/images/separator-h.png"; + wrap = "0"; + isContainer = "0"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "307 3"; + extent = "2 26"; + minExtent = "1 1"; + canSave = "1"; + visible = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiControl() { + isContainer = "1"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "312 3"; + extent = "95 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiBitmapButtonCtrl(GuiEditorSnapCheckBox) { + bitmap = "tools/gui/images/GUI-editor/snap-grid"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "29 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipProfile = "GuiToolTipProfile"; + ToolTip = "Snap gui controls to a grid. Modify grid size under edit."; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl(GuiEditorEdgeSnapping_btn) { + bitmap = "tools/gui/images/GUI-editor/edgesnap"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "31 0"; + extent = "29 27"; + minExtent = "120 21"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.toggleEdgeSnap();"; + tooltipProfile = "GuiToolTipProfile"; + ToolTip = "Toggles Edge Smart Snapping"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl(GuiEditorCenterSnapping_btn) { + bitmap = "tools/gui/images/GUI-editor/centersnap"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "62 0"; + extent = "29 27"; + minExtent = "120 21"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.toggleCenterSnap();"; + tooltipProfile = "GuiToolTipProfile"; + ToolTip = "Toggles Center Smart Snapping"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapCtrl() { + bitmap = "core/art/gui/images/separator-h.png"; + wrap = "0"; + isContainer = "0"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "415 3"; + extent = "2 26"; + minExtent = "1 1"; + canSave = "1"; + visible = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiControl() { + isContainer = "1"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "422 3"; + extent = "95 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/GUI-editor/align-left"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "29 27"; + minExtent = "120 21"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.Justify(0);"; + tooltipProfile = "GuiToolTipProfile"; + ToolTip = "Align Left"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/GUI-editor/vertical-center"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 0"; + extent = "29 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.Justify(1);"; + tooltipProfile = "GuiToolTipProfile"; + ToolTip = "Center Vertically "; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/GUI-editor/align-right"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "40 0"; + extent = "29 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.Justify(2);"; + tooltipProfile = "GuiToolTipProfile"; + ToolTip = "Align Right"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + isContainer = "1"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "498 3"; + extent = "95 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/GUI-editor/align-top"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "29 27"; + minExtent = "120 21"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.Justify(3);"; + tooltipProfile = "GuiToolTipProfile"; + ToolTip = "Align Top"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/GUI-editor/horizontal-center"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "25 0"; + extent = "29 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.Justify(7);"; + tooltipProfile = "GuiToolTipProfile"; + ToolTip = "Center Horizontally"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/GUI-editor/align-bottom"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "50 0"; + extent = "29 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.Justify(4);"; + tooltipProfile = "GuiToolTipProfile"; + ToolTip = "Align Bottom"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapCtrl() { + bitmap = "core/art/gui/images/separator-h.png"; + wrap = "0"; + isContainer = "0"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "582 3"; + extent = "2 26"; + minExtent = "1 1"; + canSave = "1"; + visible = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapCtrl() { + bitmap = "core/art/gui/images/separator-h.png"; + wrap = "0"; + isContainer = "0"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "639 3"; + extent = "2 26"; + minExtent = "1 1"; + canSave = "1"; + visible = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiControl() { + isContainer = "1"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "615 3"; + extent = "117 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/GUI-editor/send-to-back"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "49 0"; + extent = "29 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.PushToBack();"; + tooltipProfile = "GuiToolTipProfile"; + ToolTip = "Send to Back"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/GUI-editor/bring-to-front"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "27 0"; + extent = "29 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.BringToFront();"; + tooltipProfile = "GuiToolTipProfile"; + ToolTip = "Send to Front"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + isContainer = "1"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "583 3"; + extent = "60 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/GUI-editor/distribute-horizontal"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "29 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.Justify(6);"; + tooltipProfile = "GuiToolTipProfile"; + ToolTip = "Distribute Horizontally"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/GUI-editor/distribute-vertical"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "25 0"; + extent = "29 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.Justify(5);"; + tooltipProfile = "GuiToolTipProfile"; + ToolTip = "Distribute Vertically"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; + //--------------------- + new GuiEditorRuler(GuiEditorTopRuler) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "10 32"; + Extent = "614 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + refCtrl = "GuiEditorScroll"; + editCtrl = "GuiEditor"; + }; + new GuiEditorRuler(GuiEditorLeftRuler) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "height"; + Position = "0 42"; + Extent = "10 523"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + refCtrl = "GuiEditorScroll"; + editCtrl = "GuiEditor"; + }; + + new GuiScrollCtrl(GuiEditorScroll) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "10 41"; + Extent = "617 543"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = false; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiControl(GuiEditorRegion) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "1 1"; + Extent = "640 480"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiBackFillProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "640 480"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/guiEditor/gui/gridTiny2"; + wrap = "1"; + }; + new GuiControl(GuiEditorContent) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "640 480"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + }; + new GuiEditCtrl(GuiEditor) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Docking = "None"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "640 480"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + }; + }; + }; + }; + new GuiControl(GuiEditorSidebar) { + isContainer = "1"; + Profile = "menubarProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "798 0"; + Extent = "226 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTabBookCtrl(GuiEditorTabBook) { + tabPosition = "Top"; + tabMargin = "7"; + minTabWidth = "40"; + tabHeight = "20"; + allowReorder = "1"; + defaultPage = "0"; + selectedPage = "0"; + FrontTabPadding = "0"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 12"; + Extent = "223 754"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTabPageCtrl() { + fitBook = "1"; + text = "GUI"; + maxLength = "1024"; + docking = "client"; + Margin = "-1 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 20"; + Extent = "223 734"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + internalName = "guiPage"; + + new GuiFrameSetCtrl() { + columns = "0"; + rows = "0 338"; + borderWidth = "1"; + borderColor = "207 207 207 207"; + borderEnable = "dynamic"; + borderMovable = "dynamic"; + autoBalance = "1"; + fudgeFactor = "2"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiFrameSetProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "222 734"; + MinExtent = "8 64"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiPanel() { + position = "0 0"; + extent = "222 337"; + + new GuiTextEditCtrl( GuiEditorTreeFilter ) { + position = "2 4"; + extent = "200 18"; + profile = "GuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + class = "GuiTreeViewFilterText"; + treeView = GuiEditorTreeView; + }; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/clear-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "205 5"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + class = "GuiTreeViewFilterClearButton"; + textCtrl = GuiEditorTreeFilter; + }; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 25"; + Extent = "222 312"; + MinExtent = "8 64"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTreeViewCtrl(GuiEditorTreeView) { + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "0"; + MouseDragging = "1"; + MultipleSelections = "1"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "0"; + ClearAllOnSingleSelection = "1"; + showRoot = "1"; + useInspectorTooltips = "0"; + tooltipOnWidthOnly = "0"; + compareToObjectID = "1"; + canRenameObjects = "1"; + renameInternal = "0"; + isContainer = "1"; + Profile = "GuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 22"; + Extent = "89 2"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + showObjectIds = "0"; + showClassNames = "0"; + showObjectNames = "1"; + showInternalNames = "1"; + showClassNameForUnnamedObjects = "1"; + }; + }; + }; + + new GuiControl() { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 338"; + Extent = "222 396"; + MinExtent = "8 64"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 2"; + Extent = "223 341"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiInspector(GuiEditorInspectFields) { + dividerMargin = "5"; + showCustomFields = "1"; + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + DynamicSize = "1"; + ChangeChildSizeToFit = "1"; + ChangeChildPosition = "1"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "221 24"; + MinExtent = "8 24"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + superClass = "EditorInspectorBase"; + }; + }; + new GuiMLTextCtrl(GuiEditorFieldInfo) { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + isContainer = "0"; + Profile = "GuiInspectorFieldInfoMLTextProfile"; + HorizSizing = "width"; + VertSizing = "top"; + position = "0 349"; + Extent = "213 13"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; + + new GuiTabPageCtrl() { + fitBook = "1"; + text = "Library"; + maxLength = "1024"; + docking = "client"; + Margin = "-1 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 20"; + Extent = "223 734"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + internalName = "toolboxPage"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + docking = "client"; + + new GuiStackControl(GuiEditorToolbox) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "2"; + DynamicSize = "1"; + ChangeChildSizeToFit = "1"; + ChangeChildPosition = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "3 3"; + Extent = "419 10008"; + MinExtent = "16 16"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; + + new GuiTabPageCtrl() { + fitBook = "1"; + text = "Profiles"; + maxLength = "1024"; + docking = "client"; + Margin = "-1 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 20"; + Extent = "223 734"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + internalName = "profilesPage"; + + new GuiFrameSetCtrl() { + columns = "0"; + rows = "0 338"; + borderWidth = "1"; + borderColor = "207 207 207 207"; + borderEnable = "dynamic"; + borderMovable = "dynamic"; + autoBalance = "1"; + fudgeFactor = "2"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiFrameSetProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "222 734"; + MinExtent = "8 64"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiPanel() { + position = "0 0"; + extent = "222 337"; + + new GuiTextEditCtrl( GuiEditorProfilesTreeFilter ) { + position = "2 4"; + extent = "200 18"; + profile = "GuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + class = "GuiTreeViewFilterText"; + treeView = GuiEditorProfilesTree; + }; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/clear-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "205 5"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + class = "GuiTreeViewFilterClearButton"; + textCtrl = GuiEditorProfilesTreeFilter; + }; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 25"; + Extent = "222 312"; + MinExtent = "8 64"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTreeViewCtrl(GuiEditorProfilesTree) { + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "0"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "0"; + DragToItemAllowed = "0"; + ClearAllOnSingleSelection = "1"; + showRoot = "1"; + internalNamesOnly = "0"; + objectNamesOnly = "0"; + useInspectorTooltips = "0"; + tooltipOnWidthOnly = "0"; + compareToObjectID = "1"; + canRenameObjects = "1"; + renameInternal = "0"; + isContainer = "1"; + Profile = "GuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "89 2"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiControl() { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 338"; + Extent = "222 396"; + MinExtent = "8 64"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextEditCtrl(GuiEditorProfileFileName) { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 2"; + Extent = "180 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/save-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "184 2"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GuiEditor.saveProfile( GuiEditorProfilesTree.getSelectedProfile(), GuiEditorProfileFileName.getText() );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Save the currently selected profile."; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/save-as"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "205 2"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GuiEditor.showSaveProfileDialog( GuiEditorProfileFileName.getText() );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Save the currently selected profile to a different file."; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 22"; + Extent = "223 321"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiInspector(GuiEditorProfileInspector) { + dividerMargin = "5"; + showCustomFields = "1"; + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + DynamicSize = "1"; + ChangeChildSizeToFit = "1"; + ChangeChildPosition = "1"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "221 24"; + MinExtent = "8 24"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + superClass = "EditorInspectorBase"; + }; + }; + new GuiMLTextCtrl(GuiEditorProfileFieldInfo) { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + isContainer = "0"; + Profile = "GuiInspectorFieldInfoMLTextProfile"; + HorizSizing = "width"; + VertSizing = "top"; + position = "0 349"; + Extent = "213 13"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; + }; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "156 12"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "button1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "174 12"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "button2"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "192 12"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "button3"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "207 12"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "button4"; + canSaveDynamicFields = "0"; + }; + }; + }; + + new GuiControl() { + position = "0 583"; + extent = "800 17"; + horizSizing = "width"; + vertSizing = "top"; + minExtent = "64 17"; + canSave = "1"; + visible = "1"; + isContainer = "1"; + profile = "menubarProfile"; + + new GuiTextCtrl( GuiEditorStatusBar ) { + profile = "GuiTextProfile"; + position = "5 0"; + extent = "500 17"; + minExtent = "64 17"; + canSave = "1"; + visible = "1"; + }; + new GuiSeparatorCtrl() { + profile = "GuiDefaultProfile"; + position = "505 0"; + extent = "10 17"; + minExtent = "10 17"; + canSave = "1"; + visible = "1"; + horizSizing = "left"; + }; + new GuiTextCtrl( GuiEditorSelectionStatus ) { + profile = "GuiTextProfile"; + position = "515 0"; + extent = "100 17"; + minExtent = "100 17"; + canSave = "1"; + visible = "1"; + horizSizing = "left"; + }; + }; +}; diff --git a/Templates/Empty/game/tools/guiEditor/gui/guiEditorNewGuiDialog.ed.gui b/Templates/Empty/game/tools/guiEditor/gui/guiEditorNewGuiDialog.ed.gui new file mode 100644 index 000000000..6d60958f6 --- /dev/null +++ b/Templates/Empty/game/tools/guiEditor/gui/guiEditorNewGuiDialog.ed.gui @@ -0,0 +1,199 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(GuiEditorNewGuiDialog,EditorGuiGroup) { + isContainer = "1"; + profile = "GuiOverlayProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + enabled = "1"; + + new GuiWindowCtrl() { + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + edgeSnap = "0"; + text = "Create new GUI"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "GuiWindowProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "357 303"; + extent = "310 161"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "228 114"; + extent = "63 25"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + command = "GuiEditorNewGuiDialog.onCancel();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Create"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "101 114"; + extent = "124 25"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + command = "GuiEditorNewGuiDialog.onOK();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + accelerator = "enter"; + }; + new GuiControl() { + isContainer = "1"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "15 28"; + extent = "278 76"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "GUI Name"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "14 13"; + extent = "80 18"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "103 13"; + extent = "160 17"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "nameField"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "GUI Class"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "14 44"; + extent = "80 18"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiPopUpMenuProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "103 44"; + extent = "160 18"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "classDropdown"; + canSaveDynamicFields = "0"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/guiEditor/gui/guiEditorPrefsDlg.ed.gui b/Templates/Empty/game/tools/guiEditor/gui/guiEditorPrefsDlg.ed.gui new file mode 100644 index 000000000..e9b3c5f77 --- /dev/null +++ b/Templates/Empty/game/tools/guiEditor/gui/guiEditorPrefsDlg.ed.gui @@ -0,0 +1,181 @@ +%guiContent = new GuiControl(GuiEditorPrefsDlg, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl() { + canSaveDynamicFields = "0"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "250 210"; + Extent = "280 95"; + MinExtent = "344 144"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "Canvas.popDialog(\"GuiEditorPrefsDlg\");"; + EdgeSnap = "0"; + text = "Gui Editor Grid Preferences"; + + new GuiButtonCtrl(GuiEditorPrefsDlgCancelBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + position = "100 60"; + Extent = "80 25"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Accelerator = "escape"; + hovertime = "1000"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl(GuiEditorPrefsDlgOkBtn) { + canSaveDynamicFields = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + position = "190 60"; + Extent = "80 25"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Ok"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl(GuiEditorPrefsDlgDefaultsBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "top"; + position = "10 60"; + Extent = "60 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Reset"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "center"; + VertSizing = "bottom"; + position = "-3 20"; + Extent = "288 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "16 10"; + Extent = "48 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Grid Size:"; + maxLength = "1024"; + }; + new GuiTextEditCtrl(GuiEditorPrefsDlgGridEdit) { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + Enabled = "1"; + Component = "textEdit"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "72 11"; + Extent = "32 18"; + MinExtent = "8 18"; + canSave = "1"; + Visible = "1"; + Command = "GuiEditorPrefsDlgGridEdit.onAction();"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + }; + new GuiSliderCtrl(GuiEditorPrefsDlgGridSlider) { + canSaveDynamicFields = "0"; + internalName = "Slider"; + Enabled = "1"; + Component = "Slider"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "112 14"; + Extent = "160 12"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "GuiEditorPrefsDlgGridSlider.onAction();"; + hovertime = "1000"; + range = "0 64"; + ticks = "0"; + value = "0"; + }; + }; + }; +}; + diff --git a/Templates/Empty/game/tools/guiEditor/gui/guiEditorSelectDlg.ed.gui b/Templates/Empty/game/tools/guiEditor/gui/guiEditorSelectDlg.ed.gui new file mode 100644 index 000000000..9dab62999 --- /dev/null +++ b/Templates/Empty/game/tools/guiEditor/gui/guiEditorSelectDlg.ed.gui @@ -0,0 +1,566 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(GuiEditorSelectDlgContainer,EditorGuiGroup) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiWindowCtrl(GuiEditorSelectDlg) { + text = "Select Controls"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "1"; + closeCommand = "$ThisControl.toggleVisibility();"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "268 177"; + extent = "380 373"; + minExtent = "200 100"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + class = "EObjectSelection"; + internalName = "SelectControlsDlg"; + + new GuiBitmapBorderCtrl() { + position = "7 104"; + extent = "265 262"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiGroupBorderProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "10 25"; + extent = "246 200"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "0"; + dynamicSize = "1"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "1 1"; + extent = "246 1242"; + minExtent = "16 16"; + horizSizing = "width"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "classList"; + canSave = "1"; + canSaveDynamicFields = "0"; + + }; + }; + new GuiButtonCtrl() { + text = "Select All"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "10 231"; + extent = "65 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "GuiEditorSelectDlg.selectAllInClassList( true );"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Classes"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "113 6"; + extent = "40 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiAutoSizeTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Deselect All"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "76 231"; + extent = "65 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "GuiEditorSelectDlg.selectAllInClassList( false );"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapBorderCtrl() { + position = "7 25"; + extent = "366 74"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiGroupBorderProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Name Pattern"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "11 9"; + extent = "67 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiAutoSizeTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Retain Current Selection"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "216 46"; + extent = "140 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "retainSelection"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Create Selection Set"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "13 73"; + extent = "117 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiCheckBoxProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "createSelectionSet"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "•"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "157 80"; + extent = "199 17"; + minExtent = "20 2"; + horizSizing = "width"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiTextEditProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "selectionSetName"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "•"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "91 9"; + extent = "265 17"; + minExtent = "20 2"; + horizSizing = "width"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "namePattern"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Select Child Controls Of:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "11 30"; + extent = "119 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiAutoSizeTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "138 30"; + extent = "218 17"; + minExtent = "20 2"; + horizSizing = "width"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "groupList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapBorderCtrl() { + position = "246 104"; + extent = "233 262"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiGroupBorderProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "9 25"; + extent = "215 200"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "0"; + dynamicSize = "1"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "1 1"; + extent = "215 16"; + minExtent = "16 16"; + horizSizing = "width"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "filterList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiButtonCtrl() { + text = "Select All"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "9 231"; + extent = "65 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Filters"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "101 6"; + extent = "30 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiAutoSizeTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Deselect All"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "75 231"; + extent = "65 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiButtonCtrl() { + text = "Select"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "278 104"; + extent = "95 30"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "GuiEditorSelectDlg.onSelectObjects(true);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Deselect"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "278 137"; + extent = "95 30"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "GuiEditorSelectDlg.onSelectObjects(false);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/guiEditor/main.cs b/Templates/Empty/game/tools/guiEditor/main.cs new file mode 100644 index 000000000..da793b380 --- /dev/null +++ b/Templates/Empty/game/tools/guiEditor/main.cs @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function initializeGuiEditor() +{ + echo( " % - Initializing Gui Editor" ); + + // GUIs. + + exec( "./gui/guiEditor.ed.gui" ); + exec( "./gui/guiEditorNewGuiDialog.ed.gui" ); + exec( "./gui/guiEditorPrefsDlg.ed.gui" ); + exec( "./gui/guiEditorSelectDlg.ed.gui" ); + exec( "./gui/EditorChooseGUI.ed.gui" ); + + // Scripts. + + exec( "./scripts/guiEditor.ed.cs" ); + exec( "./scripts/guiEditorTreeView.ed.cs" ); + exec( "./scripts/guiEditorInspector.ed.cs" ); + exec( "./scripts/guiEditorProfiles.ed.cs" ); + exec( "./scripts/guiEditorGroup.ed.cs" ); + exec( "./scripts/guiEditorUndo.ed.cs" ); + exec( "./scripts/guiEditorCanvas.ed.cs" ); + exec( "./scripts/guiEditorContentList.ed.cs" ); + exec( "./scripts/guiEditorStatusBar.ed.cs" ); + exec( "./scripts/guiEditorToolbox.ed.cs" ); + exec( "./scripts/guiEditorSelectDlg.ed.cs" ); + + exec( "./scripts/guiEditorNewGuiDialog.ed.cs" ); + exec( "./scripts/fileDialogs.ed.cs" ); + exec( "./scripts/guiEditorPrefsDlg.ed.cs" ); + exec( "./scripts/EditorChooseGUI.ed.cs" ); +} + +function destroyGuiEditor() +{ +} diff --git a/Templates/Empty/game/tools/guiEditor/scripts/EditorChooseGUI.ed.cs b/Templates/Empty/game/tools/guiEditor/scripts/EditorChooseGUI.ed.cs new file mode 100644 index 000000000..d59c61225 --- /dev/null +++ b/Templates/Empty/game/tools/guiEditor/scripts/EditorChooseGUI.ed.cs @@ -0,0 +1,105 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function GE_ReturnToMainMenu() +{ + loadMainMenu(); +} + +function GE_OpenGUIFile() +{ + %openFileName = GuiBuilder::getOpenName(); + if( %openFileName $= "" ) + return; + + // Make sure the file is valid. + if ((!isFile(%openFileName)) && (!isFile(%openFileName @ ".dso"))) + return; + + // Allow stomping objects while exec'ing the GUI file as we want to + // pull the file's objects even if we have another version of the GUI + // already loaded. + + %oldRedefineBehavior = $Con::redefineBehavior; + $Con::redefineBehavior = "replaceExisting"; + + // Load up the level. + exec( %openFileName ); + + $Con::redefineBehavior = %oldRedefineBehavior; + + // The level file should have contained a scenegraph, which should now be in the instant + // group. And, it should be the only thing in the group. + if( !isObject( %guiContent ) ) + { + MessageBox( getEngineName(), + "You have loaded a Gui file that was created before this version. It has been loaded but you must open it manually from the content list dropdown", + "Ok", "Information" ); + GuiEditContent( Canvas.getContent() ); + return 0; + } + + GuiEditContent( %guiContent ); +} + +function GE_GUIList::onURL(%this, %url) +{ + // Remove 'gamelink:' from front + %gui = getSubStr(%url, 9, 1024); + GuiEditContent(%gui); +} + +function EditorChooseGUI::onWake() +{ + // Build the text list + GE_GUIList.clear(); + + %list = "<linkcolor:0000FF><linkcolorhl:FF0000>"; + %list = GE_ScanGroupForGuis(GuiGroup, %list); + GE_GUIList.setText(%list); + GE_GUIList.forceReflow(); + GE_GUIList.scrollToTop(); +} + +function GE_ScanGroupForGuis(%group, %text) +{ + %count = %group.getCount(); + for(%i=0; %i < %count; %i++) + { + %obj = %group.getObject(%i); + if(%obj.getClassName() $= "GuiCanvas") + { + %text = %text @ GE_ScanGroupForGuis(%obj, %text); + } + else + { + if(%obj.getName() $= "") + %name = "(unnamed) - " @ %obj; + else + %name = %obj.getName() @ " - " @ %obj; + + %text = %text @ "<a:gamelink:" @ %obj @ ">" @ %name @ "</a><br>"; + } + } + + return %text; +} diff --git a/Templates/Empty/game/tools/guiEditor/scripts/fileDialogs.ed.cs b/Templates/Empty/game/tools/guiEditor/scripts/fileDialogs.ed.cs new file mode 100644 index 000000000..dbb1a2a37 --- /dev/null +++ b/Templates/Empty/game/tools/guiEditor/scripts/fileDialogs.ed.cs @@ -0,0 +1,98 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +$GUI::FileSpec = "Torque Gui Files (*.gui)|*.gui|All Files (*.*)|*.*|"; + +/// GuiBuilder::getSaveName - Open a Native File dialog and retrieve the +/// location to save the current document. +/// @arg defaultFileName The FileName to default in the field and to be selected when a path is opened +function GuiBuilder::getSaveName( %defaultFileName ) +{ + %defaultPath = GuiEditor.LastPath; + + if( %defaultFileName $= "" ) + { + %prefix = ""; + if( isFunction( "isScriptPathExpando" ) ) + { + // if we're editing a game, we want to default to the games dir. + // if we're not, then we default to the tools directory or the base. + if( isScriptPathExpando( "^game") ) + %prefix = "^game/"; + else if( isScriptPathExpando( "^tools" ) ) + %prefix = "^tools/"; + } + + %defaultFileName = expandFilename( %prefix @ "gui/untitled.gui" ); + } + else + %defaultPath = filePath( %defaultFileName ); + + %dlg = new SaveFileDialog() + { + Filters = $GUI::FileSpec; + DefaultPath = makeFullPath( %defaultPath ); + DefaultFile = %defaultFileName; + ChangePath = false; + OverwritePrompt = true; + }; + + if( %dlg.Execute() ) + { + GuiEditor.LastPath = filePath( %dlg.FileName ); + %filename = %dlg.FileName; + if( fileExt( %filename ) !$= ".gui" ) + %filename = %filename @ ".gui"; + } + else + %filename = ""; + + %dlg.delete(); + + return %filename; +} + +function GuiBuilder::getOpenName( %defaultFileName ) +{ + if( %defaultFileName $= "" ) + %defaultFileName = expandFilename("^game/gui/untitled.gui"); + + %dlg = new OpenFileDialog() + { + Filters = $GUI::FileSpec; + DefaultPath = GuiEditor.LastPath; + DefaultFile = %defaultFileName; + ChangePath = false; + MustExist = true; + }; + + if(%dlg.Execute()) + { + GuiEditor.LastPath = filePath( %dlg.FileName ); + %filename = %dlg.FileName; + %dlg.delete(); + return %filename; + } + + %dlg.delete(); + return ""; +} diff --git a/Templates/Empty/game/tools/guiEditor/scripts/guiEditor.ed.cs b/Templates/Empty/game/tools/guiEditor/scripts/guiEditor.ed.cs new file mode 100644 index 000000000..505150b63 --- /dev/null +++ b/Templates/Empty/game/tools/guiEditor/scripts/guiEditor.ed.cs @@ -0,0 +1,1154 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +//============================================================================================= +// Activation. +//============================================================================================= + +$InGuiEditor = false; +$MLAAFxGuiEditorTemp = false; + +function GuiEdit( %val ) +{ + if (Canvas.isFullscreen()) + { + MessageBoxOK("Windowed Mode Required", "Please switch to windowed mode to access the GUI Editor."); + return; + } + + if(%val != 0) + return; + + if (!$InGuiEditor) + { + GuiEditContent(Canvas.getContent()); + + //Temp fix to disable MLAA when in GUI editor + if( isObject(MLAAFx) && MLAAFx.isEnabled==true ) + { + MLAAFx.isEnabled = false; + $MLAAFxGuiEditorTemp = true; + } + + } + else + { + GuiEditCanvas.quit(); + } + +} + +function GuiEditContent( %content ) +{ + if( !isObject( GuiEditCanvas ) ) + new GuiControl( GuiEditCanvas, EditorGuiGroup ); + + GuiEditor.openForEditing( %content ); + + $InGuiEditor = true; +} + +function toggleGuiEditor( %make ) +{ + if( %make ) + { + if( EditorIsActive() && !GuiEditor.toggleIntoEditorGui ) + toggleEditor( true ); + + GuiEdit(); + + // Cancel the scheduled event to prevent + // the level from cycling after it's duration + // has elapsed. + cancel($Game::Schedule); + } +} + +GlobalActionMap.bind( keyboard, "f10", toggleGuiEditor ); + +//============================================================================================= +// Methods. +//============================================================================================= + +package GuiEditor_BlockDialogs +{ + function GuiCanvas::pushDialog() {} + function GuiCanvas::popDialog() {} +}; + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::openForEditing( %this, %content ) +{ + Canvas.setContent( GuiEditorGui ); + while( GuiEditorContent.getCount() ) + GuiGroup.add( GuiEditorContent.getObject( 0 ) ); // get rid of anything being edited + + // Clear the current guide set and add the guides + // from the control. + + %this.clearGuides(); + %this.readGuides( %content ); + + // Enumerate GUIs and put them into the content list. + + GuiEditorContentList.init(); + + GuiEditorScroll.scrollToTop(); + activatePackage( GuiEditor_BlockDialogs ); + GuiEditorContent.add( %content ); + deactivatePackage( GuiEditor_BlockDialogs ); + GuiEditorContentList.sort(); + + if(%content.getName() $= "") + %name = "(unnamed) - " @ %content; + else + %name = %content.getName() @ " - " @ %content; + + GuiEditorContentList.setText(%name); + + %this.setContentControl(%content); + + // Initialize the preview resolution list and select the current + // preview resolution. + + GuiEditorResList.init(); + + %res = %this.previewResolution; + if( %res $= "" ) + %res = "1024 768"; + GuiEditorResList.selectFormat( %res ); + + // Initialize the treeview and expand the first level. + + GuiEditorTreeView.init(); + GuiEditorTreeView.open( %content ); + GuiEditorTreeView.expandItem( 1 ); + + // Initialize profiles tree. + + if( !GuiEditorProfilesTree.isInitialized ) + { + GuiEditorProfilesTree.init(); + GuiEditorProfilesTree.isInitialized = true; + } + + // Create profile change manager if we haven't already. + + if( !isObject( GuiEditorProfileChangeManager ) ) + new SimGroup( GuiEditorProfileChangeManager ); + + // clear the undo manager if we're switching controls. + if( %this.lastContent != %content ) + GuiEditor.getUndoManager().clearAll(); + + GuiEditor.setFirstResponder(); + + %this.updateUndoMenu(); + %this.lastContent = %content; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::switchToWorldEditor( %this ) +{ + %editingWorldEditor = false; + if( GuiEditorContent.getObject( 0 ) == EditorGui.getId() ) + %editingWorldEditor = true; + + GuiEdit(); + + if( !$missionRunning ) + EditorNewLevel(); + else if( !%editingWorldEditor ) + toggleEditor( true ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::enableMenuItems(%this, %val) +{ + %menu = GuiEditCanvas.menuBar->EditMenu.getID(); + + %menu.enableItem( 3, %val ); // cut + %menu.enableItem( 4, %val ); // copy + %menu.enableItem( 5, %val ); // paste + //%menu.enableItem( 7, %val ); // selectall + //%menu.enableItem( 8, %val ); // deselectall + %menu.enableItem( 9, %val ); // selectparents + %menu.enableItem( 10, %val ); // selectchildren + %menu.enableItem( 11, %val ); // addselectparents + %menu.enableItem( 12, %val ); // addselectchildren + %menu.enableItem( 15, %val ); // lock + %menu.enableItem( 16, %val ); // hide + %menu.enableItem( 18, %val ); // group + %menu.enableItem( 19, %val ); // ungroup + + GuiEditCanvas.menuBar->LayoutMenu.enableAllItems( %val ); + GuiEditCanvas.menuBar->MoveMenu.enableAllItems( %val ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::showPrefsDialog(%this) +{ + Canvas.pushDialog(GuiEditorPrefsDlg); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::getUndoManager( %this ) +{ + if( !isObject( GuiEditorUndoManager ) ) + new UndoManager( GuiEditorUndoManager ); + + return GuiEditorUndoManager; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::undo(%this) +{ + %action = %this.getUndoManager().getNextUndoName(); + + %this.getUndoManager().undo(); + %this.updateUndoMenu(); + //%this.clearSelection(); + + GuiEditorStatusBar.print( "Undid '" @ %action @ "'" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::redo(%this) +{ + %action = %this.getUndoManager().getNextRedoName(); + + %this.getUndoManager().redo(); + %this.updateUndoMenu(); + //%this.clearSelection(); + + GuiEditorStatusBar.print( "Redid '" @ %action @ "'" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::updateUndoMenu(%this) +{ + %uman = %this.getUndoManager(); + %nextUndo = %uman.getNextUndoName(); + %nextRedo = %uman.getNextRedoName(); + + %editMenu = GuiEditCanvas.menuBar->editMenu; + + %editMenu.setItemName( 0, "Undo " @ %nextUndo ); + %editMenu.setItemName( 1, "Redo " @ %nextRedo ); + + %editMenu.enableItem( 0, %nextUndo !$= "" ); + %editMenu.enableItem( 1, %nextRedo !$= "" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::isFilteredClass( %this, %className ) +{ + // Filter out all the internal GuiInspector classes. + + if( startsWith( %className, "GuiInspector" ) && %className !$= "GuiInspector" ) + return true; + + // Filter out GuiEditor classes. + + if( startsWith( %className, "GuiEditor" ) ) + return true; + + // Filter out specific classes. + + switch$( %className ) + { + case "GuiCanvas": return true; + case "GuiAviBitmapCtrl": return true; // For now. Probably removed altogether. + case "GuiArrayCtrl": return true; // Abstract base class really. + case "GuiScintillaTextCtrl": return true; // Internal class. + case "GuiNoMouseCtrl": return true; // Too odd. + case "GuiEditCtrl": return true; + case "GuiBackgroundCtrl": return true; // Just plain useless. + case "GuiTSCtrl": return true; // Abstract base class. + case "GuiTickCtrl": return true; // Abstract base class. + case "GuiWindowCollapseCtrl": return true; // Legacy. + } + + return false; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::editProfile( %this, %profile ) +{ + GuiEditorTabBook->profilesPage.select(); + GuiEditorProfilesTree.setSelectedProfile( %profile ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::createControl( %this, %className ) +{ + %ctrl = eval( "return new " @ %className @ "();" ); + if( !isObject( %ctrl ) ) + return; + + // Add the control. + + %this.addNewCtrl( %ctrl ); +} + +//--------------------------------------------------------------------------------------------- + +/// Group all GuiControls in the currenct selection set under a new GuiControl. +function GuiEditor::groupSelected( %this ) +{ + %selection = %this.getSelection(); + if( %selection.getCount() < 2 ) + return; + + // Create action. + + %action = GuiEditorGroupAction::create( %selection, GuiEditor.getContentControl() ); + %action.groupControls(); + + // Update editor tree. + + %this.clearSelection(); + %this.addSelection( %action.group[ 0 ].groupObject ); + GuiEditorTreeView.update(); + + // Update undo state. + + %action.addtoManager( %this.getUndoManager() ); + %this.updateUndoMenu(); +} + +//--------------------------------------------------------------------------------------------- + +/// Take all direct GuiControl instances in the selection set and reparent their child controls +/// to each of the group's parents. The GuiControl group objects are deleted. +function GuiEditor::ungroupSelected( %this ) +{ + %action = GuiEditorUngroupAction::create( %this.getSelection() ); + %action.ungroupControls(); + + // Update editor tree. + + %this.clearSelection(); + GuiEditorTreeView.update(); + + // Update undo state. + + %action.addToManager( %this.getUndoManager() ); + %this.updateUndoMenu(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::deleteControl( %this, %ctrl ) +{ + // Unselect. + + GuiEditor.removeSelection( %ctrl ); + + // Record undo. + + %set = new SimSet() { parentGroup = RootGroup; }; + %set.add( %ctrl ); + + %action = UndoActionDeleteObject::create( %set, %this.getTrash(), GuiEditorTreeView ); + %action.addToManager( %this.getUndoManager() ); + %this.updateUndoMenu(); + + GuiEditorTreeView.update(); + %set.delete(); + + // Remove. + + %this.getTrash().add( %ctrl ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::setPreviewResolution( %this, %width, %height ) +{ + GuiEditorRegion.resize( 0, 0, %width, %height ); + GuiEditorContent.getObject( 0 ).resize( 0, 0, %width, %height ); + + GuiEditor.previewResolution = %width SPC %height; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::toggleEdgeSnap( %this ) +{ + %this.snapToEdges = !%this.snapToEdges; + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_EDGESNAP_INDEX, %this.snapToEdges ); + GuiEditorEdgeSnapping_btn.setStateOn( %this.snapToEdges ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::toggleCenterSnap( %this ) +{ + %this.snapToCenters = !%this.snapToCenters; + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_CENTERSNAP_INDEX, %this.snapToCenters ); + GuiEditorCenterSnapping_btn.setStateOn( %this.snapToCenters ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::toggleFullBoxSelection( %this ) +{ + %this.fullBoxSelection = !%this.fullBoxSelection; + GuiEditCanvas.menuBar->EditMenu.checkItem( $GUI_EDITOR_MENU_FULLBOXSELECT_INDEX, %this.fullBoxSelection ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::toggleDrawGuides( %this ) +{ + %this.drawGuides= !%this.drawGuides; + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_DRAWGUIDES_INDEX, %this.drawGuides ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::toggleGuideSnap( %this ) +{ + %this.snapToGuides = !%this.snapToGuides; + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_GUIDESNAP_INDEX, %this.snapToGuides ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::toggleControlSnap( %this ) +{ + %this.snapToControls = !%this.snapToControls; + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_CONTROLSNAP_INDEX, %this.snapToControls ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::toggleCanvasSnap( %this ) +{ + %this.snapToCanvas = !%this.snapToCanvas; + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_CANVASSNAP_INDEX, %this.snapToCanvas ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::toggleGridSnap( %this ) +{ + %this.snap2Grid = !%this.snap2Grid; + if( !%this.snap2Grid ) + %this.setSnapToGrid( 0 ); + else + %this.setSnapToGrid( %this.snap2GridSize ); + + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_GRIDSNAP_INDEX, %this.snap2Grid ); + GuiEditorSnapCheckBox.setStateOn( %this.snap2Grid ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::toggleLockSelection( %this ) +{ + %this.toggleFlagInAllSelectedObjects( "locked" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::toggleHideSelection( %this ) +{ + %this.toggleFlagInAllSelectedObjects( "hidden" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::selectAllControlsInSet( %this, %set, %deselect ) +{ + if( !isObject( %set ) ) + return; + + foreach( %obj in %set ) + { + if( !%obj.isMemberOfClass( "GuiControl" ) ) + continue; + + if( !%deselect ) + %this.addSelection( %obj ); + else + %this.removeSelection( %obj ); + } +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::toggleFlagInAllSelectedObjects( %this, %flagFieldName ) +{ + // Use the inspector's code here to record undo information + // for the field edits. + + GuiEditorInspectFields.onInspectorPreFieldModification( %flagFieldName ); + + %selected = %this.getSelection(); + foreach( %object in %selected ) + %object.setFieldValue( %flagFieldName, !%object.getFieldValue( %flagFieldName ) ); + + GuiEditorInspectFields.onInspectorPostFieldModification(); + GuiEditorInspectFields.refresh(); +} + +//============================================================================================= +// Event Handlers. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onDelete(%this) +{ + GuiEditorTreeView.update(); + // clear out the gui inspector. + GuiEditorInspectFields.update(0); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onSelectionMoved( %this, %ctrl ) +{ + GuiEditorInspectFields.update( %ctrl ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onSelectionResized( %this, %ctrl ) +{ + GuiEditorInspectFields.update( %ctrl ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onSelect(%this, %ctrl) +{ + if( !%this.dontSyncTreeViewSelection ) + { + GuiEditorTreeView.clearSelection(); + GuiEditorTreeView.addSelection( %ctrl ); + } + + GuiEditorInspectFields.update( %ctrl ); + + GuiEditorSelectionStatus.setText( "1 Control Selected" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onAddSelected( %this, %ctrl ) +{ + if( !%this.dontSyncTreeViewSelection ) + { + GuiEditorTreeView.addSelection( %ctrl ); + GuiEditorTreeView.scrollVisibleByObjectId( %ctrl ); + } + + GuiEditorSelectionStatus.setText( %this.getNumSelected() @ " Controls Selected" ); + + // Add to inspection set. + + GuiEditorInspectFields.addInspect( %ctrl ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onRemoveSelected( %this, %ctrl ) +{ + if( !%this.dontSyncTreeViewSelection ) + GuiEditorTreeView.removeSelection( %ctrl ); + + GuiEditorSelectionStatus.setText( %this.getNumSelected() @ " Controls Selected" ); + + // Remove from inspection set. + + GuiEditorInspectFields.removeInspect( %ctrl ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onClearSelected( %this ) +{ + if( !%this.dontSyncTreeViewSelection ) + GuiEditorTreeView.clearSelection(); + + GuiEditorInspectFields.update( 0 ); + GuiEditorSelectionStatus.setText( "" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onControlDragged( %this, %payload, %position ) +{ + // Make sure we have the right kind of D&D. + + if( !%payload.parentGroup.isInNamespaceHierarchy( "GuiDragAndDropControlType_GuiControl" ) ) + return; + + // use the position under the mouse cursor, not the payload position. + %position = VectorSub( %position, GuiEditorContent.getGlobalPosition() ); + %x = getWord( %position, 0 ); + %y = getWord( %position, 1 ); + %target = GuiEditor.getContentControl().findHitControl( %x, %y ); + + // Make sure the target is a valid parent for our payload. + + while( ( !%target.isContainer || !%target.acceptsAsChild( %payload ) ) + && %target != GuiEditor.getContentControl() ) + %target = %target.getParent(); + + if( %target != %this.getCurrentAddSet() ) + %this.setCurrentAddSet( %target ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onControlDropped(%this, %payload, %position) +{ + // Make sure we have the right kind of D&D. + + if( !%payload.parentGroup.isInNamespaceHierarchy( "GuiDragAndDropControlType_GuiControl" ) ) + return; + + %pos = %payload.getGlobalPosition(); + %x = getWord(%pos, 0); + %y = getWord(%pos, 1); + + %this.addNewCtrl(%payload); + + %payload.setPositionGlobal(%x, %y); + %this.setFirstResponder(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onGainFirstResponder(%this) +{ + %this.enableMenuItems(true); + + // JCF: don't just turn them all on! + // Undo/Redo is only enabled if those actions exist. + %this.updateUndoMenu(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onLoseFirstResponder(%this) +{ + %this.enableMenuItems(false); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onHierarchyChanged( %this ) +{ + GuiEditorTreeView.update(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onMouseModeChange( %this ) +{ + GuiEditorStatusBar.setText( GuiEditorStatusBar.getMouseModeHelp() ); +} + +//============================================================================================= +// Resolution List. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorResList::init( %this ) +{ + %this.clear(); + + // Non-widescreen formats. + + %this.add( "640x480 (VGA, 4:3)", 640 ); + %this.add( "800x600 (SVGA, 4:3)", 800 ); + %this.add( "1024x768 (XGA, 4:3)", 1024 ); + %this.add( "1280x1024 (SXGA, 4:3)", 1280 ); + %this.add( "1600x1200 (UXGA, 4:3)", 1600 ); + + // Widescreen formats. + + %this.add( "1280x720 (WXGA, 16:9)", 720 ); + %this.add( "1600x900 (16:9)", 900 ); + %this.add( "1920x1080 (16:9)", 1080 ); + %this.add( "1440x900 (WXGA+, 16:10)", 900 ); + %this.add( "1680x1050 (WSXGA+, 16:10)", 1050 ); + %this.add( "1920x1200 (WUXGA, 16:10)", 1200 ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorResList::selectFormat( %this, %format ) +{ + %width = getWord( %format, 0 ); + %height = getWord( %format, 1 ); + + switch( %height ) + { + case 720: + %this.setSelected( 720 ); + + case 900: + %this.setSelected( 900 ); + + case 1050: + %this.setSelected( 1050 ); + + case 1080: + %this.setSelected( 1080 ); + + default: + + switch( %width ) + { + case 640: + %this.setSelected( 640 ); + + case 800: + %this.setSelected( 800 ); + + case 1024: + %this.setSelected( 1024 ); + + case 1280: + %this.setSelected( 1280 ); + + case 1600: + %this.setSelected( 1600 ); + + default: + %this.setSelected( 1200 ); + } + } +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorResList::onSelect( %this, %id ) +{ + switch( %id ) + { + case 640: + GuiEditor.setPreviewResolution( 640, 480 ); + + case 800: + GuiEditor.setPreviewResolution( 800, 600 ); + + case 1024: + GuiEditor.setPreviewResolution( 1024, 768 ); + + case 1280: + GuiEditor.setPreviewResolution( 1280, 1024 ); + + case 1600: + GuiEditor.setPreviewResolution( 1600, 1200 ); + + case 720: + GuiEditor.setPreviewResolution( 1280, 720 ); + + case 900: + GuiEditor.setPreviewResolution( 1440, 900 ); + + case 1050: + GuiEditor.setPreviewResolution( 1680, 1050 ); + + case 1080: + GuiEditor.setPreviewResolution( 1920, 1080 ); + + case 1200: + GuiEditor.setPreviewResolution( 1920, 1200 ); + } +} + +//============================================================================================= +// Sidebar. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTabBook::onWake( %this ) +{ + if( !isObject( "GuiEditorTabBookLibraryPopup" ) ) + new PopupMenu( GuiEditorTabBookLibraryPopup ) + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Alphabetical View" TAB "" TAB "GuiEditorToolbox.setViewType( \"Alphabetical\" );"; + item[ 1 ] = "Categorized View" TAB "" TAB "GuiEditorToolbox.setViewType( \"Categorized\" );"; + }; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTabBook::onTabSelected( %this, %text, %index ) +{ + %sidebar = GuiEditorSidebar; + %name = %this.getObject( %index ).getInternalName(); + + switch$( %name ) + { + case "guiPage": + + %sidebar-->button1.setVisible( false ); + %sidebar-->button2.setVisible( false ); + %sidebar-->button3.setVisible( true ); + %sidebar-->button4.setVisible( true ); + + %sidebar-->button4.setBitmap( "tools/gui/images/delete" ); + %sidebar-->button4.command = "GuiEditor.deleteSelection();"; + %sidebar-->button4.tooltip = "Delete Selected Control(s)"; + + %sidebar-->button3.setBitmap( "tools/gui/images/visible" ); + %sidebar-->button3.command = "GuiEditor.toggleHideSelection();"; + %sidebar-->button3.tooltip = "Hide Selected Control(s)"; + + case "profilesPage": + + %sidebar-->button1.setVisible( true ); + %sidebar-->button2.setVisible( true ); + %sidebar-->button3.setVisible( true ); + %sidebar-->button4.setVisible( true ); + + %sidebar-->button4.setBitmap( "tools/gui/images/delete" ); + %sidebar-->button4.command = "GuiEditor.showDeleteProfileDialog( GuiEditorProfilesTree.getSelectedProfile() );"; + %sidebar-->button4.tooltip = "Delete Selected Profile"; + + %sidebar-->button3.setBitmap( "core/art/gui/images/new" ); + %sidebar-->button3.command = "GuiEditor.createNewProfile( \"Unnamed\" );"; + %sidebar-->button3.tooltip = "Create New Profile with Default Values"; + + %sidebar-->button2.setBitmap( "tools/gui/images/copy-btn" ); + %sidebar-->button2.command = "GuiEditor.createNewProfile( GuiEditorProfilesTree.getSelectedProfile().getName(), GuiEditorProfilesTree.getSelectedProfile() );"; + %sidebar-->button2.tooltip = "Create New Profile by Copying the Selected Profile"; + + %sidebar-->button1.setBitmap( "tools/gui/images/reset-icon" ); + %sidebar-->button1.command = "GuiEditor.revertProfile( GuiEditorProfilesTree.getSelectedProfile() );"; + %sidebar-->button1.tooltip = "Revert Changes to the Selected Profile"; + + case "toolboxPage": + + //TODO + + %sidebar-->button1.setVisible( false ); + %sidebar-->button2.setVisible( false ); + %sidebar-->button3.setVisible( false ); + %sidebar-->button4.setVisible( false ); + } +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTabBook::onTabRightClick( %this, %text, %index ) +{ + %name = %this.getObject( %index ).getInternalName(); + + switch$( %name ) + { + case "toolboxPage": + + // Open toolbox popup. + + %popup = GuiEditorTabBookLibraryPopup; + + %currentViewType = GuiEditorToolbox.getViewType(); + switch$( %currentViewType ) + { + case "Alphabetical": + %popup.checkRadioItem( 0, 1, 0 ); + + case "Categorized": + %popup.checkRadioItem( 0, 1, 1 ); + } + + %popup.showPopup( Canvas ); + } +} + +//============================================================================================= +// Toolbar. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorSnapCheckBox::onWake(%this) +{ + %snap = GuiEditor.snap2grid * GuiEditor.snap2gridsize; + %this.setValue( %snap ); + GuiEditor.setSnapToGrid( %snap ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorSnapCheckBox::onAction(%this) +{ + %snap = GuiEditor.snap2gridsize * %this.getValue(); + GuiEditor.snap2grid = %this.getValue(); + GuiEditor.setSnapToGrid(%snap); +} + +//============================================================================================= +// GuiEditorGui. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorGui::onWake( %this ) +{ + GHGuiEditor.setStateOn( 1 ); + + if( !isObject( %this->SelectControlsDlg ) ) + { + %this.add( GuiEditorSelectDlg ); + GuiEditorSelectDlg.setVisible( false ); + } + + // Attach our menus. + + if( isObject( %this.menuGroup ) ) + for( %i = 0; %i < %this.menuGroup.getCount(); %i ++ ) + %this.menuGroup.getObject( %i ).attachToMenuBar(); + + // Read settings. + + %this.initSettings(); + %this.readSettings(); + + // Initialize toolbox. + + if( !GuiEditorToolbox.isInitialized ) + GuiEditorToolbox.initialize(); + + // Set up initial menu toggle states. + + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_EDGESNAP_INDEX, GuiEditor.snapToEdges ); + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_CENTERSNAP_INDEX, GuiEditor.snapToCenters ); + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_GUIDESNAP_INDEX, GuiEditor.snapToGuides ); + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_CONTROLSNAP_INDEX, GuiEditor.snapToControls ); + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_CANVASSNAP_INDEX, GuiEditor.snapToCanvas ); + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_GRIDSNAP_INDEX, GuiEditor.snap2Grid ); + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_DRAWGUIDES_INDEX, GuiEditor.drawGuides ); + GuiEditCanvas.menuBar->EditMenu.checkItem( $GUI_EDITOR_MENU_FULLBOXSELECT_INDEX, GuiEditor.fullBoxSelection ); + + // Sync toolbar buttons. + + GuiEditorSnapCheckBox.setStateOn( GuiEditor.snap2Grid ); + GuiEditorEdgeSnapping_btn.setStateOn( GuiEditor.snapToEdges ); + GuiEditorCenterSnapping_btn.setStateOn( GuiEditor.snapToCenters ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorGui::onSleep( %this) +{ + // If we are editing a control, store its guide state. + + %content = GuiEditor.getContentControl(); + if( isObject( %content ) ) + GuiEditor.writeGuides( %content ); + + // Remove our menus. + + if( isObject( %this.menuGroup ) ) + for( %i = 0; %i < %this.menuGroup.getCount(); %i ++ ) + %this.menuGroup.getObject( %i ).removeFromMenuBar(); + + // Store our preferences. + + %this.writeSettings(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorGui::initSettings( %this ) +{ + EditorSettings.beginGroup( "GuiEditor", true ); + + EditorSettings.setDefaultValue( "lastPath", "" ); + EditorSettings.setDefaultValue( "previewResolution", "1024 768" ); + + EditorSettings.beginGroup( "EngineDevelopment" ); + EditorSettings.setDefaultValue( "toggleIntoEditor", 0 ); + EditorSettings.setDefaultValue( "showEditorProfiles", 0 ); + EditorSettings.setDefaultValue( "showEditorGuis", 0 ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Library" ); + EditorSettings.setDefaultValue( "viewType", "Categorized" ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Snapping" ); + EditorSettings.setDefaultValue( "snapToControls", "1" ); + EditorSettings.setDefaultValue( "snapToGuides", "1" ); + EditorSettings.setDefaultValue( "snapToCanvas", "1" ); + EditorSettings.setDefaultValue( "snapToEdges", "1" ); + EditorSettings.setDefaultValue( "snapToCenters", "1" ); + EditorSettings.setDefaultValue( "sensitivity", "2" ); + EditorSettings.setDefaultValue( "snap2Grid", "0" ); + EditorSettings.setDefaultValue( "snap2GridSize", $GuiEditor::defaultGridSize ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Selection" ); + EditorSettings.setDefaultValue( "fullBox", "0" ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Rendering" ); + EditorSettings.setDefaultValue( "drawBorderLines", "1" ); + EditorSettings.setDefaultValue( "drawGuides", "1" ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Help" ); + EditorSettings.setDefaultValue( "documentationURL", "http://www.garagegames.com/products/torque-3d/documentation/user" ); //RDTODO: make this point to Gui Editor docs when available + + // Create a path to the local documentation. This is a bit of guesswork here. + // It assumes that the project is located in a folder of the SDK root directory + // (e.g. "Examples/" or "Demos/") and that from there the path to the game + // folder is "<project>/game". + EditorSettings.setDefaultValue("documentationLocal", "../../../Documentation/Official Documentation.html" ); + + EditorSettings.setDefaultValue("documentationReference", "../../../Documentation/Torque 3D - Script Manual.chm" ); + + EditorSettings.endGroup(); + + EditorSettings.endGroup(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorGui::readSettings( %this ) +{ + EditorSettings.read(); + + EditorSettings.beginGroup( "GuiEditor", true ); + + GuiEditor.lastPath = EditorSettings.value( "lastPath" ); + GuiEditor.previewResolution = EditorSettings.value( "previewResolution" ); + + EditorSettings.beginGroup( "EngineDevelopment" ); + GuiEditor.toggleIntoEditor = EditorSettings.value( "toggleIntoEditor" ); + GuiEditor.showEditorProfiles = EditorSettings.value( "showEditorProfiles" ); + GuiEditor.showEditorGuis = EditorSettings.value( "showEditorGuis" ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Library" ); + GuiEditorToolbox.currentViewType = EditorSettings.value( "viewType" ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Snapping" ); + GuiEditor.snapToGuides = EditorSettings.value( "snapToGuides" ); + GuiEditor.snapToControls = EditorSettings.value( "snapToControls" ); + GuiEditor.snapToCanvas = EditorSettings.value( "snapToCanvas" ); + GuiEditor.snapToEdges = EditorSettings.value( "snapToEdges" ); + GuiEditor.snapToCenters = EditorSettings.value( "snapToCenters" ); + GuiEditor.snapSensitivity = EditorSettings.value( "sensitivity" ); + GuiEditor.snap2Grid = EditorSettings.value( "snap2Grid" ); + GuiEditor.snap2GridSize = EditorSettings.value( "snap2GridSize" ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Selection" ); + GuiEditor.fullBoxSelection = EditorSettings.value( "fullBox" ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Rendering" ); + GuiEditor.drawBorderLines = EditorSettings.value( "drawBorderLines" ); + GuiEditor.drawGuides = EditorSettings.value( "drawGuides" ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Help" ); + GuiEditor.documentationURL = EditorSettings.value( "documentationURL" ); + GuiEditor.documentationLocal = EditorSettings.value( "documentationLocal" ); + GuiEditor.documentationReference = EditorSettings.value( "documentationReference" ); + EditorSettings.endGroup(); + + EditorSettings.endGroup(); + + if( GuiEditor.snap2Grid ) + GuiEditor.setSnapToGrid( GuiEditor.snap2GridSize ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorGui::writeSettings( %this ) +{ + EditorSettings.beginGroup( "GuiEditor", true ); + + EditorSettings.setValue( "lastPath", GuiEditor.lastPath ); + EditorSettings.setValue( "previewResolution", GuiEditor.previewResolution ); + + EditorSettings.beginGroup( "EngineDevelopment" ); + EditorSettings.setValue( "toggleIntoEditor", GuiEditor.toggleIntoEditor ); + EditorSettings.setValue( "showEditorProfiles", GuiEditor.showEditorProfiles ); + EditorSettings.setValue( "showEditorGuis", GuiEditor.showEditorGuis ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Library" ); + EditorSettings.setValue( "viewType", GuiEditorToolbox.currentViewType ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Snapping" ); + EditorSettings.setValue( "snapToControls", GuiEditor.snapToControls ); + EditorSettings.setValue( "snapToGuides", GuiEditor.snapToGuides ); + EditorSettings.setValue( "snapToCanvas", GuiEditor.snapToCanvas ); + EditorSettings.setValue( "snapToEdges", GuiEditor.snapToEdges ); + EditorSettings.setValue( "snapToCenters", GuiEditor.snapToCenters ); + EditorSettings.setValue( "sensitivity", GuiEditor.snapSensitivity ); + EditorSettings.setValue( "snap2Grid", GuiEditor.snap2Grid ); + EditorSettings.setValue( "snap2GridSize", GuiEditor.snap2GridSize ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Selection" ); + EditorSettings.setValue( "fullBox", GuiEditor.fullBoxSelection ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Rendering" ); + EditorSettings.setValue( "drawBorderLines", GuiEditor.drawBorderLines ); + EditorSettings.setValue( "drawGuides", GuiEditor.drawGuides ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Help" ); + EditorSettings.setValue( "documentationURL", GuiEditor.documentationURL ); + EditorSettings.setValue( "documentationLocal", GuiEditor.documentationLocal ); + EditorSettings.setValue( "documentationReference", GuiEditor.documentationReference ); + EditorSettings.endGroup(); + + EditorSettings.endGroup(); + + EditorSettings.write(); +} diff --git a/Templates/Empty/game/tools/guiEditor/scripts/guiEditorCanvas.ed.cs b/Templates/Empty/game/tools/guiEditor/scripts/guiEditorCanvas.ed.cs new file mode 100644 index 000000000..1305ae170 --- /dev/null +++ b/Templates/Empty/game/tools/guiEditor/scripts/guiEditorCanvas.ed.cs @@ -0,0 +1,540 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +//============================================================================================= +// Event Handlers. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditCanvas::onAdd( %this ) +{ + // %this.setWindowTitle("Torque Gui Editor"); + + %this.onCreateMenu(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditCanvas::onRemove( %this ) +{ + if( isObject( GuiEditorGui.menuGroup ) ) + GuiEditorGui.delete(); + + // cleanup + %this.onDestroyMenu(); +} + +//--------------------------------------------------------------------------------------------- + +/// Create the Gui Editor menu bar. +function GuiEditCanvas::onCreateMenu(%this) +{ + if(isObject(%this.menuBar)) + return; + + //set up %cmdctrl variable so that it matches OS standards + if( $platform $= "macos" ) + { + %cmdCtrl = "cmd"; + %redoShortcut = "Cmd-Shift Z"; + } + else + { + %cmdCtrl = "Ctrl"; + %redoShort = "Ctrl Y"; + } + + // Menu bar + %this.menuBar = new MenuBar() + { + dynamicItemInsertPos = 3; + + new PopupMenu() + { + superClass = "MenuBuilder"; + barTitle = "File"; + internalName = "FileMenu"; + + item[0] = "New Gui..." TAB %cmdCtrl SPC "N" TAB %this @ ".create();"; + item[1] = "Open..." TAB %cmdCtrl SPC "O" TAB %this @ ".open();"; + item[2] = "Save" TAB %cmdCtrl SPC "S" TAB %this @ ".save( false, true );"; + item[3] = "Save As..." TAB %cmdCtrl @ "-Shift S" TAB %this @ ".save( false );"; + item[4] = "Save Selected As..." TAB %cmdCtrl @ "-Alt S" TAB %this @ ".save( true );"; + item[5] = "-"; + item[6] = "Revert Gui" TAB "" TAB %this @ ".revert();"; + item[7] = "Add Gui From File..." TAB "" TAB %this @ ".append();"; + item[8] = "-"; + item[9] = "Open Gui File in Torsion" TAB "" TAB %this @".openInTorsion();"; + item[10] = "-"; + item[11] = "Close Editor" TAB "F10" TAB %this @ ".quit();"; + item[12] = "Quit" TAB %cmdCtrl SPC "Q" TAB "quit();"; + }; + + new PopupMenu() + { + superClass = "MenuBuilder"; + barTitle = "Edit"; + internalName = "EditMenu"; + + item[0] = "Undo" TAB %cmdCtrl SPC "Z" TAB "GuiEditor.undo();"; + item[1] = "Redo" TAB %redoShortcut TAB "GuiEditor.redo();"; + item[2] = "-"; + item[3] = "Cut" TAB %cmdCtrl SPC "X" TAB "GuiEditor.saveSelection(); GuiEditor.deleteSelection();"; + item[4] = "Copy" TAB %cmdCtrl SPC "C" TAB "GuiEditor.saveSelection();"; + item[5] = "Paste" TAB %cmdCtrl SPC "V" TAB "GuiEditor.loadSelection();"; + item[6] = "-"; + item[7] = "Select All" TAB %cmdCtrl SPC "A" TAB "GuiEditor.selectAll();"; + item[8] = "Deselect All" TAB %cmdCtrl SPC "D" TAB "GuiEditor.clearSelection();"; + item[9] = "Select Parent(s)" TAB %cmdCtrl @ "-Alt Up" TAB "GuiEditor.selectParents();"; + item[10] = "Select Children" TAB %cmdCtrl @ "-Alt Down" TAB "GuiEditor.selectChildren();"; + item[11] = "Add Parent(s) to Selection" TAB %cmdCtrl @ "-Alt-Shift Up" TAB "GuiEditor.selectParents( true );"; + item[12] = "Add Children to Selection" TAB %cmdCtrl @ "-Alt-Shift Down" TAB "GuiEditor.selectChildren( true );"; + item[13] = "Select..." TAB "" TAB "GuiEditorSelectDlg.toggleVisibility();"; + item[14] = "-"; + item[15] = "Lock/Unlock Selection" TAB %cmdCtrl SPC "L" TAB "GuiEditor.toggleLockSelection();"; + item[16] = "Hide/Unhide Selection" TAB %cmdCtrl SPC "H" TAB "GuiEditor.toggleHideSelection();"; + item[17] = "-"; + item[18] = "Group Selection" TAB %cmdCtrl SPC "G" TAB "GuiEditor.groupSelected();"; + item[19] = "Ungroup Selection" TAB %cmdCtrl @ "-Shift G" TAB "GuiEditor.ungroupSelected();"; + item[20] = "-"; + item[21] = "Full Box Selection" TAB "" TAB "GuiEditor.toggleFullBoxSelection();"; + item[22] = "-"; + item[23] = "Grid Size" TAB %cmdCtrl SPC "," TAB "GuiEditor.showPrefsDialog();"; + }; + + new PopupMenu() + { + superClass = "MenuBuilder"; + barTitle = "Layout"; + internalName = "LayoutMenu"; + + item[0] = "Align Left" TAB %cmdCtrl SPC "Left" TAB "GuiEditor.Justify(0);"; + item[1] = "Center Horizontally" TAB "" TAB "GuiEditor.Justify(1);"; + item[2] = "Align Right" TAB %cmdCtrl SPC "Right" TAB "GuiEditor.Justify(2);"; + item[3] = "-"; + item[4] = "Align Top" TAB %cmdCtrl SPC "Up" TAB "GuiEditor.Justify(3);"; + item[5] = "Center Vertically" TAB "" TAB "GuiEditor.Justify(7);"; + item[6] = "Align Bottom" TAB %cmdCtrl SPC "Down" TAB "GuiEditor.Justify(4);"; + item[7] = "-"; + item[8] = "Space Vertically" TAB "" TAB "GuiEditor.Justify(5);"; + item[9] = "Space Horizontally" TAB "" TAB "GuiEditor.Justify(6);"; + item[10] = "-"; + item[11] = "Fit into Parent(s)" TAB "" TAB "GuiEditor.fitIntoParents();"; + item[12] = "Fit Width to Parent(s)" TAB "" TAB "GuiEditor.fitIntoParents( true, false );"; + item[13] = "Fit Height to Parent(s)" TAB "" TAB "GuiEditor.fitIntoParents( false, true );"; + item[14] = "-"; + item[15] = "Bring to Front" TAB "" TAB "GuiEditor.BringToFront();"; + item[16] = "Send to Back" TAB "" TAB "GuiEditor.PushToBack();"; + }; + + new PopupMenu() + { + superClass = "MenuBuilder"; + barTitle = "Move"; + internalName = "MoveMenu"; + + item[0] = "Nudge Left" TAB "Left" TAB "GuiEditor.moveSelection( -1, 0);"; + item[1] = "Nudge Right" TAB "Right" TAB "GuiEditor.moveSelection( 1, 0);"; + item[2] = "Nudge Up" TAB "Up" TAB "GuiEditor.moveSelection( 0, -1);"; + item[3] = "Nudge Down" TAB "Down" TAB "GuiEditor.moveSelection( 0, 1 );"; + item[4] = "-"; + item[5] = "Big Nudge Left" TAB "Shift Left" TAB "GuiEditor.moveSelection( - GuiEditor.snap2gridsize, 0 );"; + item[6] = "Big Nudge Right" TAB "Shift Right" TAB "GuiEditor.moveSelection( GuiEditor.snap2gridsize, 0 );"; + item[7] = "Big Nudge Up" TAB "Shift Up" TAB "GuiEditor.moveSelection( 0, - GuiEditor.snap2gridsize );"; + item[8] = "Big Nudge Down" TAB "Shift Down" TAB "GuiEditor.moveSelection( 0, GuiEditor.snap2gridsize );"; + }; + + new PopupMenu() + { + superClass = "MenuBuilder"; + barTitle = "Snap"; + internalName = "SnapMenu"; + + item[0] = "Snap Edges" TAB "Alt-Shift E" TAB "GuiEditor.toggleEdgeSnap();"; + item[1] = "Snap Centers" TAB "Alt-Shift C" TAB "GuiEditor.toggleCenterSnap();"; + item[2] = "-"; + item[3] = "Snap to Guides" TAB "Alt-Shift G" TAB "GuiEditor.toggleGuideSnap();"; + item[4] = "Snap to Controls" TAB "Alt-Shift T" TAB "GuiEditor.toggleControlSnap();"; + item[5] = "Snap to Canvas" TAB "" TAB "GuiEditor.toggleCanvasSnap();"; + item[6] = "Snap to Grid" TAB "" TAB "GuiEditor.toggleGridSnap();"; + item[7] = "-"; + item[8] = "Show Guides" TAB "" TAB "GuiEditor.toggleDrawGuides();"; + item[9] = "Clear Guides" TAB "" TAB "GuiEditor.clearGuides();"; + }; + + new PopupMenu() + { + superClass = "MenuBuilder"; + internalName = "HelpMenu"; + + barTitle = "Help"; + + item[0] = "Online Documentation..." TAB "Alt F1" TAB "gotoWebPage( GuiEditor.documentationURL );"; + item[1] = "Offline User Guid..." TAB "" TAB "gotoWebPage( GuiEditor.documentationLocal );"; + item[2] = "Offline Reference Guide..." TAB "" TAB "shellExecute( GuiEditor.documentationReference );"; + item[3] = "-"; + item[4] = "Torque 3D Public Forums..." TAB "" TAB "gotoWebPage( \"http://www.garagegames.com/community/forums/73\" );"; + item[5] = "Torque 3D Private Forums..." TAB "" TAB "gotoWebPage( \"http://www.garagegames.com/community/forums/63\" );"; + }; + }; + %this.menuBar.attachToCanvas( Canvas, 0 ); +} + +$GUI_EDITOR_MENU_EDGESNAP_INDEX = 0; +$GUI_EDITOR_MENU_CENTERSNAP_INDEX = 1; +$GUI_EDITOR_MENU_GUIDESNAP_INDEX = 3; +$GUI_EDITOR_MENU_CONTROLSNAP_INDEX = 4; +$GUI_EDITOR_MENU_CANVASSNAP_INDEX = 5; +$GUI_EDITOR_MENU_GRIDSNAP_INDEX = 6; +$GUI_EDITOR_MENU_DRAWGUIDES_INDEX = 8; +$GUI_EDITOR_MENU_FULLBOXSELECT_INDEX = 21; + +//--------------------------------------------------------------------------------------------- + +/// Called before onSleep when the canvas content is changed +function GuiEditCanvas::onDestroyMenu(%this) +{ + if( !isObject( %this.menuBar ) ) + return; + + // Destroy menus + while( %this.menuBar.getCount() != 0 ) + %this.menuBar.getObject( 0 ).delete(); + + %this.menuBar.removeFromCanvas(); + %this.menuBar.delete(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditCanvas::onWindowClose(%this) +{ + %this.quit(); +} + +//============================================================================================= +// Menu Commands. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditCanvas::create( %this ) +{ + GuiEditorNewGuiDialog.init( "NewGui", "GuiControl" ); + + Canvas.pushDialog( GuiEditorNewGuiDialog ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditCanvas::load( %this, %filename ) +{ + %newRedefineBehavior = "replaceExisting"; + if( isDefined( "$GuiEditor::loadRedefineBehavior" ) ) + { + // This trick allows to choose different redefineBehaviors when loading + // GUIs. This is useful, for example, when loading GUIs that would lead to + // problems when loading with their correct names because script behavior + // would immediately attach. + // + // This allows to also edit the GUI editor's own GUI inside itself. + + %newRedefineBehavior = $GuiEditor::loadRedefineBehavior; + } + + // Allow stomping objects while exec'ing the GUI file as we want to + // pull the file's objects even if we have another version of the GUI + // already loaded. + + %oldRedefineBehavior = $Con::redefineBehavior; + $Con::redefineBehavior = %newRedefineBehavior; + + // Load up the gui. + exec( %fileName ); + + $Con::redefineBehavior = %oldRedefineBehavior; + + // The GUI file should have contained a GUIControl which should now be in the instant + // group. And, it should be the only thing in the group. + if( !isObject( %guiContent ) ) + { + MessageBox( getEngineName(), + "You have loaded a Gui file that was created before this version. It has been loaded but you must open it manually from the content list dropdown", + "Ok", "Information" ); + return 0; + } + + GuiEditor.openForEditing( %guiContent ); + + GuiEditorStatusBar.print( "Loaded '" @ %filename @ "'" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditCanvas::openInTorsion( %this ) +{ + if( !GuiEditorContent.getCount() ) + return; + + %guiObject = GuiEditorContent.getObject( 0 ); + EditorOpenDeclarationInTorsion( %guiObject ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditCanvas::open( %this ) +{ + %openFileName = GuiBuilder::getOpenName(); + if( %openFileName $= "" ) + return; + + // Make sure the file is valid. + if ((!isFile(%openFileName)) && (!isFile(%openFileName @ ".dso"))) + return; + + %this.load( %openFileName ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditCanvas::save( %this, %selectedOnly, %noPrompt ) +{ + // Get the control we should save. + + if( %selectedOnly ) + { + %selected = GuiEditor.getSelection(); + if( !%selected.getCount() ) + return; + else if( %selected.getCount() > 1 ) + { + MessageBox( "Invalid selection", "Only a single control hierarchy can be saved to a file. Make sure you have selected only one control in the tree view." ); + return; + } + + %currentObject = %selected.getObject( 0 ); + } + else if( GuiEditorContent.getCount() > 0 ) + %currentObject = GuiEditorContent.getObject( 0 ); + else + return; + + // Store the current guide set on the control. + + GuiEditor.writeGuides( %currentObject ); + %currentObject.canSaveDynamicFields = true; // Make sure the guides get saved out. + + // Construct a base filename. + + if( %currentObject.getName() !$= "" ) + %name = %currentObject.getName() @ ".gui"; + else + %name = "Untitled.gui"; + + // Construct a path. + + if( %selectedOnly + && %currentObject != GuiEditorContent.getObject( 0 ) + && %currentObject.getFileName() $= GuiEditorContent.getObject( 0 ).getFileName() ) + { + // Selected child control that hasn't been yet saved to its own file. + + %currentFile = GuiEditor.LastPath @ "/" @ %name; + %currentFile = makeRelativePath( %currentFile, getMainDotCsDir() ); + } + else + { + %currentFile = %currentObject.getFileName(); + if( %currentFile $= "") + { + // No file name set on control. Force a prompt. + %noPrompt = false; + + if( GuiEditor.LastPath !$= "" ) + { + %currentFile = GuiEditor.LastPath @ "/" @ %name; + %currentFile = makeRelativePath( %currentFile, getMainDotCsDir() ); + } + else + %currentFile = expandFileName( %name ); + } + else + %currentFile = expandFileName( %currentFile ); + } + + // Get the filename. + + if( !%noPrompt ) + { + %filename = GuiBuilder::getSaveName( %currentFile ); + if( %filename $= "" ) + return; + } + else + %filename = %currentFile; + + // Save the Gui. + + if( isWriteableFileName( %filename ) ) + { + // + // Extract any existent TorqueScript before writing out to disk + // + %fileObject = new FileObject(); + %fileObject.openForRead( %filename ); + %skipLines = true; + %beforeObject = true; + // %var++ does not post-increment %var, in torquescript, it pre-increments it, + // because ++%var is illegal. + %lines = -1; + %beforeLines = -1; + %skipLines = false; + while( !%fileObject.isEOF() ) + { + %line = %fileObject.readLine(); + if( %line $= "//--- OBJECT WRITE BEGIN ---" ) + %skipLines = true; + else if( %line $= "//--- OBJECT WRITE END ---" ) + { + %skipLines = false; + %beforeObject = false; + } + else if( %skipLines == false ) + { + if(%beforeObject) + %beforeNewFileLines[ %beforeLines++ ] = %line; + else + %newFileLines[ %lines++ ] = %line; + } + } + %fileObject.close(); + %fileObject.delete(); + + %fo = new FileObject(); + %fo.openForWrite(%filename); + + // Write out the captured TorqueScript that was before the object before the object + for( %i = 0; %i <= %beforeLines; %i++) + %fo.writeLine( %beforeNewFileLines[ %i ] ); + + %fo.writeLine("//--- OBJECT WRITE BEGIN ---"); + %fo.writeObject(%currentObject, "%guiContent = "); + %fo.writeLine("//--- OBJECT WRITE END ---"); + + // Write out captured TorqueScript below Gui object + for( %i = 0; %i <= %lines; %i++ ) + %fo.writeLine( %newFileLines[ %i ] ); + + %fo.close(); + %fo.delete(); + + %currentObject.setFileName( makeRelativePath( %filename, getMainDotCsDir() ) ); + + GuiEditorStatusBar.print( "Saved file '" @ %currentObject.getFileName() @ "'" ); + } + else + MessageBox( "Error writing to file", "There was an error writing to file '" @ %currentFile @ "'. The file may be read-only.", "Ok", "Error" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditCanvas::append( %this ) +{ + // Get filename. + + %openFileName = GuiBuilder::getOpenName(); + if( %openFileName $= "" + || ( !isFile( %openFileName ) + && !isFile( %openFileName @ ".dso" ) ) ) + return; + + // Exec file. + + %oldRedefineBehavior = $Con::redefineBehavior; + $Con::redefineBehavior = "renameNew"; + exec( %openFileName ); + $Con::redefineBehavior = %oldRedefineBehavior; + + // Find guiContent. + + if( !isObject( %guiContent ) ) + { + MessageBox( "Error loading GUI file", "The GUI content controls could not be found. This function can only be used with files saved by the GUI editor.", "Ok", "Error" ); + return; + } + + if( !GuiEditorContent.getCount() ) + GuiEditor.openForEditing( %guiContent ); + else + { + GuiEditor.getCurrentAddSet().add( %guiContent ); + GuiEditor.readGuides( %guiContent ); + GuiEditor.onAddNewCtrl( %guiContent ); + GuiEditor.onHierarchyChanged(); + } + + GuiEditorStatusBar.print( "Appended controls from '" @ %openFileName @ "'" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditCanvas::revert( %this ) +{ + if( !GuiEditorContent.getCount() ) + return; + + %gui = GuiEditorContent.getObject( 0 ); + %filename = %gui.getFileName(); + if( %filename $= "" ) + return; + + if( MessageBox( "Revert Gui", "Really revert the current Gui? This cannot be undone.", "OkCancel", "Question" ) == $MROk ) + %this.load( %filename ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditCanvas::close( %this ) +{ +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditCanvas::quit( %this ) +{ + %this.close(); + GuiGroup.add(GuiEditorGui); + // we must not delete a window while in its event handler, or we foul the event dispatch mechanism + %this.schedule(10, delete); + + Canvas.setContent(GuiEditor.lastContent); + $InGuiEditor = false; + + //Temp fix to disable MLAA when in GUI editor + if( isObject(MLAAFx) && $MLAAFxGuiEditorTemp==true ) + { + MLAAFx.isEnabled = true; + $MLAAFxGuiEditorTemp = false; + } +} diff --git a/Templates/Empty/game/tools/guiEditor/scripts/guiEditorContentList.ed.cs b/Templates/Empty/game/tools/guiEditor/scripts/guiEditorContentList.ed.cs new file mode 100644 index 000000000..8a946a2a2 --- /dev/null +++ b/Templates/Empty/game/tools/guiEditor/scripts/guiEditorContentList.ed.cs @@ -0,0 +1,102 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Code for the drop-down that allows selecting a GUI to edit in the Gui Editor. + + +if( !isDefined( "$GuiEditor::GuiFilterList" ) ) +{ + /// List of named controls that are filtered out from the + /// control list dropdown. + $GuiEditor::GuiFilterList = + "GuiEditorGui" TAB + "AL_ShadowVizOverlayCtrl" TAB + "MessageBoxOKDlg" TAB + "MessageBoxOKCancelDlg" TAB + "MessageBoxOKCancelDetailsDlg" TAB + "MessageBoxYesNoDlg" TAB + "MessageBoxYesNoCancelDlg" TAB + "MessagePopupDlg"; +} + + +//--------------------------------------------------------------------------------------------- + +function GuiEditorContentList::init( %this ) +{ + %this.clear(); + %this.scanGroup( GuiGroup ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorContentList::scanGroup( %this, %group ) +{ + foreach( %obj in %group ) + { + if( %obj.isMemberOfClass( "GuiControl" ) ) + { + if(%obj.getClassName() $= "GuiCanvas") + { + %this.scanGroup( %obj ); + } + else + { + if(%obj.getName() $= "") + %name = "(unnamed) - " @ %obj; + else + %name = %obj.getName() @ " - " @ %obj; + + %skip = false; + + foreach$( %guiEntry in $GuiEditor::GuiFilterList ) + if( %obj.getName() $= %guiEntry ) + { + %skip = true; + break; + } + + if( !%skip ) + %this.add( %name, %obj ); + } + } + else if( %obj.isMemberOfClass( "SimGroup" ) + && ( %obj.internalName !$= "EditorGuiGroup" // Don't put our editor's GUIs in the list + || GuiEditor.showEditorGuis ) ) // except if explicitly requested. + { + // Scan nested SimGroups for GuiControls. + + %this.scanGroup( %obj ); + } + } +} + +//============================================================================================= +// Event Handlers. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorContentList::onSelect( %this, %ctrl ) +{ + GuiEditor.openForEditing( %ctrl ); +} diff --git a/Templates/Empty/game/tools/guiEditor/scripts/guiEditorGroup.ed.cs b/Templates/Empty/game/tools/guiEditor/scripts/guiEditorGroup.ed.cs new file mode 100644 index 000000000..558aa7763 --- /dev/null +++ b/Templates/Empty/game/tools/guiEditor/scripts/guiEditorGroup.ed.cs @@ -0,0 +1,149 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +// GuiEditorGroups are recorded only for undo/redo. They are ScriptObjects +// containing all the information about a particular GUIControl group. +// +// The properties of GuiEditorGroups are: +// +// int count - Number of controls in group. +// object ctrl[ 0 .. count ] - Controls in group. +// object ctrlParent[ 0 .. count ] - Original parent of each control in group (if missing, controls are moved to parent of group object in ungroup()) +// object groupObject - The GuiControl group object. +// object groupParent - The object to which the group should be parented to. + + +/// Return the combined global bounds of the controls contained in the GuiEditorGroup. +function GuiEditorGroup::getGlobalBounds( %this ) +{ + %minX = 2147483647; + %minY = 2147483647; + %maxX = -2147483647; + %maxY = -2147483647; + + for( %i = 0; %i < %this.count; %i ++ ) + { + %ctrl = %this.ctrl[ %i ]; + + %pos = %ctrl.getGlobalPosition(); + %extent = %ctrl.getExtent(); + + // Min. + + %posX = getWord( %pos, 0 ); + %posY = getWord( %pos, 1 ); + + if( %posX < %minX ) + %minX = %posX; + if( %posY < %minY ) + %minY = %posY; + + // Max. + + %posX += getWord( %extent, 0 ); + %posY += getWord( %extent, 1 ); + + if( %posX > %maxX ) + %maxX = %posX; + if( %posY > %maxY ) + %maxY = %posY; + } + + return ( %minX SPC %minY SPC ( %maxX - %minX ) SPC ( %maxY - %minY ) ); +} + +/// Create a new GuiControl and move all the controls contained in the GuiEditorGroup into it. +function GuiEditorGroup::group( %this ) +{ + %parent = %this.groupParent; + + // Create group. + + %group = new GuiControl(); + %parent.addGuiControl( %group ); + %this.groupObject = %group; + + // Make group fit around selection. + + %bounds = %this.getGlobalBounds(); + %parentGlobalPos = %parent.getGlobalPosition(); + + %x = getWord( %bounds, 0 ) - getWord( %parentGlobalPos, 0 ); + %y = getWord( %bounds, 1 ) - getWord( %parentGlobalPos, 1 ); + + %group.setPosition( %x, %y ); + %group.setExtent( getWord( %bounds, 2 ), getWord( %bounds, 3 ) ); + + // Reparent all objects to group. + + for( %i = 0; %i < %this.count; %i ++ ) + { + %ctrl = %this.ctrl[ %i ]; + + // Save parent for undo. + + %this.ctrlParent[ %i ] = %ctrl.parentGroup; + + // Reparent. + + %group.addGuiControl( %ctrl ); + + // Move into place in new parent. + + %pos = %ctrl.getPosition(); + %ctrl.setPosition( getWord( %pos, 0 ) - %x, getWord( %pos, 1 ) - %y ); + } +} + +/// Move all controls out of group to either former parent or group parent. +function GuiEditorGroup::ungroup( %this ) +{ + %defaultParent = %this.groupParent; + %groupPos = %this.groupObject.getPosition(); + + %x = getWord( %groupPos, 0 ); + %y = getWord( %groupPos, 1 ); + + // Move each control to its former parent (or default parent when + // there is no former parent). + + for( %i = 0; %i < %this.count; %i ++ ) + { + %ctrl = %this.ctrl[ %i ]; + + %parent = %defaultParent; + if( isObject( %this.ctrlParent[ %i ] ) ) + %parent = %this.ctrlParent[ %i ]; + + %parent.addGuiControl( %ctrl ); + + // Move into place in new parent. + + %ctrlPos = %ctrl.getPosition(); + %ctrl.setPosition( getWord( %ctrlPos, 0 ) + %x, getWord( %ctrlPos, 1 ) + %y ); + } + + // Delete old group object. + + %this.groupObject.delete(); +} diff --git a/Templates/Empty/game/tools/guiEditor/scripts/guiEditorInspector.ed.cs b/Templates/Empty/game/tools/guiEditor/scripts/guiEditorInspector.ed.cs new file mode 100644 index 000000000..fafc0a7c2 --- /dev/null +++ b/Templates/Empty/game/tools/guiEditor/scripts/guiEditorInspector.ed.cs @@ -0,0 +1,172 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Core for the main Gui Editor inspector that shows the properties of +// the currently selected control. + + +//--------------------------------------------------------------------------------------------- + +function GuiEditorInspectFields::update( %this, %inspectTarget ) +{ + %this.inspect( %inspectTarget ); +} + +//============================================================================================= +// Event Handlers. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorInspectFields::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ) +{ + // The instant group will try to add our + // UndoAction if we don't disable it. + pushInstantGroup(); + + %nameOrClass = %object.getName(); + if ( %nameOrClass $= "" ) + %nameOrClass = %object.getClassname(); + + %action = new InspectorFieldUndoAction() + { + actionName = %nameOrClass @ "." @ %fieldName @ " Change"; + + objectId = %object.getId(); + fieldName = %fieldName; + fieldValue = %oldValue; + arrayIndex = %arrayIndex; + + inspectorGui = %this; + }; + + // Restore the instant group. + popInstantGroup(); + + %action.addToManager( GuiEditor.getUndoManager() ); + + GuiEditor.updateUndoMenu(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorInspectFields::onInspectorPreFieldModification( %this, %fieldName, %arrayIndex ) +{ + pushInstantGroup(); + %undoManager = GuiEditor.getUndoManager(); + + %numObjects = %this.getNumInspectObjects(); + if( %numObjects > 1 ) + %action = %undoManager.pushCompound( "Multiple Field Edit" ); + + for( %i = 0; %i < %numObjects; %i ++ ) + { + %object = %this.getInspectObject( %i ); + + %nameOrClass = %object.getName(); + if( %nameOrClass $= "" ) + %nameOrClass = %object.getClassname(); + + %undo = new InspectorFieldUndoAction() + { + actionName = %nameOrClass @ "." @ %fieldName @ " Change"; + + objectId = %object.getId(); + fieldName = %fieldName; + fieldValue = %object.getFieldValue( %fieldName, %arrayIndex ); + arrayIndex = %arrayIndex; + + inspectorGui = %this; + }; + + if( %numObjects > 1 ) + %undo.addToManager( %undoManager ); + else + { + %action = %undo; + break; + } + } + + %this.currentFieldEditAction = %action; + popInstantGroup(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorInspectFields::onInspectorPostFieldModification( %this ) +{ + if( %this.currentFieldEditAction.isMemberOfClass( "CompoundUndoAction" ) ) + { + // Finish multiple field edit. + GuiEditor.getUndoManager().popCompound(); + } + else + { + // Queue single field undo. + %this.currentFieldEditAction.addToManager( GuiEditor.getUndoManager() ); + } + + %this.currentFieldEditAction = ""; + GuiEditor.updateUndoMenu(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorInspectFields::onInspectorDiscardFieldModification( %this ) +{ + %this.currentFieldEditAction.undo(); + + if( %this.currentFieldEditAction.isMemberOfClass( "CompoundUndoAction" ) ) + { + // Multiple field editor. Pop and discard. + GuiEditor.getUndoManager().popCompound( true ); + } + else + { + // Single field edit. Just kill undo action. + %this.currentFieldEditAction.delete(); + } + + %this.currentFieldEditAction = ""; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorInspectFields::onFieldSelected( %this, %fieldName, %fieldTypeStr, %fieldDoc ) +{ + GuiEditorFieldInfo.setText( "<font:ArialBold:14>" @ %fieldName @ "<font:ArialItalic:14> (" @ %fieldTypeStr @ ") " NL "<font:Arial:14>" @ %fieldDoc ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorInspectFields::onBeginCompoundEdit( %this ) +{ + GuiEditor.getUndoManager().pushCompound( "Multiple Field Edits" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorInspectFields::onEndCompoundEdit( %this ) +{ + GuiEditor.getUndoManager().popCompound(); +} diff --git a/Templates/Empty/game/tools/guiEditor/scripts/guiEditorNewGuiDialog.ed.cs b/Templates/Empty/game/tools/guiEditor/scripts/guiEditorNewGuiDialog.ed.cs new file mode 100644 index 000000000..248c0e97d --- /dev/null +++ b/Templates/Empty/game/tools/guiEditor/scripts/guiEditorNewGuiDialog.ed.cs @@ -0,0 +1,107 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Dialog for creating new GUIs. Allows to enter an object name and +// select a GuiControl class to use for the toplevel object. + + +//--------------------------------------------------------------------------------------------- + +function GuiEditorNewGuiDialog::init( %this, %guiName, %guiClass ) +{ + %this-->nameField.setValue( %guiName ); + + // Initialize the class dropdown if we haven't already. + + %classDropdown = %this-->classDropdown; + if( !%classDropdown.size() ) + { + %classes = enumerateConsoleClassesByCategory( "Gui" ); + %count = getFieldCount( %classes ); + + for( %i = 0; %i < %count; %i ++ ) + { + %className = getField( %classes, %i ); + if( GuiEditor.isFilteredClass( %className ) + || !isMemberOfClass( %className, "GuiControl" ) ) + continue; + + %classDropdown.add( %className, 0 ); + } + + %classDropdown.sort(); + } + + %classDropdown.setText( "GuiControl" ); +} + +//============================================================================================= +// Event Handlers. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorNewGuiDialog::onWake( %this ) +{ + // Center the dialog. + + %root = %this.getRoot(); + %this.setPosition( %root.extent.x / 2 - %this.extent.x / 2, %root.extent.y / 2 - %this.extent.y / 2 ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorNewGuiDialog::onOK( %this ) +{ + %name = %this-->nameField.getValue(); + %class = %this-->classDropdown.getText(); + + // Make sure we don't clash with an existing object. + // If there's an existing GUIControl with the name, ask to replace. + // If there's an existing non-GUIControl with the name, or the name is invalid, refuse to create. + + if( isObject( %name ) && %name.isMemberOfClass( "GuiControl" ) ) + { + if( MessageBox( "Warning", "Replace the existing control '" @ %name @ "'?", "OkCancel", "Question" ) == $MROk ) + %name.delete(); + else + return; + } + + if( Editor::validateObjectName( %name, false ) ) + { + %this.getRoot().popDialog( %this ); + %obj = eval("return new " @ %class @ "(" @ %name @ ");"); + + // Make sure we have no association with a filename. + %obj.setFileName( "" ); + + GuiEditContent(%obj); + } +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorNewGuiDialog::onCancel( %this ) +{ + %this.getRoot().popDialog( %this ); +} diff --git a/Templates/Empty/game/tools/guiEditor/scripts/guiEditorPrefsDlg.ed.cs b/Templates/Empty/game/tools/guiEditor/scripts/guiEditorPrefsDlg.ed.cs new file mode 100644 index 000000000..c4713fc4e --- /dev/null +++ b/Templates/Empty/game/tools/guiEditor/scripts/guiEditorPrefsDlg.ed.cs @@ -0,0 +1,85 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +$GuiEditor::defaultGridSize = 8; +$GuiEditor::minGridSize = 3; + +//----------------------------------------------------------------------------------------- +// Buttons +//----------------------------------------------------------------------------------------- + +function GuiEditorPrefsDlgOkBtn::onAction(%this) +{ + GuiEditor.snap2gridsize = GuiEditorPrefsDlgGridEdit.getValue(); + if( GuiEditor.snap2grid ) + GuiEditor.setSnapToGrid( GuiEditor.snap2gridsize ); + + Canvas.popDialog( GuiEditorPrefsDlg ); +} + +function GuiEditorPrefsDlgCancelBtn::onAction(%this) +{ + Canvas.popDialog( GuiEditorPrefsDlg ); +} + +function GuiEditorPrefsDlgDefaultsBtn::onAction(%this) +{ + GuiEditorPrefsDlgGridSlider.setValue( $GuiEditor::defaultGridSize ); +} + +//----------------------------------------------------------------------------------------- +// Grid +//----------------------------------------------------------------------------------------- + +function GuiEditorPrefsDlgGridEdit::onWake(%this) +{ + %this.setValue( GuiEditor.snap2gridsize ); +} + +function GuiEditorPrefsDlgGridEdit::onAction( %this ) +{ + %value = %this.getValue(); + if( %value < $GuiEditor::minGridSize ) + { + %value = $GuiEditor::minGridSize; + %this.setValue( %value ); + } + + GuiEditorPrefsDlgGridSlider.setValue( %value ); +} + +function GuiEditorPrefsDlgGridSlider::onWake(%this) +{ + %this.setValue( GuiEditor.snap2gridsize ); +} + +function GuiEditorPrefsDlgGridSlider::onAction(%this) +{ + %value = %this.value; + if( %value < $GuiEditor::minGridSize ) + { + %value = $GuiEditor::minGridSize; + %this.setValue( %value ); + } + + GuiEditorPrefsDlgGridEdit.setvalue( mCeil( %value ) ); +} diff --git a/Templates/Empty/game/tools/guiEditor/scripts/guiEditorProfiles.ed.cs b/Templates/Empty/game/tools/guiEditor/scripts/guiEditorProfiles.ed.cs new file mode 100644 index 000000000..997512b37 --- /dev/null +++ b/Templates/Empty/game/tools/guiEditor/scripts/guiEditorProfiles.ed.cs @@ -0,0 +1,623 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +$GUI_EDITOR_DEFAULT_PROFILE_FILENAME = "art/gui/customProfiles.cs"; +$GUI_EDITOR_DEFAULT_PROFILE_CATEGORY = "Other"; + + + +//============================================================================================= +// GuiEditor. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::createNewProfile( %this, %name, %copySource ) +{ + if( %name $= "" ) + return; + + // Make sure the object name is unique. + + if( isObject( %name ) ) + %name = getUniqueName( %name ); + + // Create the profile. + + if( %copySource !$= "" ) + eval( "new GuiControlProfile( " @ %name @ " : " @ %copySource.getName() @ " );" ); + else + eval( "new GuiControlProfile( " @ %name @ " );" ); + + // Add the item and select it. + + %category = %this.getProfileCategory( %name ); + %group = GuiEditorProfilesTree.findChildItemByName( 0, %category ); + + %id = GuiEditorProfilesTree.insertItem( %group, %name @ " (" @ %name.getId() @ ")", %name.getId(), "" ); + + GuiEditorProfilesTree.sort( 0, true, true, false ); + GuiEditorProfilesTree.clearSelection(); + GuiEditorProfilesTree.selectItem( %id ); + + // Mark it as needing to be saved. + + %this.setProfileDirty( %name, true ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::getProfileCategory( %this, %profile ) +{ + if( %this.isDefaultProfile( %name ) ) + return "Default"; + else if( %profile.category !$= "" ) + return %profile.category; + else + return $GUI_EDITOR_DEFAULT_PROFILE_CATEGORY; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::showDeleteProfileDialog( %this, %profile ) +{ + if( %profile $= "" ) + return; + + if( %profile.isInUse() ) + { + MessageBoxOk( "Error", + "The profile '" @ %profile.getName() @ "' is still used by Gui controls." + ); + return; + } + + MessageBoxYesNo( "Delete Profile?", + "Do you really want to delete '" @ %profile.getName() @ "'?", + "GuiEditor.deleteProfile( " @ %profile @ " );" + ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::deleteProfile( %this, %profile ) +{ + if( isObject( "GuiEditorProfilesPM" ) ) + new PersistenceManager( GuiEditorProfilesPM ); + + // Clear dirty state. + + %this.setProfileDirty( %profile, false ); + + // Remove from tree. + + %id = GuiEditorProfilesTree.findItemByValue( %profile.getId() ); + GuiEditorProfilesTree.removeItem( %id ); + + // Remove from file. + + GuiEditorProfilesPM.removeObjectFromFile( %profile ); + + // Delete profile object. + + %profile.delete(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::showSaveProfileDialog( %this, %currentFileName ) +{ + getSaveFileName( "TorqueScript Files|*.cs", %this @ ".doSaveProfile", %currentFileName ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::doSaveProfile( %this, %fileName ) +{ + %path = makeRelativePath( %fileName, getMainDotCsDir() ); + + GuiEditorProfileFileName.setText( %path ); + %this.saveProfile( GuiEditorProfilesTree.getSelectedProfile(), %path ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::saveProfile( %this, %profile, %fileName ) +{ + if( !isObject( "GuiEditorProfilesPM" ) ) + new PersistenceManager( GuiEditorProfilesPM ); + + if( !GuiEditorProfilesPM.isDirty( %profile ) + && ( %fileName $= "" || %fileName $= %profile.getFileName() ) ) + return; + + // Update the filename, if requested. + + if( %fileName !$= "" ) + { + %profile.setFileName( %fileName ); + GuiEditorProfilesPM.setDirty( %profile, %fileName ); + } + + // Save the object. + + GuiEditorProfilesPM.saveDirtyObject( %profile ); + + // Clear its dirty state. + + %this.setProfileDirty( %profile, false, true ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::revertProfile( %this, %profile ) +{ + // Revert changes. + + GuiEditorProfileChangeManager.revertEdits( %profile ); + + // Clear its dirty state. + + %this.setProfileDirty( %profile, false ); + + // Refresh inspector. + + if( GuiEditorProfileInspector.getInspectObject() == %profile ) + GuiEditorProfileInspector.refresh(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::isProfileDirty( %this, %profile ) +{ + if( !isObject( "GuiEditorProfilesPM" ) ) + return false; + + return GuiEditorProfilesPM.isDirty( %profile ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::setProfileDirty( %this, %profile, %value, %noCheck ) +{ + if( !isObject( "GuiEditorProfilesPM" ) ) + new PersistenceManager( GuiEditorProfilesPM ); + + if( %value ) + { + if( !GuiEditorProfilesPM.isDirty( %profile ) || %noCheck ) + { + // If the profile hasn't yet been associated with a file, + // put it in the default file. + + if( %profile.getFileName() $= "" ) + %profile.setFileName( $GUI_EDITOR_DEFAULT_PROFILE_FILENAME ); + + // Add the profile to the dirty set. + + GuiEditorProfilesPM.setDirty( %profile ); + + // Show the item as dirty in the tree. + + %id = GuiEditorProfilesTree.findItemByValue( %profile.getId() ); + GuiEditorProfilesTree.editItem( %id, GuiEditorProfilesTree.getItemText( %id ) SPC "*", %profile.getId() ); + + // Count the number of unsaved profiles. If this is + // the first one, indicate in the window title that + // we have unsaved profiles. + + %this.increaseNumDirtyProfiles(); + } + } + else + { + if( GuiEditorProfilesPM.isDirty( %profile ) || %noCheck ) + { + // Remove from dirty list. + + GuiEditorProfilesPM.removeDirty( %profile ); + + // Clear the dirty marker in the tree. + + %id = GuiEditorProfilesTree.findItemByValue( %profile.getId() ); + %text = GuiEditorProfilesTree.getItemText( %id ); + GuiEditorProfilesTree.editItem( %id, getSubStr( %text, 0, strlen( %text ) - 2 ), %profile.getId() ); + + // Count saved profiles. If this was the last unsaved profile, + // remove the unsaved changes indicator from the window title. + + %this.decreaseNumDirtyProfiles(); + + // Remove saved edits from the change manager. + + GuiEditorProfileChangeManager.clearEdits( %profile ); + } + } +} + +//--------------------------------------------------------------------------------------------- + +/// Return true if the given profile name is the default profile for a +/// GuiControl class or if it's the GuiDefaultProfile. +function GuiEditor::isDefaultProfile( %this, %name ) +{ + if( %name $= "GuiDefaultProfile" ) + return true; + + if( !endsWith( %name, "Profile" ) ) + return false; + + %className = getSubStr( %name, 0, strlen( %name ) - 7 ) @ "Ctrl"; + if( !isClass( %className ) ) + return false; + + return true; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::increaseNumDirtyProfiles( %this ) +{ + %this.numDirtyProfiles ++; + if( %this.numDirtyProfiles == 1 ) + { + %tab = GuiEditorTabBook-->profilesPage; + %tab.setText( %tab.text @ " *" ); + } +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::decreaseNumDirtyProfiles( %this ) +{ + %this.numDirtyProfiles --; + if( !%this.numDirtyProfiles ) + { + %tab = GuiEditorTabBook-->profilesPage; + %title = %tab.text; + %title = getSubstr( %title, 0, strlen( %title ) - 2 ); + + %tab.setText( %title ); + } +} + +//============================================================================================= +// GuiEditorProfilesTree. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfilesTree::init( %this ) +{ + %this.clear(); + + %defaultGroup = %this.insertItem( 0, "Default", -1 ); + %otherGroup = %this.insertItem( 0, $GUI_EDITOR_DEFAULT_PROFILE_CATEGORY, -1 ); + + foreach( %obj in GuiDataGroup ) + { + if( !%obj.isMemberOfClass( "GuiControlProfile" ) ) + continue; + + // If it's an Editor profile, skip if showing them is not enabled. + + if( %obj.category $= "Editor" && !GuiEditor.showEditorProfiles ) + continue; + + // Create a visible name. + + %name = %obj.getName(); + if( %name $= "" ) + %name = "<Unnamed>"; + %text = %name @ " (" @ %obj.getId() @ ")"; + + // Find which group to put the control in. + + %isDefaultProfile = GuiEditor.isDefaultProfile( %name ); + if( %isDefaultProfile ) + %group = %defaultGroup; + else if( %obj.category !$= "" ) + { + %group = %this.findChildItemByName( 0, %obj.category ); + if( !%group ) + %group = %this.insertItem( 0, %obj.category ); + } + else + %group = %otherGroup; + + // Insert the item. + + %this.insertItem( %group, %text, %obj.getId(), "" ); + } + + %this.sort( 0, true, true, false ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfilesTree::onSelect( %this, %id ) +{ + %obj = %this.getItemValue( %id ); + if( %obj == -1 ) + return; + + GuiEditorProfileInspector.inspect( %obj ); + + %fileName = %obj.getFileName(); + if( %fileName $= "" ) + %fileName = $GUI_EDITOR_DEFAULT_PROFILE_FILENAME; + + GuiEditorProfileFileName.setText( %fileName ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfilesTree::onUnselect( %this, %id ) +{ + GuiEditorProfileInspector.inspect( 0 ); + GuiEditorProfileFileName.setText( "" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfilesTree::onProfileRenamed( %this, %profile, %newName ) +{ + %item = %this.findItemByValue( %profile.getId() ); + if( %item == -1 ) + return; + + %newText = %newName @ " (" @ %profile.getId() @ ")"; + if( GuiEditor.isProfileDirty( %profile ) ) + %newText = %newText @ " *"; + + %this.editItem( %item, %newText, %profile.getId() ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfilesTree::getSelectedProfile( %this ) +{ + return %this.getItemValue( %this.getSelectedItem() ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfilesTree::setSelectedProfile( %this, %profile ) +{ + %id = %this.findItemByValue( %profile.getId() ); + %this.selectItem( %id ); +} + +//============================================================================================= +// GuiEditorProfileInspector. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfileInspector::onFieldSelected( %this, %fieldName, %fieldTypeStr, %fieldDoc ) +{ + GuiEditorProfileFieldInfo.setText( "<font:ArialBold:14>" @ %fieldName @ "<font:ArialItalic:14> (" @ %fieldTypeStr @ ") " NL "<font:Arial:14>" @ %fieldDoc ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfileInspector::onFieldAdded( %this, %object, %fieldName ) +{ + GuiEditor.setProfileDirty( %object, true ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfileInspector::onFieldRemoved( %this, %object, %fieldName ) +{ + GuiEditor.setProfileDirty( %object, true ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfileInspector::onFieldRenamed( %this, %object, %oldFieldName, %newFieldName ) +{ + GuiEditor.setProfileDirty( %object, true ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfileInspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ) +{ + GuiEditor.setProfileDirty( %object, true ); + + // If it's the name field, make sure to sync up the treeview. + + if( %fieldName $= "name" ) + GuiEditorProfilesTree.onProfileRenamed( %object, %newValue ); + + // Add change record. + + GuiEditorProfileChangeManager.registerEdit( %object, %fieldName, %arrayIndex, %oldValue ); + + // Add undo. + + pushInstantGroup(); + + %nameOrClass = %object.getName(); + if ( %nameOrClass $= "" ) + %nameOrClass = %object.getClassname(); + + %action = new InspectorFieldUndoAction() + { + actionName = %nameOrClass @ "." @ %fieldName @ " Change"; + + objectId = %object.getId(); + fieldName = %fieldName; + fieldValue = %oldValue; + arrayIndex = %arrayIndex; + + inspectorGui = %this; + }; + + popInstantGroup(); + %action.addToManager( GuiEditor.getUndoManager() ); + GuiEditor.updateUndoMenu(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfileInspector::onInspectorPreFieldModification( %this, %fieldName, %arrayIndex ) +{ + pushInstantGroup(); + %undoManager = GuiEditor.getUndoManager(); + + %object = %this.getInspectObject(); + + %nameOrClass = %object.getName(); + if( %nameOrClass $= "" ) + %nameOrClass = %object.getClassname(); + + %action = new InspectorFieldUndoAction() + { + actionName = %nameOrClass @ "." @ %fieldName @ " Change"; + + objectId = %object.getId(); + fieldName = %fieldName; + fieldValue = %object.getFieldValue( %fieldName, %arrayIndex ); + arrayIndex = %arrayIndex; + + inspectorGui = %this; + }; + + %this.currentFieldEditAction = %action; + popInstantGroup(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfileInspector::onInspectorPostFieldModification( %this ) +{ + %action = %this.currentFieldEditAction; + %object = %action.objectId; + %fieldName = %action.fieldName; + %arrayIndex = %action.arrayIndex; + %oldValue = %action.fieldValue; + %newValue = %object.getFieldValue( %fieldName, %arrayIndex ); + + // If it's the name field, make sure to sync up the treeview. + + if( %action.fieldName $= "name" ) + GuiEditorProfilesTree.onProfileRenamed( %object, %newValue ); + + // Add change record. + + GuiEditorProfileChangeManager.registerEdit( %object, %fieldName, %arrayIndex, %oldValue ); + + %this.currentFieldEditAction.addToManager( GuiEditor.getUndoManager() ); + %this.currentFieldEditAction = ""; + + GuiEditor.updateUndoMenu(); + GuiEditor.setProfileDirty( %object, true ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfileInspector::onInspectorDiscardFieldModification( %this ) +{ + %this.currentFieldEditAction.undo(); + %this.currentFieldEditAction.delete(); + %this.currentFieldEditAction = ""; +} + +//============================================================================================= +// GuiEditorProfileChangeManager. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfileChangeManager::registerEdit( %this, %profile, %fieldName, %arrayIndex, %oldValue ) +{ + // Early-out if we already have a registered edit on the same field. + + foreach( %obj in %this ) + { + if( %obj.profile != %profile ) + continue; + + if( %obj.fieldName $= %fieldName + && %obj.arrayIndex $= %arrayIndex ) + return; + } + + // Create a new change record. + + new ScriptObject() + { + parentGroup = %this; + profile = %profile; + fieldName = %fieldName; + arrayIndex = %arrayIndex; + oldValue = %oldValue; + }; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfileChangeManager::clearEdits( %this, %profile ) +{ + for( %i = 0; %i < %this.getCount(); %i ++ ) + { + %obj = %this.getObject( %i ); + if( %obj.profile != %profile ) + continue; + + %obj.delete(); + %i --; + } +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfileChangeManager::revertEdits( %this, %profile ) +{ + for( %i = 0; %i < %this.getCount(); %i ++ ) + { + %obj = %this.getObject( %i ); + if( %obj.profile != %profile ) + continue; + + %profile.setFieldValue( %obj.fieldName, %obj.oldValue, %obj.arrayIndex ); + + %obj.delete(); + %i --; + } +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfileChangeManager::getEdits( %this, %profile ) +{ + %set = new SimSet(); + + foreach( %obj in %this ) + if( %obj.profile == %profile ) + %set.add( %obj ); + + return %set; +} diff --git a/Templates/Empty/game/tools/guiEditor/scripts/guiEditorSelectDlg.ed.cs b/Templates/Empty/game/tools/guiEditor/scripts/guiEditorSelectDlg.ed.cs new file mode 100644 index 000000000..795cef4d3 --- /dev/null +++ b/Templates/Empty/game/tools/guiEditor/scripts/guiEditorSelectDlg.ed.cs @@ -0,0 +1,87 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------------------------- + +function GuiEditorSelectDlg::toggleVisibility( %this ) +{ + if( %this.isVisible() ) + %this.setVisible( false ); + else + %this.setVisible( true ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorSelectDlg::getRootGroup( %this ) +{ + return GuiEditor.getContentControl(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorSelectDlg::includeClass( %this, %className ) +{ + return ( isMemberOfClass( %className, "GuiControl" ) + && !GuiEditor.isFilteredClass( %className ) ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorSelectDlg::selectObject( %this, %object, %val ) +{ + if( %val ) + GuiEditor.addSelection( %object ); + else + GuiEditor.removeSelection( %object ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorSelectDlg::clearSelection( %this ) +{ + GuiEditor.clearSelection(); +} + +//============================================================================================= +// Events. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorSelectDlg::onVisible( %this, %visible ) +{ + if( !%visible ) + return; + + if( !%this.isInitialized ) + { + %this.init(); + %this.isInitialized = true; + } + + // Re-initialize the group list on each wake. + + %this.initGroupList(); +} diff --git a/Templates/Empty/game/tools/guiEditor/scripts/guiEditorStatusBar.ed.cs b/Templates/Empty/game/tools/guiEditor/scripts/guiEditorStatusBar.ed.cs new file mode 100644 index 000000000..5c8df8f5a --- /dev/null +++ b/Templates/Empty/game/tools/guiEditor/scripts/guiEditorStatusBar.ed.cs @@ -0,0 +1,90 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Code for the status bar in the Gui Editor. + + +//--------------------------------------------------------------------------------------------- + +function GuiEditorStatusBar::getMouseModeHelp( %this ) +{ + %isMac = ( $platform $= "macos" ); + if( %isMac ) + %cmdCtrl = "CMD"; + else + %cmdCtrl = "CTRL"; + + %mouseMode = GuiEditor.getMouseMode(); + switch$( %mouseMode ) + { + case "Selecting": + return ""; + + case "DragSelecting": + return %cmdCtrl @ " to add to selection; ALT to exclude parents; CTRL+ALT to exclude children"; + + case "MovingSelection": + return ""; + + case "SizingSelection": + return "CTRL to activate snapping; ALT to move instead of resize"; + + case "DragGuide": + return "Drag into ruler to delete; drop to place"; + } + + return ""; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorStatusBar::print( %this, %message ) +{ + %this.setText( %message ); + + %sequenceNum = %this.sequenceNum + 1; + %this.sequenceNum = %sequenceNum; + + %this.schedule( 4 * 1000, "clearMessage", %sequenceNum ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorStatusBar::clearMessage( %this, %sequenceNum ) +{ + // If we had no newer message in the meantime, clear + // out the current text. + + if( %this.sequenceNum == %sequenceNum ) + %this.setText( %this.getMouseModeHelp() ); +} + +//============================================================================================= +// Event Handlers. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorStatusBar::onWake( %this ) +{ + %this.setText( %this.getMouseModeHelp() ); +} diff --git a/Templates/Empty/game/tools/guiEditor/scripts/guiEditorToolbox.ed.cs b/Templates/Empty/game/tools/guiEditor/scripts/guiEditorToolbox.ed.cs new file mode 100644 index 000000000..4dc83888a --- /dev/null +++ b/Templates/Empty/game/tools/guiEditor/scripts/guiEditorToolbox.ed.cs @@ -0,0 +1,394 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Code for the toolbox tab of the Gui Editor sidebar. + + +//--------------------------------------------------------------------------------------------- + +function GuiEditorToolbox::initialize( %this ) +{ + // Set up contents. + + %viewType = %this.currentViewType; + if( %viewType $= "" ) + %viewType = "Categorized"; + + %this.currentViewType = ""; + %this.setViewType( %viewType ); + + %this.isInitialized = true; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorToolbox::getViewType( %this ) +{ + return %this.currentViewType; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorToolbox::setViewType( %this, %viewType ) +{ + if( %this.currentViewType $= %viewType + || !%this.isMethod( "setViewType" @ %viewType ) ) + return; + + %this.clear(); + eval( %this @ ".setViewType" @ %viewType @ "();" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorToolbox::setViewTypeAlphabetical( %this ) +{ + %controls = enumerateConsoleClassesByCategory( "Gui" ); + %classes = new ArrayObject(); + + // Collect relevant classes. + + foreach$( %className in %controls ) + { + if( GuiEditor.isFilteredClass( %className ) + || !isMemberOfClass( %className, "GuiControl" ) ) + continue; + + %classes.push_back( %className ); + } + + // Sort classes alphabetically. + + %classes.sortk( true ); + + // Add toolbox buttons. + + %numClasses = %classes.count(); + for( %i = 0; %i < %numClasses; %i ++ ) + { + %className = %classes.getKey( %i ); + %ctrl = new GuiIconButtonCtrl() + { + profile = "GuiIconButtonSmallProfile"; + extent = "128 18"; + text = %className; + iconBitmap = EditorIconRegistry::findIconByClassName( %className ); + buttonMargin = "2 2"; + iconLocation = "left"; + textLocation = "left"; + textMargin = "24"; + AutoSize = true; + + command = "GuiEditor.createControl( " @ %className @ " );"; + useMouseEvents = true; + className = "GuiEditorToolboxButton"; + tooltip = %className NL "\n" @ getDescriptionOfClass( %className ); + tooltipProfile = "GuiToolTipProfile"; + }; + + %this.add( %ctrl ); + } + + %classes.delete(); + %this.currentViewType = "Alphabetical"; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorToolbox::setViewTypeCategorized( %this ) +{ + // Create rollouts for each class category we have and + // record the classes in each category in a temporary array + // on the rollout so we can later sort the class names before + // creating the actual controls in the toolbox. + + %controls = enumerateConsoleClassesByCategory( "Gui" ); + foreach$( %className in %controls ) + { + if( GuiEditor.isFilteredClass( %className ) + || !isMemberOfClass( %className, "GuiControl" ) ) + continue; + + // Get the class's next category under Gui. + + %category = getWord( getCategoryOfClass( %className ), 1 ); + if( %category $= "" ) + continue; + + // Find or create the rollout for the category. + + %rollout = %this.getOrCreateRolloutForCategory( %category ); + + // Insert the item. + + if( !%rollout.classes ) + %rollout.classes = new ArrayObject(); + + %rollout.classes.push_back( %className ); + } + + // Go through the rollouts, sort the class names, and + // create the toolbox controls. + + foreach( %rollout in %this ) + { + if( !%rollout.isMemberOfClass( "GuiRolloutCtrl" ) ) + continue; + + // Get the array with the class names and sort it. + // Sort in descending order to counter reversal of order + // when we later add the controls to the stack. + + %classes = %rollout.classes; + %classes.sortk( true ); + + // Add a control for each of the classes to the + // rollout's stack control. + + %stack = %rollout-->array; + %numClasses = %classes.count(); + for( %n = 0; %n < %numClasses; %n ++ ) + { + %className = %classes.getKey( %n ); + %ctrl = new GuiIconButtonCtrl() + { + profile = "GuiIconButtonSmallProfile"; + extent = "128 18"; + text = %className; + iconBitmap = EditorIconRegistry::findIconByClassName( %className ); + buttonMargin = "2 2"; + iconLocation = "left"; + textLocation = "left"; + textMargin = "24"; + AutoSize = true; + + command = "GuiEditor.createControl( " @ %className @ " );"; + useMouseEvents = true; + className = "GuiEditorToolboxButton"; + tooltip = %className NL "\n" @ getDescriptionOfClass( %className ); + tooltipProfile = "GuiToolTipProfile"; + }; + + %stack.add( %ctrl ); + } + + // Delete the temporary array. + + %rollout.classes = ""; + %classes.delete(); + } + + %this.currentViewType = "Categorized"; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorToolbox::getOrCreateRolloutForCategory( %this, %category ) +{ + // Try to find an existing rollout. + + %ctrl = %this.getRolloutForCategory( %category ); + if( %ctrl != 0 ) + return %ctrl; + + // None there. Create a new one. + + %ctrl = new GuiRolloutCtrl() { + Margin = "0 0 0 0"; + DefaultHeight = "40"; + Expanded = "1"; + ClickCollapse = "1"; + HideHeader = "0"; + isContainer = "1"; + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "421 114"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + autoCollapseSiblings = true; + caption = %category; + class = "GuiEditorToolboxRolloutCtrl"; + + new GuiDynamicCtrlArrayControl() { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "421 64"; + MinExtent = "64 64"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + padding = "6 2 4 0"; + colSpacing = "1"; + rowSpacing = "9"; + dynamicSize = true; + autoCellSize = true; + internalName = "array"; + }; + }; + + %this.add( %ctrl ); + %ctrl.collapse(); + + // Sort the rollouts by their caption. + + %this.sort( "_GuiEditorToolboxSortRollouts" ); + + return %ctrl; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorToolbox::getRolloutForCategory( %this, %category ) +{ + foreach( %obj in %this ) + { + if( !%obj.isMemberOfClass( "GuiRolloutCtrl" ) ) + continue; + + if( stricmp( %obj.caption, %category ) == 0 ) + return %obj; + } + + return 0; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorToolbox::startGuiControlDrag( %this, %class ) +{ + // Create a new control of the given class. + + %payload = eval( "return new " @ %class @ "();" ); + if( !isObject( %payload ) ) + return; + + // this offset puts the cursor in the middle of the dragged object. + %xOffset = getWord( %payload.extent, 0 ) / 2; + %yOffset = getWord( %payload.extent, 1 ) / 2; + + // position where the drag will start, to prevent visible jumping. + %cursorpos = Canvas.getCursorPos(); + %xPos = getWord( %cursorpos, 0 ) - %xOffset; + %yPos = getWord( %cursorpos, 1 ) - %yOffset; + + // Create drag&drop control. + + %dragCtrl = new GuiDragAndDropControl() + { + canSaveDynamicFields = "0"; + Profile = "GuiSolidDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = %xPos SPC %yPos; + extent = %payload.extent; + MinExtent = "32 32"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + deleteOnMouseUp = true; + class = "GuiDragAndDropControlType_GuiControl"; + }; + + %dragCtrl.add( %payload ); + Canvas.getContent().add( %dragCtrl ); + + // Start drag. + + %dragCtrl.startDragging( %xOffset, %yOffset ); +} + +//============================================================================================= +// GuiEditorToolboxRolloutCtrl. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorToolboxRolloutCtrl::onHeaderRightClick( %this ) +{ + if( !isObject( GuiEditorToolboxRolloutCtrlMenu ) ) + new PopupMenu( GuiEditorToolboxRolloutCtrlMenu ) + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Expand All" TAB "" TAB %this @ ".expandAll();"; + item[ 1 ] = "Collapse All" TAB "" TAB %this @ ".collapseAll();"; + }; + + GuiEditorToolboxRolloutCtrlMenu.showPopup( %this.getRoot() ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorToolboxRolloutCtrl::expandAll( %this ) +{ + foreach( %ctrl in %this.parentGroup ) + { + if( %ctrl.isMemberOfClass( "GuiRolloutCtrl" ) ) + %ctrl.instantExpand(); + } +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorToolboxRolloutCtrl::collapseAll( %this ) +{ + foreach( %ctrl in %this.parentGroup ) + { + if( %ctrl.isMemberOfClass( "GuiRolloutCtrl" ) ) + %ctrl.instantCollapse(); + } +} + +//============================================================================================= +// GuiEditorToolboxButton. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorToolboxButton::onMouseDragged( %this ) +{ + GuiEditorToolbox.startGuiControlDrag( %this.text ); +} + +//============================================================================================= +// Misc. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +/// Utility function to sort rollouts by their caption. +function _GuiEditorToolboxSortRollouts( %a, %b ) +{ + return strinatcmp( %a.caption, %b.caption ); +} diff --git a/Templates/Empty/game/tools/guiEditor/scripts/guiEditorTreeView.ed.cs b/Templates/Empty/game/tools/guiEditor/scripts/guiEditorTreeView.ed.cs new file mode 100644 index 000000000..0a2009128 --- /dev/null +++ b/Templates/Empty/game/tools/guiEditor/scripts/guiEditorTreeView.ed.cs @@ -0,0 +1,220 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Code for the main Gui Editor tree view that shows the hierarchy of the +// current GUI being edited. + + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTreeView::init(%this) +{ + if( !isObject( %this.contextMenu ) ) + %this.contextMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Rename" TAB "" TAB "GuiEditorTreeView.showItemRenameCtrl( GuiEditorTreeView.findItemByObjectId( %this.object ) );"; + item[ 1 ] = "Delete" TAB "" TAB "GuiEditor.deleteControl( %this.object );"; + item[ 2 ] = "-"; + item[ 3 ] = "Locked" TAB "" TAB "%this.object.setLocked( !%this.object.locked ); GuiEditorTreeView.update();"; + item[ 4 ] = "Hidden" TAB "" TAB "%this.object.setVisible( !%this.object.isVisible() ); GuiEditorTreeView.update();"; + item[ 5 ] = "-"; + item[ 6 ] = "Add New Controls Here" TAB "" TAB "GuiEditor.setCurrentAddSet( %this.object );"; + item[ 7 ] = "Add Child Controls to Selection" TAB "" TAB "GuiEditor.selectAllControlsInSet( %this.object, false );"; + item[ 8 ] = "Remove Child Controls from Selection" TAB "" TAB "GuiEditor.selectAllControlsInSet( %this.object, true );"; + + object = -1; + }; + + if( !isObject( %this.contextMenuMultiSel ) ) + %this.contextMenuMultiSel = new PopupMenu() + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Delete" TAB "" TAB "GuiEditor.deleteSelection();"; + }; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTreeView::update( %this ) +{ + %obj = GuiEditorContent.getObject( 0 ); + + if( !isObject( %obj ) ) + GuiEditorTreeView.clear(); + else + { + // Open inspector tree. + + GuiEditorTreeView.open( %obj ); + + // Sync selection with GuiEditor. + + GuiEditorTreeView.clearSelection(); + + %selection = GuiEditor.getSelection(); + %count = %selection.getCount(); + + for( %i = 0; %i < %count; %i ++ ) + GuiEditorTreeView.addSelection( %selection.getObject( %i ) ); + } +} + +//============================================================================================= +// Event Handlers. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +/// Defines the icons to be used in the tree view control. +/// Provide the paths to each icon minus the file extension. +/// Seperate them with ':'. +/// The order of the icons must correspond to the bit array defined +/// in the GuiTreeViewCtrl.h. +function GuiEditorTreeView::onDefineIcons(%this) +{ + %icons = ":" @ // Default1 + ":" @ // SimGroup1 + ":" @ // SimGroup2 + ":" @ // SimGroup3 + ":" @ // SimGroup4 + "core/art/gui/images/treeview/hidden:" @ + "tools/worldEditor/images/lockedHandle"; + + GuiEditorTreeView.buildIconTable( %icons ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTreeView::onRightMouseDown( %this, %item, %pts, %obj ) +{ + if( %this.getSelectedItemsCount() > 1 ) + { + %popup = %this.contextMenuMultiSel; + %popup.showPopup( Canvas ); + } + else if( %obj ) + { + %popup = %this.contextMenu; + + %popup.checkItem( 3, %obj.locked ); + %popup.checkItem( 4, !%obj.isVisible() ); + + %popup.enableItem( 6, %obj.isContainer ); + %popup.enableItem( 7, %obj.getCount() > 0 ); + %popup.enableItem( 8, %obj.getCount() > 0 ); + + %popup.object = %obj; + %popup.showPopup( Canvas ); + } +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTreeView::onAddSelection(%this,%ctrl) +{ + GuiEditor.dontSyncTreeViewSelection = true; + GuiEditor.addSelection( %ctrl ); + GuiEditor.dontSyncTreeViewSelection = false; + GuiEditor.setFirstResponder(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTreeView::onRemoveSelection( %this, %ctrl ) +{ + GuiEditor.dontSyncTreeViewSelection = true; + GuiEditor.removeSelection( %ctrl ); + GuiEditor.dontSyncTreeViewSelection = false; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTreeView::onDeleteSelection(%this) +{ + GuiEditor.clearSelection(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTreeView::onSelect( %this, %obj ) +{ + if( isObject( %obj ) ) + { + GuiEditor.dontSyncTreeViewSelection = true; + GuiEditor.select( %obj ); + GuiEditor.dontSyncTreeViewSelection = false; + GuiEditorInspectFields.update( %obj ); + } +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTreeView::isValidDragTarget( %this, %id, %obj ) +{ + return ( %obj.isContainer || %obj.getCount() > 0 ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTreeView::onBeginReparenting( %this ) +{ + if( isObject( %this.reparentUndoAction ) ) + %this.reparentUndoAction.delete(); + + %action = UndoActionReparentObjects::create( %this ); + + %this.reparentUndoAction = %action; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTreeView::onReparent( %this, %obj, %oldParent, %newParent ) +{ + %this.reparentUndoAction.add( %obj, %oldParent, %newParent ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTreeView::onEndReparenting( %this ) +{ + %action = %this.reparentUndoAction; + %this.reparentUndoAction = ""; + + if( %action.numObjects > 0 ) + { + if( %action.numObjects == 1 ) + %action.actionName = "Reparent Control"; + else + %action.actionName = "Reparent Controls"; + + %action.addToManager( GuiEditor.getUndoManager() ); + + GuiEditor.updateUndoMenu(); + } + else + %action.delete(); +} diff --git a/Templates/Empty/game/tools/guiEditor/scripts/guiEditorUndo.ed.cs b/Templates/Empty/game/tools/guiEditor/scripts/guiEditorUndo.ed.cs new file mode 100644 index 000000000..fad91557e --- /dev/null +++ b/Templates/Empty/game/tools/guiEditor/scripts/guiEditorUndo.ed.cs @@ -0,0 +1,598 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +//--------------------------------------------------------------------------------------------- + +function GuiEditorUndoManager::onAddUndo( %this ) +{ + GuiEditor.updateUndoMenu(); +} + +//----------------------------------------------------------------------------------------- +// Undo adding an object +function UndoActionAddObject::create( %set, %trash, %treeView ) +{ + %act = UndoActionAddDelete::create( UndoActionAddObject, %set, %trash, %treeView ); + %act.actionName = "Add Objects"; + return %act; +} + +function UndoActionAddObject::undo(%this) +{ + %this.trashObjects(); +} + +function UndoActionAddObject::redo(%this) +{ + %this.restoreObjects(); +} + +//----------------------------------------------------------------------------------------- +// Undo Deleting an object +function UndoActionDeleteObject::create( %set, %trash, %treeView ) +{ + %act = UndoActionAddDelete::create( UndoActionDeleteObject, %set, %trash, %treeView, true ); + %act.designatedDeleter = true; + %act.actionName = "Delete Objects"; + return %act; +} + +function UndoActionDeleteObject::undo( %this ) +{ + %this.restoreObjects(); +} + +function UndoActionDeleteObject::redo( %this ) +{ + %this.trashObjects(); +} + +//----------------------------------------------------------------------------------------- +// Behavior common to Add and Delete UndoActions +function UndoActionAddDelete::create( %class, %set, %trash, %treeView, %clearNames ) +{ + // record objects + // record parents + // record trash + // return new subclass %class of UndoActionAddDelete + + // The instant group will try to add our + // UndoAction if we don't disable it. + pushInstantGroup(); + + %act = new UndoScriptAction() { class = %class; superclass = UndoActionAddDelete; }; + + // Restore the instant group. + popInstantGroup(); + + for(%i = 0; %i < %set.getCount(); %i++) + { + %obj = %set.getObject(%i); + + %act.object[ %i ] = %obj.getId(); + %act.parent[ %i ] = %obj.getParent(); + %act.objectName[ %i ] = %obj.name; + + // Clear object name so we don't get name clashes with the trash. + + if( %clearNames ) + %obj.name = ""; + } + + %act.objCount = %set.getCount(); + %act.trash = %trash; + %act.tree = %treeView; + + return %act; +} + +function UndoActionAddDelete::trashObjects(%this) +{ + // Move objects to trash. + + for( %i = 0; %i < %this.objCount; %i ++ ) + { + %object = %this.object[ %i ]; + + %this.trash.add( %object ); + %object.name = ""; + } + + // Note that we're responsible for deleting those objects we've moved to the trash. + + %this.designatedDeleter = true; + + // Update the tree view. + + if( isObject( %this.tree ) ) + %this.tree.update(); +} + +function UndoActionAddDelete::restoreObjects(%this) +{ + // Move objects to saved parent and restore names. + + for( %i = 0; %i < %this.objCount; %i ++ ) + { + %object = %this.object[ %i ]; + %object.name = %this.objectName[ %i ]; + %this.parent[ %i ].add( %object ); + } + + // Note that we no longer own the objects, and should not delete them when we're deleted. + + %this.designatedDeleter = false; + + // Update the tree view. + + if( isObject( %this.tree ) ) + %this.tree.update(); +} + +function UndoActionAddObject::onRemove(%this) +{ + // if this undoAction owns objects in the trash, delete them. + if( !%this.designatedDeleter) + return; + + for( %i = 0; %i < %this.objCount; %i ++) + %this.object[ %i ].delete(); +} + +//----------------------------------------------------------------------------------------- +// Undo grouping/ungrouping of controls. + +function GuiEditorGroupUngroupAction::groupControls( %this ) +{ + for( %i = 0; %i < %this.count; %i ++ ) + %this.group[ %i ].group(); + + GuiEditorTreeView.update(); +} + +function GuiEditorGroupUngroupAction::ungroupControls( %this ) +{ + for( %i = 0; %i < %this.count; %i ++ ) + %this.group[ %i ].ungroup(); + + GuiEditorTreeView.update(); +} + +function GuiEditorGroupUngroupAction::onRemove( %this ) +{ + for( %i = 0; %i < %this.count; %i ++ ) + if( isObject( %this.group[ %i ] ) ) + %this.group[ %i ].delete(); +} + +function GuiEditorGroupAction::create( %set, %root ) +{ + // Create action object. + + pushInstantGroup(); + %action = new UndoScriptAction() + { + actionName = "Group"; + className = GuiEditorGroupAction; + superClass = GuiEditorGroupUngroupAction; + count = 1; + group[ 0 ] = new ScriptObject() + { + className = GuiEditorGroup; + count = %set.getCount(); + groupParent = GuiEditor.getCurrentAddSet(); + }; + }; + popInstantGroup(); + + // Add objects from set to group. + + %group = %action.group[ 0 ]; + %num = %set.getCount(); + for( %i = 0; %i < %num; %i ++ ) + { + %ctrl = %set.getObject( %i ); + if( %ctrl != %root ) + %group.ctrl[ %i ] = %ctrl; + } + + return %action; +} + +function GuiEditorGroupAction::undo( %this ) +{ + %this.ungroupControls(); +} + +function GuiEditorGroupAction::redo( %this ) +{ + %this.groupControls(); +} + +function GuiEditorUngroupAction::create( %set, %root ) +{ + // Create action object. + + pushInstantGroup(); + %action = new UndoScriptAction() + { + actionName = "Ungroup"; + className = GuiEditorUngroupAction; + superClass = GuiEditorGroupUngroupAction; + }; + + // Add groups from set to action. + + %groupCount = 0; + %numInSet = %set.getCount(); + for( %i = 0; %i < %numInSet; %i ++ ) + { + %obj = %set.getObject( %i ); + if( %obj.getClassName() $= "GuiControl" && %obj != %root ) + { + // Create group object. + + %group = new ScriptObject() + { + className = GuiEditorGroup; + count = %obj.getCount(); + groupParent = %obj.parentGroup; + groupObject = %obj; + }; + %action.group[ %groupCount ] = %group; + %groupCount ++; + + // Add controls. + + %numControls = %obj.getCount(); + for( %j = 0; %j < %numControls; %j ++ ) + %group.ctrl[ %j ] = %obj.getObject( %j ); + } + } + + popInstantGroup(); + + %action.count = %groupCount; + return %action; +} + +function GuiEditorUngroupAction::undo( %this ) +{ + %this.groupControls(); +} + +function GuiEditorUngroupAction::redo( %this ) +{ + %this.ungroupControls(); +} + +//------------------------------------------------------------------------------ +// Undo Any State Change. +function GenericUndoAction::create() +{ + // The instant group will try to add our + // UndoAction if we don't disable it. + pushInstantGroup(); + + %act = new UndoScriptAction() { class = GenericUndoAction; }; + %act.actionName = "Edit Objects"; + + // Restore the instant group. + popInstantGroup(); + + return %act; +} + +function GenericUndoAction::watch(%this, %object) +{ + // make sure we're working with the object id, because it cannot change. + %object = %object.getId(); + + %fieldCount = %object.getFieldCount(); + %dynFieldCount = %object.getDynamicFieldCount(); + + // inspect all the fields on the object, including dyanamic ones. + // record field names and values. + for(%i = 0; %i < %fieldCount; %i++) + { + %field = %object.getField(%i); + %this.fieldNames[%object] = %this.fieldNames[%object] SPC %field; + %this.fieldValues[%object, %field] = %object.getFieldValue(%field); + } + for(%i = 0; %i < %dynFieldCount; %i++) + { + %field = %object.getDynamicField(%i); + %this.fieldNames[%object] = %this.fieldNames[%object] SPC %field; + %this.fieldValues[%object, %field] = %object.getFieldValue(%field); + } + // clean spurious spaces from the field name list + %this.fieldNames[%object] = trim(%this.fieldNames[%object]); + // record that we know this object + %this.objectIds[%object] = 1; + %this.objectIdList = %this.objectIdList SPC %object; +} + +function GenericUndoAction::learn(%this, %object) +{ + // make sure we're working with the object id, because it cannot change. + %object = %object.getId(); + + %fieldCount = %object.getFieldCount(); + %dynFieldCount = %object.getDynamicFieldCount(); + + // inspect all the fields on the object, including dyanamic ones. + // record field names and values. + for(%i = 0; %i < %fieldCount; %i++) + { + %field = %object.getField(%i); + %this.newFieldNames[%object] = %this.newFieldNames[%object] SPC %field; + %this.newFieldValues[%object, %field] = %object.getFieldValue(%field); + } + for(%i = 0; %i < %dynFieldCount; %i++) + { + %field = %object.getDynamicField(%i); + %this.newFieldNames[%object] = %this.newFieldNames[%object] SPC %field; + %this.newFieldValues[%object, %field] = %object.getFieldValue(%field); + } + // trim + %this.newFieldNames[%object] = trim(%this.newFieldNames[%object]); + + // look for differences + //---------------------------------------------------------------------- + %diffs = false; + %newFieldNames = %this.newFieldNames[%object]; + %oldFieldNames = %this.fieldNames[%object]; + %numNewFields = getWordCount(%newFieldNames); + %numOldFields = getWordCount(%oldFieldNames); + // compare the old field list to the new field list. + // if a field is on the old list that isn't on the new list, + // add it to the newNullFields list. + for(%i = 0; %i < %numOldFields; %i++) + { + %field = getWord(%oldFieldNames, %i); + %newVal = %this.newFieldValues[%object, %field]; + %oldVal = %this.fieldValues[%object, %field]; + if(%newVal !$= %oldVal) + { + %diffs = true; + if(%newVal $= "") + { + %newNullFields = %newNullFields SPC %field; + } + } + } + // scan the new field list + // add missing fields to the oldNullFields list + for(%i = 0; %i < %numNewFields; %i++) + { + %field = getWord(%newFieldNames, %i); + %newVal = %this.newFieldValues[%object, %field]; + %oldVal = %this.fieldValues[%object, %field]; + if(%newVal !$= %oldVal) + { + %diffs = true; + if(%oldVal $= "") + { + %oldNullFields = %oldNullFields SPC %field; + } + } + } + %this.newNullFields[%object] = trim(%newNullFields); + %this.oldNullFields[%object] = trim(%oldNullFields); + + return %diffs; +} + +function GenericUndoAction::watchSet(%this, %set) +{ + // scan the set + // this.watch each object. + %setcount = %set.getCount(); + %i = 0; + for(; %i < %setcount; %i++) + { + %object = %set.getObject(%i); + %this.watch(%object); + } +} + +function GenericUndoAction::learnSet(%this, %set) +{ + // scan the set + // this.learn any objects that we have a this.objectIds[] entry for. + %diffs = false; + for(%i = 0; %i < %set.getCount(); %i++) + { + %object = %set.getObject(%i).getId(); + if(%this.objectIds[%object] != 1) + continue; + + if(%this.learn(%object)) + %diffs = true; + } + + return %diffs; +} + +function GenericUndoAction::undo(%this) +{ + // set the objects to the old values + // scan through our objects + %objectList = %this.objectIdList; + for(%i = 0; %i < getWordCount(%objectList); %i++) + { + %object = getWord(%objectList, %i); + // scan through the old extant fields + %fieldNames = %this.fieldNames[%object]; + for(%j = 0; %j < getWordCount(%fieldNames); %j++) + { + %field = getWord(%fieldNames, %j); + %object.setFieldValue(%field, %this.fieldValues[%object, %field]); + } + // null out the fields in the null list + %fieldNames = %this.oldNullFields[%object]; + for(%j = 0; %j < getWordCount(%fieldNames); %j++) + { + %field = getWord(%fieldNames, %j); + %object.setFieldValue(%field, ""); + } + } + + // update the tree view + if(isObject(%this.tree)) + %this.tree.update(); +} + +function GenericUndoAction::redo(%this) +{ + // set the objects to the new values + // set the objects to the new values + // scan through our objects + %objectList = %this.objectIdList; + for(%i = 0; %i < getWordCount(%objectList); %i++) + { + %object = getWord(%objectList, %i); + // scan through the new extant fields + %fieldNames = %this.newFieldNames[%object]; + for(%j = 0; %j < getWordCount(%fieldNames); %j++) + { + %field = getWord(%fieldNames, %j); + %object.setFieldValue(%field, %this.newFieldValues[%object, %field]); + } + // null out the fields in the null list + %fieldNames = %this.newNullFields[%object]; + for(%j = 0; %j < getWordCount(%fieldNames); %j++) + { + %field = getWord(%fieldNames, %j); + %object.setFieldValue(%field, ""); + } + } + + // update the tree view + if(isObject(%this.tree)) + %this.tree.update(); +} + +//----------------------------------------------------------------------------------------- +// Gui Editor Undo hooks from code +function GuiEditor::onPreEdit(%this, %selection) +{ + if ( isObject(%this.pendingGenericUndoAction) ) + { + error("Error: attempting to create two generic undo actions at once in the same editor!"); + return; + } + + //echo("pre edit"); + %act = GenericUndoAction::create(); + %act.watchSet(%selection); + %act.tree = GuiEditorTreeView; + + %this.pendingGenericUndoAction = %act; + + %this.updateUndoMenu(); +} + +function GuiEditor::onPostEdit(%this, %selection) +{ + if(!isObject(%this.pendingGenericUndoAction)) + error("Error: attempting to complete a GenericUndoAction that hasn't been started!"); + + %act = %this.pendingGenericUndoAction; + %this.pendingGenericUndoAction = ""; + + %diffs = %act.learnSet(%selection); + if(%diffs) + { + //echo("adding generic undoaction to undo manager"); + //%act.dump(); + %act.addToManager(%this.getUndoManager()); + } + else + { + //echo("deleting empty generic undoaction"); + %act.delete(); + } + + %this.updateUndoMenu(); +} + +function GuiEditor::onPreSelectionNudged(%this, %selection) +{ + %this.onPreEdit(%selection); + %this.pendingGenericUndoAction.actionName = "Nudge"; +} + +function GuiEditor::onPostSelectionNudged(%this, %selection) +{ + %this.onPostEdit(%selection); +} + +function GuiEditor::onAddNewCtrl(%this, %ctrl) +{ + %set = new SimSet(); + %set.add(%ctrl); + %act = UndoActionAddObject::create(%set, %this.getTrash(), GuiEditorTreeView); + %set.delete(); + %act.addToManager(%this.getUndoManager()); + %this.updateUndoMenu(); + //GuiEditorInspectFields.update(0); +} + +function GuiEditor::onAddNewCtrlSet(%this, %selection) +{ + %act = UndoActionAddObject::create(%selection, %this.getTrash(), GuiEditorTreeView); + %act.addToManager(%this.getUndoManager()); + %this.updateUndoMenu(); +} + +function GuiEditor::onTrashSelection(%this, %selection) +{ + %act = UndoActionDeleteObject::create(%selection, %this.getTrash(), GuiEditorTreeView); + %act.addToManager(%this.getUndoManager()); + %this.updateUndoMenu(); +} + +function GuiEditor::onControlInspectPreApply(%this, %object) +{ + %set = new SimSet(); + %set.add(%object); + %this.onPreEdit(%set); + %this.pendingGenericUndoAction.actionName = "Change Properties"; + %set.delete(); +} + +function GuiEditor::onControlInspectPostApply(%this, %object) +{ + %set = new SimSet(); + %set.add(%object); + %this.onPostEdit(%set); + %set.delete(); + GuiEditorTreeView.update(); +} + +function GuiEditor::onFitIntoParents( %this ) +{ + %selected = %this.getSelection(); + //TODO +} diff --git a/Templates/Empty/game/tools/levels/BlankRoom.mis b/Templates/Empty/game/tools/levels/BlankRoom.mis new file mode 100644 index 000000000..5ca65ed5a --- /dev/null +++ b/Templates/Empty/game/tools/levels/BlankRoom.mis @@ -0,0 +1,94 @@ +//--- OBJECT WRITE BEGIN --- +new SimGroup(MissionGroup) { + canSaveDynamicFields = "1"; + cdTrack = "2"; + CTF_scoreLimit = "5"; + Enabled = "1"; + musicTrack = "lush"; + + new LevelInfo(theLevelInfo) { + visibleDistance = "1000"; + fogColor = "0.6 0.6 0.7 1"; + fogDensity = "0"; + fogDensityOffset = "700"; + fogAtmosphereHeight = "0"; + canvasClearColor = "0 0 0 255"; + canSaveDynamicFields = "1"; + levelName = "Blank Room"; + desc0 = "A blank room ready to be populated with Torque objects.\n\nGuns, anyone?"; + Enabled = "1"; + }; + new SkyBox(theSky) { + canSaveDynamicFields = "1"; + Position = "0 0 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + Material = "BlackSkyMat"; + drawBottom = "0"; + fogBandHeight = "0"; + }; + new Sun(theSun) { + canSaveDynamicFields = "1"; + Position = "0 0 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + azimuth = "230.396"; + elevation = "45"; + color = "0.968628 0.901961 0.901961 1"; + ambient = "0.078431 0.113725 0.156863 1"; + castShadows = "1"; + attenuationRatio = "0 1 1"; + shadowType = "PSSM"; + texSize = "1024"; + overDarkFactor = "3000 1500 750 250"; + shadowDistance = "200"; + shadowSoftness = "0.25"; + numSplits = "4"; + logWeight = "0.9"; + fadeStartDistance = "0"; + lastSplitTerrainOnly = "0"; + splitFadeDistances = "1 1 1 1"; + bias = "0.1"; + Blur = "1"; + Enabled = "1"; + height = "1024"; + lightBleedFactor = "0.8"; + minVariance = "0"; + pointShadowType = "PointShadowType_Paraboloid"; + shadowBox = "-100 -100 -100 100 100 100"; + width = "3072"; + }; + new SimGroup(PlayerDropPoints) { + canSaveDynamicFields = "1"; + Enabled = "1"; + + new SpawnSphere() { + canSaveDynamicFields = "1"; + Position = "0 0 2"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + radius = "5"; + autoSpawn = "false"; + sphereWeight = "1"; + indoorWeight = "1"; + outdoorWeight = "1"; + Enabled = "1"; + homingCount = "0"; + lockCount = "0"; + }; + }; + new GroundPlane() { + canSaveDynamicFields = "1"; + Position = "0 0 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + squareSize = "128"; + scaleU = "12"; + scaleV = "12"; + Material = "BlankWhite"; + Enabled = "1"; + }; +}; +//--- OBJECT WRITE END --- + diff --git a/Templates/Empty/game/tools/levels/BlankRoom_preview.png b/Templates/Empty/game/tools/levels/BlankRoom_preview.png new file mode 100644 index 000000000..1d91f60f7 Binary files /dev/null and b/Templates/Empty/game/tools/levels/BlankRoom_preview.png differ diff --git a/Templates/Empty/game/tools/main.cs b/Templates/Empty/game/tools/main.cs new file mode 100644 index 000000000..8d3f0bff3 --- /dev/null +++ b/Templates/Empty/game/tools/main.cs @@ -0,0 +1,236 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//--------------------------------------------------------------------------------------------- +// Path to the folder that contains the editors we will load. +//--------------------------------------------------------------------------------------------- +$Tools::resourcePath = "tools/"; + +// These must be loaded first, in this order, before anything else is loaded +$Tools::loadFirst = "editorClasses base worldEditor"; + +//--------------------------------------------------------------------------------------------- +// Object that holds the simObject id that the materialEditor uses to interpret its material list +//--------------------------------------------------------------------------------------------- +$Tools::materialEditorList = ""; + +//--------------------------------------------------------------------------------------------- +// Tools Package. +//--------------------------------------------------------------------------------------------- +package Tools +{ + function loadKeybindings() + { + Parent::loadKeybindings(); + + + } + + // Start-up. + function onStart() + { + Parent::onStart(); + + new Settings(EditorSettings) { file = "tools/settings.xml"; }; + EditorSettings.read(); + + echo( " % - Initializing Tools" ); + + // Default file path when saving from the editor (such as prefabs) + if ($Pref::WorldEditor::LastPath $= "") + { + $Pref::WorldEditor::LastPath = getMainDotCsDir(); + } + + // Common GUI stuff. + exec( "./gui/cursors.ed.cs" ); + exec( "./gui/profiles.ed.cs" ); + exec( "./editorClasses/gui/panels/navPanelProfiles.ed.cs" ); + + // Make sure we get editor profiles before any GUI's + // BUG: these dialogs are needed earlier in the init sequence, and should be moved to + // common, along with the guiProfiles they depend on. + exec( "./gui/guiDialogs.ed.cs" ); + + //%toggle = $Scripts::ignoreDSOs; + //$Scripts::ignoreDSOs = true; + + $ignoredDatablockSet = new SimSet(); + + // fill the list of editors + $editors[count] = getWordCount( $Tools::loadFirst ); + for ( %i = 0; %i < $editors[count]; %i++ ) + { + $editors[%i] = getWord( $Tools::loadFirst, %i ); + } + + %pattern = $Tools::resourcePath @ "/*/main.cs"; + %folder = findFirstFile( %pattern ); + if ( %folder $= "") + { + // if we have absolutely no matches for main.cs, we look for main.cs.dso + %pattern = $Tools::resourcePath @ "/*/main.cs.dso"; + %folder = findFirstFile( %pattern ); + } + while ( %folder !$= "" ) + { + if( filePath( %folder ) !$= "tools" ) // Skip the actual 'tools' folder...we want the children + { + %folder = filePath( %folder ); + %editor = fileName( %folder ); + if ( IsDirectory( %folder ) ) + { + // Yes, this sucks and should be done better + if ( strstr( $Tools::loadFirst, %editor ) == -1 ) + { + $editors[$editors[count]] = %editor; + $editors[count]++; + } + } + } + %folder = findNextFile( %pattern ); + } + + // initialize every editor + new SimSet( EditorPluginSet ); + %count = $editors[count]; + for ( %i = 0; %i < %count; %i++ ) + { + exec( "./" @ $editors[%i] @ "/main.cs" ); + + %initializeFunction = "initialize" @ $editors[%i]; + if( isFunction( %initializeFunction ) ) + call( %initializeFunction ); + } + + // Popuplate the default SimObject icons that + // are used by the various editors. + EditorIconRegistry::loadFromPath( "tools/classIcons/" ); + + // Load up the tools resources. All the editors are initialized at this point, so + // resources can override, redefine, or add functionality. + Tools::LoadResources( $Tools::resourcePath ); + + //$Scripts::ignoreDSOs = %toggle; + + if(isWebDemo()) + { + // if this is the web tool demo lets init some value storage + //$clicks + } + } + + function startToolTime(%tool) + { + if($toolDataToolCount $= "") + $toolDataToolCount = 0; + + if($toolDataToolEntry[%tool] !$= "true") + { + $toolDataToolEntry[%tool] = "true"; + $toolDataToolList[$toolDataToolCount] = %tool; + $toolDataToolCount++; + $toolDataClickCount[%tool] = 0; + } + + $toolDataStartTime[%tool] = getSimTime(); + $toolDataClickCount[%tool]++; + } + + function endToolTime(%tool) + { + %startTime = 0; + + if($toolDataStartTime[%tool] !$= "") + %startTime = $toolDataStartTime[%tool]; + + if($toolDataTotalTime[%tool] $= "") + $toolDataTotalTime[%tool] = 0; + + $toolDataTotalTime[%tool] += getSimTime() - %startTime; + } + + function dumpToolData() + { + %count = $toolDataToolCount; + for(%i=0; %i<%count; %i++) + { + %tool = $toolDataToolList[%i]; + %totalTime = $toolDataTotalTime[%tool]; + if(%totalTime $= "") + %totalTime = 0; + %clickCount = $toolDataClickCount[%tool]; + echo("---"); + echo("Tool: " @ %tool); + echo("Time (seconds): " @ %totalTime / 1000); + echo("Activated: " @ %clickCount); + echo("---"); + } + } + + // Shutdown. + function onExit() + { + if( EditorGui.isInitialized ) + EditorGui.shutdown(); + + // Free all the icon images in the registry. + EditorIconRegistry::clear(); + + // Save any Layouts we might be using + //GuiFormManager::SaveLayout(LevelBuilder, Default, User); + + %count = $editors[count]; + for (%i = 0; %i < %count; %i++) + { + %destroyFunction = "destroy" @ $editors[%i]; + if( isFunction( %destroyFunction ) ) + call( %destroyFunction ); + } + + // Call Parent. + Parent::onExit(); + + // write out our settings xml file + EditorSettings.write(); + } +}; + +function Tools::LoadResources( %path ) +{ + %resourcesPath = %path @ "resources/"; + %resourcesList = getDirectoryList( %resourcesPath ); + + %wordCount = getFieldCount( %resourcesList ); + for( %i = 0; %i < %wordCount; %i++ ) + { + %resource = GetField( %resourcesList, %i ); + if( isFile( %resourcesPath @ %resource @ "/resourceDatabase.cs") ) + ResourceObject::load( %path, %resource ); + } +} + +//----------------------------------------------------------------------------- +// Activate Package. +//----------------------------------------------------------------------------- +activatePackage(Tools); + diff --git a/Templates/Empty/game/tools/materialEditor/gui/MaterialToolbar.ed.gui b/Templates/Empty/game/tools/materialEditor/gui/MaterialToolbar.ed.gui new file mode 100644 index 000000000..8496749c3 --- /dev/null +++ b/Templates/Empty/game/tools/materialEditor/gui/MaterialToolbar.ed.gui @@ -0,0 +1,68 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(MaterialEditorToolbar) { + canSaveDynamicFields = "0"; + internalName = "ShapeEditorToolbar"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "672 0"; + Extent = "802" SPC getWord(EditorGuiToolbar.extent, 1); + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + canMove = "0"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + EdgeSnap = "0"; + text =""; + + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 7"; + extent = "76 16"; + minExtent = "8 8"; + visible = "1"; + text = "Material Library"; + maxLength = "255"; + helpTag = "0"; + }; + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + position = "86 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-h.png"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = ""; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "91 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "materialSelector.showDialog();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Select and Edit an Existing Material"; + hovertime = "1000"; + bitmap = "tools/materialEditor/gui/materialSelectorIcon"; + text = ""; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; +}; \ No newline at end of file diff --git a/Templates/Empty/game/tools/materialEditor/gui/Profiles.ed.cs b/Templates/Empty/game/tools/materialEditor/gui/Profiles.ed.cs new file mode 100644 index 000000000..cf8c71673 --- /dev/null +++ b/Templates/Empty/game/tools/materialEditor/gui/Profiles.ed.cs @@ -0,0 +1,70 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Material Editor Written by Dave Calabrese of Gaslight Studios + +singleton GuiControlProfile (GuiMatEdSliderProfile) +{ + bitmap = "./matEdSlider"; + category = "Editor"; +}; + +singleton GuiControlProfile (GuiMatEdRightJustifyProfile) +{ + // font + fontType = "Arial"; + fontSize = 14; + fontCharset = ANSI; + + fontColor = "0 0 0"; + + justify = "right"; + category = "Editor"; +}; + +singleton GuiControlProfile(GuiMatEdPopUpMenuProfile) +{ + opaque = false; + mouseOverSelected = true; + textOffset = "3 3"; + border = 1; + /*borderThickness = 1;*/ + fixedExtent = true; + //bitmap = "./images/scrollbar"; + bitmap = "tools/editorClasses/gui/images/scroll"; + hasBitmapArray = true; + //profileForChildren = GuiPopupMenuItemBorder; + profileForChildren = GuiControlListPopupProfile; + fillColor = "255 0 0 255"; + fontColor = "255 255 255 255"; + fillColorHL = "50 50 50"; + fontColorHL = "220 220 220"; + borderColor = "100 100 108"; + category = "Editor"; +}; + +singleton GuiControlProfile (MatEdCenteredTextProfile) +{ + fontColor = "0 0 0"; + justify = "center"; + category = "Editor"; +}; diff --git a/Templates/Empty/game/tools/materialEditor/gui/change-material-btn_d.png b/Templates/Empty/game/tools/materialEditor/gui/change-material-btn_d.png new file mode 100644 index 000000000..c8b2106c2 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/change-material-btn_d.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/change-material-btn_h.png b/Templates/Empty/game/tools/materialEditor/gui/change-material-btn_h.png new file mode 100644 index 000000000..d803dc6af Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/change-material-btn_h.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/change-material-btn_n.png b/Templates/Empty/game/tools/materialEditor/gui/change-material-btn_n.png new file mode 100644 index 000000000..4cc985e1c Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/change-material-btn_n.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/cubeMapEd_cubePreview.max b/Templates/Empty/game/tools/materialEditor/gui/cubeMapEd_cubePreview.max new file mode 100644 index 000000000..fa6249ee9 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/cubeMapEd_cubePreview.max differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/cubeMapEd_previewMat.jpg b/Templates/Empty/game/tools/materialEditor/gui/cubeMapEd_previewMat.jpg new file mode 100644 index 000000000..b10e74052 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/cubeMapEd_previewMat.jpg differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/cube_xNeg.jpg b/Templates/Empty/game/tools/materialEditor/gui/cube_xNeg.jpg new file mode 100644 index 000000000..6501386c6 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/cube_xNeg.jpg differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/cube_xPos.jpg b/Templates/Empty/game/tools/materialEditor/gui/cube_xPos.jpg new file mode 100644 index 000000000..c01a9c520 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/cube_xPos.jpg differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/cube_yNeg.jpg b/Templates/Empty/game/tools/materialEditor/gui/cube_yNeg.jpg new file mode 100644 index 000000000..d3fdd38db Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/cube_yNeg.jpg differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/cube_yPos.jpg b/Templates/Empty/game/tools/materialEditor/gui/cube_yPos.jpg new file mode 100644 index 000000000..539cf7762 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/cube_yPos.jpg differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/cube_zNeg.jpg b/Templates/Empty/game/tools/materialEditor/gui/cube_zNeg.jpg new file mode 100644 index 000000000..b81b6f920 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/cube_zNeg.jpg differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/cube_zPos.jpg b/Templates/Empty/game/tools/materialEditor/gui/cube_zPos.jpg new file mode 100644 index 000000000..7d7d797b0 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/cube_zPos.jpg differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/cubemapBtnBorder_d.png b/Templates/Empty/game/tools/materialEditor/gui/cubemapBtnBorder_d.png new file mode 100644 index 000000000..0ce0b477b Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/cubemapBtnBorder_d.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/cubemapBtnBorder_h.png b/Templates/Empty/game/tools/materialEditor/gui/cubemapBtnBorder_h.png new file mode 100644 index 000000000..acea03281 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/cubemapBtnBorder_h.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/cubemapBtnBorder_i.png b/Templates/Empty/game/tools/materialEditor/gui/cubemapBtnBorder_i.png new file mode 100644 index 000000000..f2ee385bf Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/cubemapBtnBorder_i.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/cubemapBtnBorder_n.png b/Templates/Empty/game/tools/materialEditor/gui/cubemapBtnBorder_n.png new file mode 100644 index 000000000..717f9b4f8 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/cubemapBtnBorder_n.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/cubemapEd_spherePreview.max b/Templates/Empty/game/tools/materialEditor/gui/cubemapEd_spherePreview.max new file mode 100644 index 000000000..9425d3b4f Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/cubemapEd_spherePreview.max differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/cubemaped_cubepreview.dts b/Templates/Empty/game/tools/materialEditor/gui/cubemaped_cubepreview.dts new file mode 100644 index 000000000..20472c9cf Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/cubemaped_cubepreview.dts differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/cubemaped_cylinderpreview.dts b/Templates/Empty/game/tools/materialEditor/gui/cubemaped_cylinderpreview.dts new file mode 100644 index 000000000..75a359334 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/cubemaped_cylinderpreview.dts differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/cubemaped_spherepreview.dts b/Templates/Empty/game/tools/materialEditor/gui/cubemaped_spherepreview.dts new file mode 100644 index 000000000..ed117d334 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/cubemaped_spherepreview.dts differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/cubematEd_cylinderPreview.max b/Templates/Empty/game/tools/materialEditor/gui/cubematEd_cylinderPreview.max new file mode 100644 index 000000000..2926befd6 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/cubematEd_cylinderPreview.max differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/cubepreview.dts b/Templates/Empty/game/tools/materialEditor/gui/cubepreview.dts new file mode 100644 index 000000000..18724762d Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/cubepreview.dts differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/cylinderpreview.dts b/Templates/Empty/game/tools/materialEditor/gui/cylinderpreview.dts new file mode 100644 index 000000000..dfe5ec1bc Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/cylinderpreview.dts differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/gridTiny2.PNG b/Templates/Empty/game/tools/materialEditor/gui/gridTiny2.PNG new file mode 100644 index 000000000..6ce109308 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/gridTiny2.PNG differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/guiMaterialPreviewWindow.ed.gui b/Templates/Empty/game/tools/materialEditor/gui/guiMaterialPreviewWindow.ed.gui new file mode 100644 index 000000000..2c5c6aeb4 --- /dev/null +++ b/Templates/Empty/game/tools/materialEditor/gui/guiMaterialPreviewWindow.ed.gui @@ -0,0 +1,796 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl() { + canSaveDynamicFields = "0"; + internalName = "MatEdPreviewWindowContainer"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCollapseCtrl(MaterialEditorPreviewWindow) { + canSaveDynamicFields = "0"; + internalName = "MatEdPreviewWindow"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Extent = "210 251 "; + MinExtent = "210 150"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1)-1; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "4 4 4 4"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + closeCommand = "MaterialEditorPreviewWindow.setVisible(false);"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Material Preview"; + + /*new GuiContainer(MaterialEditorPreviewPane) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; //1 + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "4 23"; + Extent = "200 221"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0";*/ + + new GuiContainer(matEd_previewPanel) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "4 45"; + Extent = "202 202"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Docking = "Client"; + Margin = "24 1 3 3 "; + + + new GuiSwatchButtonCtrl(matEd_previewBackground) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorSwatchButtonProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "-1 -1"; + Extent = "204 204"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + color = "0 0 0 .8"; + //bitmap = "tools/materialEditor/gui/gridTiny2.PNG"; + //wrap = "1"; + }; + new GuiContainer(){ // this is blocking the mouse imput to the swatch imput behind it + HorizSizing = "width"; + VertSizing = "height"; + Position = "-1 -1"; + Extent = "204 204"; + }; + new GuiMaterialPreview(matEd_previewObjectView) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "1 1"; + Extent = "199 199"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + cameraZRot = "0"; + forceFOV = "0"; + }; + //}; + }; + + new GuiPopUpMenuCtrl(matEd_quickPreview_Popup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "4 24"; + Extent = "67 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updatePreviewObject();"; + ToolTip = "Changes the Preview Mesh"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Sphere"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + new GuiSwatchButtonCtrl(MaterialPreviewBackgroundPicker) { // Background Color + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorSwatchButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + position = "189 229"; + Extent = "14 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "getColorF($thisControl.color, \"MaterialEditorGui.updatePreviewBackground\");"; + color = "0 0 0 .8"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + // Ambient light color picker + new GuiSwatchButtonCtrl(matEd_ambientLightColorPicker) { + canSaveDynamicFields = "0"; + Enabled = "1"; + color = "1 1 1 1"; + isContainer = "0"; + Profile = "GuiInspectorSwatchButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "81 28"; + Extent = "14 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "getColorF($ThisControl.color, \"MaterialEditorGui.updateAmbientColor\");"; + hovertime = "1000"; + groupNum = "-1"; + ToolTip ="Change Ambient Light Color"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + // Light color picker + new GuiSwatchButtonCtrl(matEd_lightColorPicker) { + canSaveDynamicFields = "0"; + Enabled = "1"; + color = "1 1 1 1"; + isContainer = "0"; + Profile = "GuiInspectorSwatchButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "75 23"; + Extent = "14 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "getColorF($ThisControl.color, \"MaterialEditorGui.updateLightColor\");"; + hovertime = "1000"; + groupNum = "-1"; + ToolTip ="Change Normal Light Color"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiCheckboxCtrl(){ + position = "108 25"; + Extent = "98 18"; + HorizSizing = "left"; + profile = "GuiCheckBoxProfile"; + Variable = "MaterialEditorGui.livePreview"; + Command = "MaterialEditorGui.updateLivePreview($ThisControl.getValue());"; + text ="Preview in World"; + }; + }; + new GuiWindowCtrl(matEd_cubemapEditor) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "200 257"; + Extent = "478 248"; + MinExtent = "478 248"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + closeCommand = "MaterialEditorGui.hideCubemapEditor(true);"; + text = "Cubemap Editor"; + + new GuiTextCtrl(){ + Profile = "GuiTextProfile"; + position = "307 40"; + Extent = "30 16"; + text = "Name"; + }; + new GuiTextEditCtrl(matEd_cubemapEd_activeCubemapNameTxt) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "338 40"; + Extent = "131 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "myCubemap 1"; + maxLength = "1024"; + AltCommand = "MaterialEditorGui.editCubemapName($ThisControl.getText());"; + }; + new GuiButtonCtrl(){ + Profile = "GuiButtonProfile"; + position = "339 216"; + Extent = "74 24"; + text = "Select"; + command = "MaterialEditorGui.selectCubemap();"; // needs hookup use selected cubemap + }; + new GuiButtonCtrl(){ + Profile = "GuiButtonProfile"; + position = "417 216"; + Extent = "52 24"; + text = "Cancel"; + command = "MaterialEditorGui.hideCubemapEditor(true);"; // needs hookup Cancel + }; + new GuiScrollCtrl(matEd_cubemapEd_availableCubemapScroller) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 40"; + Extent = "154 203"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiListBoxCtrl(matEd_cubemapEd_availableCubemapList) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiListBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "2 2"; + Extent = "128 2"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + AllowMultipleSelections = "0"; + fitParentWidth = "1"; + }; + }; + new GuiTextCtrl(){ + Profile = "GuiTextProfile"; + position = "6 22"; + Extent = "67 16"; + text = "Cubemaps"; + }; + // ------------------------------ Right X Positive ------------------------------------ + new GuiBitmapCtrl(matEd_cubemapEd_XPos) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "299 106"; + Extent = "64 64"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialeditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl(matEd_cubeMapEd_xPosTxt) { + position = "304 110"; + Extent = "57 10"; + text = "+ X Right"; + }; + new GuiBitmapButtonCtrl(matEd_cubeMapEd_updateXPOSImg) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "299 106"; + Extent = "64 64"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.editCubemapImage(\"0\", $ThisControl.bitmap );"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "When using Static Cubemaps, select your CubeMap by clicking here."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + // ------------------------------ X Negitive ------------------------------------ + new GuiBitmapCtrl(matEd_cubemapEd_XNeg) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "167 106"; + Extent = "64 64"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialeditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl(matEd_cubeMapEd_xNegTxt) { + position = "171 110"; + Extent = "57 10"; + text = "- X Left"; + }; + new GuiBitmapButtonCtrl(matEd_cubeMapEd_updateXNEGImg) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "167 106"; + Extent = "64 64"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.editCubemapImage(\"1\", $ThisControl.bitmap );"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "When using Static Cubemaps, select your CubeMap by clicking here."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + // ------------------------------ Y Positive ------------------------------------ + new GuiBitmapCtrl(matEd_cubemapEd_YPos) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "233 172"; + Extent = "64 64"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialeditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl(matEd_cubeMapEd_yPosTxt) { + position = "237 175"; + Extent = "57 10"; + text = "+ Y Front"; + }; + new GuiBitmapButtonCtrl(matEd_cubeMapEd_updateYPOSImg) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "233 172"; + Extent = "64 64"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.editCubemapImage(\"3\", $ThisControl.bitmap );"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "When using Static Cubemaps, select your CubeMap by clicking here."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + // ------------------------------ Y Negitive ------------------------------------ + new GuiBitmapCtrl(matEd_cubemapEd_YNeG) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "233 40"; + Extent = "64 64"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialeditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl(matEd_cubeMapEd_yNegTxt) { + position = "237 44"; + Extent = "57 10"; + text = "- Y Back"; + }; + new GuiBitmapButtonCtrl(matEd_cubeMapEd_updateYNegImg) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "233 40"; + Extent = "64 64"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.editCubemapImage(\"2\", $ThisControl.bitmap );"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "When using Static Cubemaps, select your CubeMap by clicking here."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + // ------------------------------ Z Positive ------------------------------------ + new GuiBitmapCtrl(matEd_cubemapEd_ZPos) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "233 106"; + Extent = "64 64"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialeditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl(matEd_cubeMapEd_zPosTxt) { + position = "237 110"; + Extent = "57 10"; + text = "+ Z Top"; + }; + new GuiBitmapButtonCtrl(matEd_cubeMapEd_updateZPosImg) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "233 106"; + Extent = "64 64"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.editCubemapImage(\"4\", $ThisControl.bitmap );"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "When using Static Cubemaps, select your CubeMap by clicking here."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + // ------------------------------ Z Negitive ------------------------------------ + new GuiBitmapCtrl(matEd_cubemapEd_ZNeg) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "365 106"; + Extent = "64 64"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialeditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl(matEd_cubeMapEd_zNegTxt) { + position = "369 110"; + Extent = "57 10"; + text = "- Z Bottom"; + }; + new GuiBitmapButtonCtrl(matEd_cubeMapEd_updateZNegImg) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "365 106"; + Extent = "64 64"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.editCubemapImage(\"5\", $ThisControl.bitmap );"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "When using Static Cubemaps, select your CubeMap by clicking here."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + + // Create New Cubemap + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "top"; + position = "128 23"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "matEd_addCubemapWindow.setVisible(1);"; // -------------- Needs Hookup Create New Cubemap + hovertime = "1000"; + tooltip = "Create New Cubemap"; + bitmap = "core/art/gui/images/new"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "top"; + position = "143 23"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.showDeleteCubemapDialog();"; // -------------- Needs Hookup Delete Cubemap + hovertime = "1000"; + tooltip = "Delete Cubemap"; + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + internalName = "saveCubemap"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "top"; + position = "106 23"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.showSaveCubemapDialog();"; // -------------- Needs Hookup Save Cubemap + hovertime = "1000"; + tooltip = "Save Cubemap"; + bitmap = "tools/gui/images/save-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; + + new GuiWindowCtrl(matEd_addCubemapWindow) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "362 333"; + Extent = "300 99"; + MinExtent = "48 92"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Create Cubemap"; + + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "cubemapName"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "96 35"; + Extent = "196 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + AltCommand = ""; + passwordMask = "*"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "12 36"; + Extent = "77 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + text = "Cubemap Name"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "96 68"; + Extent = "126 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + text = "Create"; + Command = "MaterialEditorGui.addCubemap( matEd_addCubemapWindow-->cubemapName.getText() );matEd_addCubemapWindow.setVisible(0);"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "228 68"; + Extent = "64 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + text = "Cancel"; + Command = "matEd_addCubemapWindow.setVisible(0);"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui b/Templates/Empty/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui new file mode 100644 index 000000000..b0b9fab5a --- /dev/null +++ b/Templates/Empty/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui @@ -0,0 +1,3729 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(MaterialEditorGui,EditorGuiGroup) { + canSaveDynamicFields = "0"; + internalName = "MatEdPropertiesWindowContainer"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCollapseCtrl(MaterialEditorPropertiesWindow) { + canSaveDynamicFields = "0"; + internalName = "MatEdPropertiesWindow"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Extent = "210 446"; + MinExtent = "210 316"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) + getWord(MaterialEditorPreviewWindow.extent, 1) - 2; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "4 4 4 4"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + closeCommand = "MaterialEditorPropertiesWindow.setVisible(false);"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Material Properties"; + + new GuiContainer(){ // Client group + isContainer = "1"; + Docking = "Client"; + Margin = "3 1 3 3"; + Position = "4 24"; + Extent = "202 668"; + + new GuiContainer(){ // container to prevent transparent collapsing from effecting children. + Position = "0 21"; + Extent = "202 39"; + isContainer = "1"; + HorizSizing = "width"; + Visible = "1"; + + new GuiContainer(MatEdMaterialMode){ // Edit Mode + Position = "0 0"; + Extent = "202 39"; + isContainer = "1"; + HorizSizing = "width"; + Visible = "0"; + + new GuiTextCtrl(){ + Position = "1 1"; + Extent = "39 16"; + Profile = "GuiTextRightProfile"; + text = "Material"; + }; + new GuiTextEditCtrl(){ + internalName = "selMaterialName"; + Profile = "GuiTextEditProfile"; + AltCommand = "MaterialEditorGui.setMaterialDirty();MaterialEditorGui.updateActiveMaterialName($ThisControl.getText());"; // needs hookup + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "45 0"; + Extent = "158 18"; + text = ""; + HorizSizing = "width"; + }; + new GuiTextCtrl(){ + Position = "1 21"; + Extent = "39 16"; + Profile = "GuiTextRightProfile"; + text = "Target"; + }; + new GuiTextCtrl(){ // mesh name should not include the path + internalName = "selMaterialMapTo"; // will use the first child found with that name if called from a previous parent even if it is invisable. + Position = "46 21"; + Extent = "141 16"; + HorizSizing = "width"; + VertSizing = "bottom"; + text = ""; + }; + }; + new GuiContainer(MatEdTargetMode){ // Selection Mode + Position = "0 0"; + Extent = "202 39"; + isContainer = "1"; + HorizSizing = "width"; + Visible = "1"; + + new GuiBitmapButtonCtrl(){ + Profile = "GuiButtonProfile"; + Position = "186 23"; + Extent = "17 17"; + HorizSizing = "left"; + tooltip = "Swap material on the object with existing"; + bitmap = "tools/materialEditor/gui/change-material-btn"; + command = "materialSelector.showDialog(\"MaterialEditorGui.showMaterialChangeSaveDialog\");"; + }; + + new GuiTextEditCtrl(){ + internalName = "selMaterialName"; + Profile = "GuiTextEditProfile"; + AltCommand = "MaterialEditorGui.setMaterialDirty();MaterialEditorGui.updateActiveMaterialName($ThisControl.getText());"; // needs hookup + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "76 21"; + Extent = "107 18"; + text = "myMaterial 1"; + HorizSizing = "width"; + }; + new GuiTextCtrl(){ // mesh name should not include the path + internalName = "selMaterialMapTo"; + Profile = "GuiTextRightProfile"; + Position = "1 1"; + Extent = "70 16"; + HorizSizing = "right"; + VertSizing = "bottom"; + text = ""; + }; + new GuiTextCtrl(){ + Profile = "GuiTextRightProfile"; + Position = "1 21"; + Extent = "70 16"; + HorizSizing = "right"; + VertSizing = "bottom"; + text = "Material"; + }; + new GuiPopupMenuCtrlEx(SubMaterialSelector){ // needs hookup will show the name of the current mesh Maped to + Profile = "GuiPopupMenuProfile"; + Position = "76 0"; + Extent = "126 17"; + HorizSizing = "width"; + VertSizing = "bottom"; + text = ""; + tooltip = "Target Material"; + Command = "SubMaterialSelector.onSelect();"; + reverseTextList = "0"; + }; + }; + }; + + // make this shorter //////////////////////////////////////////////////////////////////////////// + new GuiScrollCtrl(matEd_scrollControl) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; //height + position = "0 65"; + Extent = "202 603"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiStackControl(MatEd_scrollContents) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "187 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiPopUpMenuCtrl() { + canSaveDynamicFields = "0"; + internalName = "MaterialLayerCtrl"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiPopUpMenuTabProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "112 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.changeLayer( $ThisControl.getText() );"; + ToolTip = "Changes the material layer being edited"; + hovertime = "1000"; + text = "Layer 0"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "185 0"; + Caption = "Basic Texture Maps"; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "185 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ // Diffuse Map + profile="GuiDefaultProfile"; + isContainer = "1"; + position = "6 21"; + Extent = "185 52"; + HorizSizing = "width"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + internalName = "diffuseMapDisplayBitmap"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialeditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"diffuse\", 1);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Change the Active Diffuse Map for this layer"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -3"; + Extent = "72 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Diffuse Map"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + internalName = "diffuseMapNameText"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "56 16"; + Extent = "134 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiSwatchButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "colorTintSwatch"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorSwatchButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "55 33"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "getColorF(materialEd_PreviewMaterial.diffuseColor[MaterialEditorGui.currentLayer], \"MaterialEditorGui.updateColorMultiply\");"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiTextCtrl(){ + profile="GuiDefaultProfile"; + text = "Color"; + position = "74 34"; + Extent = "30 15"; + }; + new GuiButtonCtrl(){ + profile="GuiButtonProfile"; + text ="Edit"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "134 34"; + Extent = "40 16"; + buttonType = "PushButton"; + command = "MaterialEditorGui.updateTextureMap(\"diffuse\", 1);"; + + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "177 34"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"diffuse\", 0);"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + }; + new GuiBitmapCtrl(){ + position="6 75"; + extent ="175 2"; + HorizSizing = "width"; + bitmap ="core/art/gui/images/separator-v"; + }; + new GuiContainer(){ // Normal Map + profile="GuiDefaultProfile"; + isContainer = "1"; + position = "6 79"; + Extent = "185 52"; + HorizSizing = "width"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + internalName = "normalMapDisplayBitmap"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialeditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -3"; + Extent = "72 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Normal Map"; + maxLength = "1024"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"normal\", 1);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Change the active Normal Map for this layer."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + internalName = "normalMapNameText"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "56 16"; + Extent = "143 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiButtonCtrl(){ + profile="GuiButtonProfile"; + text ="Edit"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "134 34"; + Extent = "40 16"; + buttonType = "PushButton"; + command = "MaterialEditorGui.updateTextureMap(\"normal\", 1);"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "177 34"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"normal\", 0);"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + }; + new GuiBitmapCtrl(){ + position="6 360"; + extent ="175 2"; + HorizSizing = "width"; + bitmap ="core/art/gui/images/separator-v"; + }; + new GuiContainer(){ // spec Map + profile="GuiDefaultProfile"; + isContainer = "1"; + position = "6 364"; + Extent = "185 52"; + HorizSizing = "width"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + internalName = "specMapDisplayBitmap"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialeditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -3"; + Extent = "72 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Spec Map"; + maxLength = "1024"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateSpecMap(1);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Change the active Tone Map for this layer."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + internalName = "specMapNameText"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "56 16"; + Extent = "143 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiButtonCtrl(){ + profile="GuiButtonProfile"; + text ="Edit"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "134 34"; + Extent = "40 16"; + buttonType = "PushButton"; + command="MaterialEditorGui.updateSpecMap(1);"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "177 34"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateSpecMap(0);"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + }; + + }; + }; + new GuiRolloutCtrl(advancedTextureMapsRollout) { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "185 0"; + Caption = "Advanced Texture Maps"; + Expanded = false; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "185 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ // Detail Map + profile="GuiDefaultProfile"; + isContainer = "1"; + position = "6 193"; + Extent = "185 52"; + HorizSizing = "width"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + internalName = "detailMapDisplayBitmap"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialeditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"detail\", 1);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Change the active Detail Map for this layer."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + + new GuiTextCtrl() { // Detailmap Scale text + profile="GuiDefaultProfile"; + position = "56 34"; + Extent = "29 16"; + text ="Scale"; + }; + + new GuiTextEditCtrl() { // Detailmap Scale + profile="GuiTextEditProfileNumbersOnly"; + internalName = "detailScaleTextEdit"; + position = "87 33"; + Extent = "28 18"; + text ="0"; + maxLength = "2"; + AltCommand = "MaterialEditorGui.updateDetailScale($ThisControl.getText());"; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -3"; + Extent = "72 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Detail Map"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + internalName = "detailMapNameText"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "56 16"; + Extent = "143 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiButtonCtrl(){ + profile="GuiButtonProfile"; + text ="Edit"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "134 34"; + Extent = "40 16"; + buttonType = "PushButton"; + command = "MaterialEditorGui.updateTextureMap(\"detail\", 1);"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "177 34"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"detail\", 0);"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + }; + new GuiBitmapCtrl(){ + position="6 246"; + extent ="175 2"; + HorizSizing = "width"; + bitmap ="core/art/gui/images/separator-v"; + }; + + new GuiContainer(){ // Detail Normal Map + profile="GuiDefaultProfile"; + isContainer = "1"; + position = "6 136"; + Extent = "185 52"; + HorizSizing = "width"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + internalName = "detailNormalMapDisplayBitmap"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialeditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"detailNormal\", 1);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Change the active DetailNormal Map for this layer."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + + new GuiTextCtrl() { // Detail Normal Map Strength text + profile="GuiDefaultProfile"; + position = "56 34"; + Extent = "29 16"; + text ="Strength"; + }; + + new GuiTextEditCtrl() { // Detail Normal Map Strength + profile="GuiTextEditProfileNumbersOnly"; + internalName = "detailNormalStrengthTextEdit"; + position = "87 33"; + Extent = "28 18"; + text ="0"; + maxLength = "3"; + AltCommand = "MaterialEditorGui.updateDetailNormalStrength($ThisControl.getText());"; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -3"; + Extent = "72 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Detail Normal Map"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + internalName = "detailNormalMapNameText"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "56 16"; + Extent = "143 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiButtonCtrl(){ + profile="GuiButtonProfile"; + text ="Edit"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "134 34"; + Extent = "40 16"; + buttonType = "PushButton"; + command = "MaterialEditorGui.updateTextureMap(\"detailNormal\", 1);"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "177 34"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"detailNormal\", 0);"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + }; + new GuiBitmapCtrl(){ + position="6 189"; + extent ="175 2"; + HorizSizing = "width"; + bitmap ="core/art/gui/images/separator-v"; + }; + + new GuiContainer(){ // Overlay Map + profile="GuiDefaultProfile"; + isContainer = "1"; + position = "6 136"; + Extent = "185 52"; + HorizSizing = "width"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + internalName = "overlayMapDisplayBitmap"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialeditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"overlay\", 1);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Change the active Overlay Map for this layer."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -3"; + Extent = "72 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Overlay Map"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + internalName = "overlayMapNameText"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "56 16"; + Extent = "143 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiButtonCtrl(){ + profile="GuiButtonProfile"; + text ="Edit"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "134 34"; + Extent = "40 16"; + buttonType = "PushButton"; + command = "MaterialEditorGui.updateTextureMap(\"overlay\", 1);"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "177 34"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"overlay\", 0);"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + }; + new GuiBitmapCtrl(){ + position="6 189"; + extent ="175 2"; + HorizSizing = "width"; + bitmap ="core/art/gui/images/separator-v"; + }; + new GuiContainer(){ // light Map + profile="GuiDefaultProfile"; + isContainer = "1"; + position = "6 250"; + Extent = "185 52"; + HorizSizing = "width"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + internalName = "lightMapDisplayBitmap"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialeditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -3"; + Extent = "72 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Light Map"; + maxLength = "1024"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"light\", 1);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Change the active light Map for this layer."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + internalName = "lightMapNameText"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "56 16"; + Extent = "143 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiButtonCtrl(){ + profile="GuiButtonProfile"; + text ="Edit"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "134 34"; + Extent = "40 16"; + buttonType = "PushButton"; + command="MaterialEditorGui.updateTextureMap(\"light\", 1);"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "177 34"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"light\", 0);"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + }; + new GuiBitmapCtrl(){ + position="6 303"; + extent ="175 2"; + HorizSizing = "width"; + bitmap ="core/art/gui/images/separator-v"; + }; + new GuiContainer(){ // tone Map + profile="GuiDefaultProfile"; + isContainer = "1"; + position = "6 307"; + Extent = "185 52"; + HorizSizing = "width"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + internalName = "toneMapDisplayBitmap"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialeditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -3"; + Extent = "72 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Tone Map"; + maxLength = "1024"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"tone\", 1);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Change the active Tone Map for this layer."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + internalName = "toneMapNameText"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "56 16"; + Extent = "143 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiButtonCtrl(){ + profile="GuiButtonProfile"; + text ="Edit"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "134 34"; + Extent = "40 16"; + buttonType = "PushButton"; + command="MaterialEditorGui.updateTextureMap(\"tone\", 1);"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "177 34"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"tone\", 0);"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + }; + new GuiBitmapCtrl(){ + position="6 357"; + extent ="175 2"; + HorizSizing = "width"; + bitmap ="core/art/gui/images/separator-v"; + }; + new GuiContainer(){ // Environment Map + profile="GuiDefaultProfile"; + isContainer = "1"; + position = "6 359"; + Extent = "185 52"; + HorizSizing = "width"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + internalName = "envMapDisplayBitmap"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialeditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -3"; + Extent = "72 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Env Map"; + maxLength = "1024"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"env\", 1);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Change the active Environment Map for this layer."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + internalName = "envMapNameText"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "56 16"; + Extent = "143 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiButtonCtrl(){ + profile="GuiButtonProfile"; + text ="Edit"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "134 34"; + Extent = "40 16"; + buttonType = "PushButton"; + command="MaterialEditorGui.updateTextureMap(\"env\", 1);"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "177 34"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"env\", 0);"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + }; + }; + }; + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "185 0"; + Caption = "Lighting Properties"; + Margin = "-1 0 0 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "185 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ // specular + profile="GuiTransparentProfile"; + isContainer = "1"; + position = "0 0"; + Extent = "185 22"; + HorizSizing = "width"; + + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "pixelSpecularCheckbox"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 4"; + Extent = "57 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateSpecularCheckbox($ThisControl.getValue());"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Enables the use of Pixel Specular for this layer."; + hovertime = "1000"; + text = "Specular"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiSwatchButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "specularColorSwatch"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorSwatchButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "69 4"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "getColorF(materialEd_PreviewMaterial.specular[MaterialEditorGui.currentLayer], \"MaterialEditorGui.updateSpecular\");"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiControl() { + class = "AggregateControl"; + position = "91 4"; + Extent = "96 20"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "specularPowerSlider"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 1"; + Extent = "61 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"specularPower[\" @ MaterialEditorGui.currentLayer @ \"]\", mCeil($ThisControl.getValue()), true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"specularPower[\" @ MaterialEditorGui.currentLayer @ \"]\", mCeil($ThisControl.getValue()), true, false);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Sets the strength of the Pixel Specular value."; + hovertime = "1000"; + range = "1 128"; + ticks = "0"; + value = "1"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "specularPowerTextEdit"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "64 0"; + Extent = "29 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"specularPower[\" @ MaterialEditorGui.currentLayer @ \"]\", mCeil($ThisControl.getValue()));"; + hovertime = "1000"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "32"; + maxLength = "3"; + }; + }; + }; + new GuiContainer(){ // glow emissive + profile="GuiTransparentProfile"; + isContainer = "1"; + position = "0 0"; + Extent = "185 22"; + HorizSizing = "width"; + + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "glowCheckbox"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "70 4"; + Extent = "40 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"glow[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Determines if this layer will Glow or not."; + hovertime = "1000"; + text = "Glow"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "emissiveCheckbox"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 4"; + Extent = "60 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"emissive[\" @ MaterialEditorGui.currentLayer @ \"]\",$ThisControl.getValue());"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Emissive causes an object to not be affected by lights. Good for light sources."; + hovertime = "1000"; + text = "Emissive"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + }; + new GuiContainer(){ // parallax + profile="GuiTransparentProfile"; + isContainer = "1"; + position = "0 0"; + Extent = "185 24"; + HorizSizing = "width"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 3"; + Extent = "54 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Parallax"; + maxLength = "1024"; + }; + + new GuiControl() { + class = "AggregateControl"; + position = "70 3"; + Extent = "115 20"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "parallaxSlider"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 2"; + Extent = "82 15"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"parallaxScale[\" @ MaterialEditorGui.currentLayer @ \"]\",$ThisControl.getValue(), true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl);MaterialEditorGui.updateActiveMaterial(\"parallaxScale[\" @ MaterialEditorGui.currentLayer @ \"]\",$ThisControl.getValue(), true, false);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Parallax Scale"; + hovertime = "1000"; + range = "0 1"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "parallaxTextEdit"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "85 0"; + Extent = "29 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl);MaterialEditorGui.updateActiveMaterial(\"parallaxScale[\" @ MaterialEditorGui.currentLayer @ \"]\",$ThisControl.getValue());"; + hovertime = "1000"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "0"; + maxLength = "3"; + }; + }; + }; + new GuiContainer(){ + profile="GuiTransparentProfile"; + isContainer = "1"; + position = "0 0"; + Extent = "185 84"; + HorizSizing = "width"; + + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "useAnisoCheckbox"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 4"; + Extent = "108 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"useAnisotropic[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Enables the use of anisotropic filtering for this layer."; + hovertime = "1000"; + text = "Anisotropic filtering"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "vertLitCheckbox"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 25"; + Extent = "102 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"vertLit[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Enables the use of vertex lighting for this layer."; + hovertime = "1000"; + text = "Vertex lit"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "vertLitCheckbox"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "113 25"; + Extent = "102 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"vertColor[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Multiply vertex colors with diffuse colors for this layer."; + hovertime = "1000"; + text = "Vertex colors"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "subSurfaceCheckbox"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 46"; + Extent = "79 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"subSurface[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Enables the use of subsurface scattering for this layer."; + hovertime = "1000"; + text = "Sub Surface"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiSwatchButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "subSurfaceColorSwatch"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorSwatchButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "90 46"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "getColorF(materialEd_PreviewMaterial.subSurfaceColor[MaterialEditorGui.currentLayer], \"MaterialEditorGui.updateSubSurfaceColor\");"; + tooltip = "Set the subsurface scattering color"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "subSurfaceRolloffTextEdit"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "114 45"; + Extent = "29 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltip = "Set the subsurface rolloff factor"; + Command = "MaterialEditorGui.updateActiveMaterial(\"subSurfaceRolloff[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getText());"; + hovertime = "1000"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "32"; + maxLength = "5"; + }; + new GuiTextCtrl() { + HorizSizing = "right"; + VertSizing = "bottom"; + position = "9 65"; + Extent = "89 16"; + text = "Minnaert constant"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "minnaertTextEdit"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "114 65"; + Extent = "29 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"minnaertConstant[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getText());"; + hovertime = "1000"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "32"; + maxLength = "3"; + }; + }; + }; + }; + new GuiRolloutCtrl(materialAnimationPropertiesRollout) { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "185 0"; + Caption = "Animation Properties"; + Margin = "-1 0 0 0"; + DragSizable = false; + Expanded = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "185 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ // Rotation Animation Properties + profile="inspectorStyleRolloutInnerProfile"; + isContainer = "1"; + position = "-1 96"; + Extent = "185 94"; + HorizSizing = "width"; + + new GuiCheckboxCtrl() { + canSaveDynamicFields = "0"; + internalName = "RotationAnimation"; + Enabled = "1"; + isContainer = "0"; + Profile = "InspectorCheckBoxTitleProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "4 -1"; + Extent = "112 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateAnimationFlags();"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Rotation Animation"; + maxLength = "1024"; + }; + + new GuiControl(){ + class = "AggregateControl"; + position = "0 29"; + Extent = "135 20"; + + new GuiTextCtrl(){ // u + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 1"; + Extent = "12 16"; + text = "U"; + }; + + new GuiSliderCtrl() { // u + Profile = "GuiSliderProfile"; + internalName = "RotationSliderU"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "25 2"; + Extent = "68 15"; + Command = "MaterialEditorGui.updateRotationOffset(true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateRotationOffset(true, false);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Change U Scroll Direction"; + hovertime = "1000"; + range = "-1 0"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl(){ // u + internalName = "RotationTextEditU"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "98 0"; + Extent = "34 18"; + text = "0"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl);"; + }; + }; + + + + new GuiControl() { + class = "AggregateControl"; + position = "0 50"; + Extent = "135 20"; + + new GuiTextCtrl(){ // v + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 1"; + Extent = "12 16"; + text = "V"; + }; + + new GuiSliderCtrl() { // v + Profile = "GuiSliderProfile"; + internalName = "RotationSliderV"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "25 2"; + Extent = "68 15"; + Command = "MaterialEditorGui.updateRotationOffset(true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateRotationOffset(true, false);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Change V Scroll Direction"; + hovertime = "1000"; + range = "-1 0"; + ticks = "0"; + value = "0"; + }; + + new GuiTextEditCtrl(){ // v + internalName = "RotationTextEditV"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "98 0"; + Extent = "34 18"; + text = "0"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateRotationOffset();"; + }; + }; + new GuiTextCtrl(){ // Pivot Point + HorizSizing = "right"; + VertSizing = "bottom"; + position = "98 16"; + Extent = "34 16"; + text = "Pivot"; + }; + new GuiBitmapCtrl(){ + HorizSizing = "right"; + VertSizing = "bottom"; + position = "136 20"; + Extent = "48 48"; + isContainer = true; + bitmap=""; + + new GuiBitmapCtrl(){ + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "48 48"; + bitmap="tools/materialEditor/gui/cubemapBtnBorder_n"; + }; + + new GuiBitmapCtrl(){ //horizontal bar + internalName = "RotationCrosshair"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 20"; + Extent = "7 7"; + MinExtent = "0 0"; + bitmap="core/art/gui/images/crosshair_blue"; + }; + }; + + new GuiControl() { + class = "AggregateControl"; + position = "0 70"; + Extent = "187 20"; + + new GuiTextCtrl(){ // Speed + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 0"; + Extent = "43 16"; + text = "Speed"; + }; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "RotationSpeedSlider"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "49 3"; + Extent = "95 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateRotationSpeed(true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateRotationSpeed(true, false);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Scrolling Speed"; + hovertime = "1000"; + range = "-10 10"; + ticks = "0"; + value = "0"; + }; + + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "RotationSpeedTextEdit"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "150 1"; + Extent = "34 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateRotationSpeed();"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + }; + }; + }; + new GuiContainer(){ // Scroll Animation Properties + profile="inspectorStyleRolloutInnerProfile"; + isContainer = "1"; + position = "-1 191"; + Extent = "185 94"; + HorizSizing = "width"; + + new GuiCheckboxCtrl() { + canSaveDynamicFields = "0"; + internalName = "ScrollAnimation"; + Enabled = "1"; + isContainer = "0"; + Profile = "InspectorCheckBoxTitleProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "4 -1"; + Extent = "112 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + Command = "MaterialEditorGui.updateAnimationFlags();"; + text = "Scroll Animation"; + maxLength = "1024"; + }; + + + new GuiControl(){ + class = "AggregateControl"; + position = "0 29"; + Extent = "135 20"; + + new GuiTextCtrl(){ // u + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 1"; + Extent = "12 16"; + text = "U"; + }; + + new GuiSliderCtrl() { // u + Profile = "GuiSliderProfile"; + internalName = "ScrollSliderU"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "25 2"; + Extent = "68 15"; + Command = "MaterialEditorGui.updateScrollOffset(true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl);MaterialEditorGui.updateScrollOffset(true, false);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Change U Scroll Direction"; + hovertime = "1000"; + range = "-1 1"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl(){ // u + internalName = "ScrollTextEditU"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "98 0"; + Extent = "34 18"; + text = "0"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl);MaterialEditorGui.updateScrollOffset();"; + }; + }; + + new GuiControl() { + class = "AggregateControl"; + position = "0 50"; + Extent = "135 20"; + + new GuiTextCtrl(){ // v + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 1"; + Extent = "12 16"; + text = "V"; + }; + + new GuiSliderCtrl() { // v + Profile = "GuiSliderProfile"; + internalName = "ScrollSliderV"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "25 2"; + Extent = "68 15"; + Command = "MaterialEditorGui.updateScrollOffset(true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl);MaterialEditorGui.updateScrollOffset(true, false);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Change V Scroll Direction"; + hovertime = "1000"; + range = "-1 1"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl(){ // v + internalName = "ScrollTextEditV"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "98 0"; + Extent = "34 18"; + text = "0"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl);MaterialEditorGui.updateScrollOffset();"; + }; + }; + new GuiTextCtrl(){ // Direction Offset + HorizSizing = "right"; + VertSizing = "bottom"; + position = "98 16"; + Extent = "34 16"; + text = "Offset"; + }; + new GuiBitmapCtrl(){ + HorizSizing = "right"; + VertSizing = "bottom"; + position = "136 20"; + Extent = "48 48"; + isContainer = true; + bitmap=""; + + new GuiBitmapCtrl(){ + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "48 48"; + bitmap="tools/materialEditor/gui/cubemapBtnBorder_n"; + }; + new GuiBitmapCtrl(){ //vertical bar + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 20"; + Extent = "7 7"; + MinExtent = "7 7"; + bitmap="core/art/gui/images/crosshair"; + }; + new GuiBitmapCtrl(){ //horizontal bar + internalName = "ScrollCrosshair"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 20"; + Extent = "7 7"; + MinExtent = "0 0"; + bitmap="core/art/gui/images/crosshair_blue"; + }; + }; + + new GuiControl() { + class = "AggregateControl"; + position = "0 70"; + Extent = "187 20"; + + new GuiTextCtrl(){ // Speed + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 0"; + Extent = "43 16"; + text = "Speed"; + }; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "ScrollSpeedSlider"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "49 3"; + Extent = "95 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateScrollSpeed(true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl);MaterialEditorGui.updateScrollSpeed(true, false);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Scrolling Speed"; + hovertime = "1000"; + range = "0 10"; + ticks = "0"; + value = "0"; + }; + + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "ScrollSpeedTextEdit"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "150 1"; + Extent = "34 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl);MaterialEditorGui.updateScrollSpeed();"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + }; + }; + }; + new GuiContainer(){ // Wave Animation Properties + profile="inspectorStyleRolloutInnerProfile"; + isContainer = "1"; + position = "-1 287"; + Extent = "185 85"; + HorizSizing = "width"; + + new GuiCheckboxCtrl() { + Profile = "InspectorCheckBoxTitleProfile"; + internalName = "WaveAnimation"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "4 -1"; + Extent = "155 16"; + MinExtent = "8 2"; + text = " Wave Animation"; + Command = "MaterialEditorGui.updateAnimationFlags();"; + groupNum = "-1"; + }; + + new GuiCheckboxCtrl() { + Profile = "GuiCheckboxProfile"; + internalName = "ScaleAnimation"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "139 24"; + Extent = "45 16"; + MinExtent = "8 2"; + text = "Scale"; + Command = "MaterialEditorGui.updateAnimationFlags();"; + groupNum = "-1"; + }; + + new GuiTextCtrl() { + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 22"; + Extent = "59 16"; + text = " Wave Type"; + }; + new GuiContainer(){ // Wave Radio Button container + profile = "GuiDefaultProfile"; + internalName = "WaveButtonContainer"; + position = "72 25"; + Extent = "49 13"; + isContainer = "1"; + + new GuiBitmapButtonCtrl(){ + profile = "GuiDefaultProfile"; + buttonType = "RadioButton"; + position = "1 0"; + Extent = "13 13"; + bitmap = "tools/materialEditor/gui/wav-sine"; + command = "MaterialEditorGui.updateWaveType();"; + tooltip="Sine Wave"; + hovertime = "1000"; + groupNum = "0"; + waveType = "Sin"; + }; + new GuiBitmapButtonCtrl(){ + profile = "GuiDefaultProfile"; + buttonType = "RadioButton"; + position = "17 0"; + Extent = "13 13"; + bitmap = "tools/materialEditor/gui/wav-triangle"; + command = "MaterialEditorGui.updateWaveType();"; + tooltip="Triangle Wave"; + hovertime = "1000"; + groupNum = "0"; + waveType = "Triangle"; + }; + new GuiBitmapButtonCtrl(){ + profile = "GuiDefaultProfile"; + buttonType = "RadioButton"; + position = "33 0"; + Extent = "13 13"; + bitmap = "tools/materialEditor/gui/wav-square"; + command = "MaterialEditorGui.updateWaveType();"; + tooltip="Square Wave"; + hovertime = "1000"; + groupNum = "0"; + waveType = "Square"; + }; + }; + + new GuiControl() { + class = "AggregateControl"; + position = "0 61"; + Extent = "187 20"; + + new GuiTextCtrl() { + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "16 1"; + Extent = "64 16"; + text = "Frequency"; + }; + + new GuiTextEditCtrl() { // frequence + canSaveDynamicFields = "0"; + internalName = "WaveTextEditFreq"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "150 1"; + Extent = "34 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateWaveFreq();"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + }; + new GuiSliderCtrl() { // freqency + canSaveDynamicFields = "0"; + internalName = "WaveSliderFreq"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "72 3"; + Extent = "74 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateWaveFreq(true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateWaveFreq(true, false);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Changes Wave Frequency"; + hovertime = "1000"; + range = "0 10"; + ticks = "0"; + value = "0"; + }; + + }; + + new GuiControl() { + class = "AggregateControl"; + position = "0 40"; + Extent = "187 20"; + + new GuiTextCtrl() { + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "21 1"; + Extent = "64 16"; + text = "Amplitude"; + }; + + new GuiTextEditCtrl() { // amplitude + Profile = "GuiTextEditProfile"; + internalName = "WaveTextEditAmp"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "150 1"; + Extent = "34 18"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateWaveAmp();"; + hovertime = "1000"; + text = "0"; + }; + new GuiSliderCtrl() { // amplitude + canSaveDynamicFields = "0"; + internalName = "WaveSliderAmp"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "72 3"; + Extent = "74 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateWaveAmp(true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateWaveAmp(true, false);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Changes Wave Amplitude"; + hovertime = "1000"; + range = "0 1"; + ticks = "0"; + value = "0"; + }; + + }; + }; + new GuiContainer(){ // image Sequence Animation Properties + profile="inspectorStyleRolloutInnerProfile"; + isContainer = "1"; + position = "-1 373"; + Extent = "185 66"; + HorizSizing = "width"; + + new GuiCheckboxCtrl() { + Profile = "InspectorCheckBoxTitleProfile"; + internalName = "SequenceAnimation"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "4 0"; + Extent = "130 16"; + MinExtent = "8 2"; + text = "Image Sequence"; + Command = "MaterialEditorGui.updateAnimationFlags();"; + groupNum = "-1"; + }; + + + new GuiControl() { + class = "AggregateControl"; + position = "0 21"; + Extent = "187 20"; + + new GuiTextCtrl() { + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "64 16"; + text = "Frames / Sec"; + }; + + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "SequenceTextEditFPS"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "150 1"; + Extent = "34 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateSequenceFPS();"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "0"; + maxLength = "1024"; + }; + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "SequenceSliderFPS"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "72 3"; + Extent = "74 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateSequenceFPS(true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateSequenceFPS(true, false);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "How many frames to display per second."; + hovertime = "1000"; + range = "0 30"; + ticks = "0"; + value = "0"; + }; + }; + + new GuiControl() { + class = "AggregateControl"; + position = "0 42"; + Extent = "187 20"; + + new GuiTextCtrl() { + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "33 1"; + Extent = "43 16"; + text = "Frames"; + }; + + new GuiTextEditCtrl() { // size + Profile = "GuiTextEditProfile"; + internalName = "SequenceTextEditSSS"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "150 1"; + Extent = "34 18"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateSequenceSSS();"; + hovertime = "1000"; + text = "0"; + }; + new GuiSliderCtrl() { //size + canSaveDynamicFields = "0"; + internalName = "SequenceSliderSSS"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "72 3"; + Extent = "74 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateSequenceSSS(true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateSequenceSSS(true, false);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "How many frames in the sequence."; + hovertime = "1000"; + range = "0 100"; + ticks = "0"; + value = "0"; + }; + }; + }; + }; + }; + new GuiRolloutCtrl(materialAdvancedPropertiesRollout) { // Advanced Properties Group + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "202 0"; + Caption = "Advanced (all layers)"; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "202 16"; + + new GuiContainer(){ // Transparentcy Properties + Profile = "GuiDefaultProfile"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "210 71"; + + new GuiPopUpMenuCtrl() { + internalName = "blendingTypePopUp"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "3 2"; + Extent = "83 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"translucentBlendOp\",$ThisControl.getValue());"; + ToolTip = "Determines the type of blending to be applied on the transparent object."; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "LerpAlpha"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "alphaTestCheckBox"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "3 39"; + Extent = "106 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"alphaTest\",$ThisControl.getValue());"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "When enabled, caused pixels under a specific alpha threshold to get discarded rather than be computed. Only valid for transparent objects."; + hovertime = "1000"; + text = "Alpha Threshold"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + + new GuiControl() { + class = "AggregateControl"; + HorizSizing = "width"; + position = "100 39"; + Extent = "187 20"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "alphaRefSlider"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 3"; + Extent = "45 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"alphaRef\",$ThisControl.getValue(), true, true );"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"alphaRef\",$ThisControl.getValue(), true, false );"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Sets the minimum transparency value that a pixel must have to be calculated. Anything below this value will simply not be rendered at all."; + hovertime = "1000"; + range = "0 255"; + ticks = "0"; + value = "0"; + }; + + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "alphaRefTextEdit"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "49 0"; + Extent = "27 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"alphaRef\",$ThisControl.getValue());"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "100"; + maxLength = "1024"; + }; + }; + + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "transZWriteCheckBox"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "3 23"; + Extent = "112 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"translucentZWrite\",$ThisControl.getValue());"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Can be used to help force a proper Z-Ordering when Z-Ordering issues occur. Only valid for materials with Transparency."; + hovertime = "1000"; + text = "Transparent Z-Write"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "translucentCheckbox"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "89 3"; + Extent = "107 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"translucent\",$ThisControl.getValue());"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Sets material to use transparent blending modes."; + hovertime = "1000"; + text = "Transparency"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "castShadows"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "3 55"; + Extent = "112 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"castShadows\", $ThisControl.getValue());"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Alows object to cast shadows."; + hovertime = "1000"; + text = "Cast Shadows"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "doubleSidedCheckBox"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "100 56"; + Extent = "85 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"doubleSided\",$ThisControl.getValue());"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Determines if this material will be rendered from both sides of the polygon, or just the \'front facing\' side. "; + hovertime = "1000"; + text = "Double Sided"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + }; + new GuiContainer(){ // Reflection Properties + Profile = "GuiDefaultProfile"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 95"; + Extent = "212 25"; + + new GuiBitmapCtrl(){ + position="2 2"; + extent ="192 2"; + HorizSizing = "width"; + bitmap ="core/art/gui/images/separator-v"; + }; + // Reflection Properties Text + new GuiTextCtrl(matEd_reflectionPropertiesText) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "91 6"; + Extent = "80 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Reflection"; + maxLength = "1024"; + }; + + new GuiPopUpMenuCtrl() { + canSaveDynamicFields = "0"; + internalName = "reflectionTypePopUp"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "3 6"; + Extent = "84 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateReflectionType($ThisControl.getText());"; + ToolTip = "Determines the type of blending to be applied on the transparent object."; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + new GuiButtonCtrl(matEd_cubemapEditBtn){ + internalName = "matEd_cubemapEditBtn"; + profile ="GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "143 6 28"; + Extent = "33 18"; + Command = "MaterialEditorGui.showCubemapEditor();"; + text = "Edit"; + }; + }; + new GuiContainer(){ // Behavior Properties + Profile = "GuiDefaultProfile"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 122"; + Extent = "212 80"; + + new GuiBitmapCtrl(){ + position="2 2"; + extent ="192 2"; + HorizSizing = "width"; + bitmap ="core/art/gui/images/separator-v"; + }; + new GuiTextCtrl() { + text = "Effect Colors[0:1]"; + position = "1 6"; + extent = "86 15"; + profile = "GuiDefaultProfile"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "89 6"; + extent = "16 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiInspectorSwatchButtonProfile"; + visible = "1"; + active = "1"; + command = "getColorF(materialEd_PreviewMaterial.effectColor[0], \"MaterialEditorGui.updateEffectColor0\");"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "effectColor0Swatch"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "109 6"; + extent = "16 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiInspectorSwatchButtonProfile"; + visible = "1"; + active = "1"; + command = "getColorF(materialEd_PreviewMaterial.effectColor[1], \"MaterialEditorGui.updateEffectColor1\");"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "effectColor1Swatch"; + }; + new GuiCheckBoxCtrl() { + text = "Show Footprints"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "1 24"; + extent = "93 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"showFootprints\", $ThisControl.getValue());"; + tooltipProfile = "GuiDefaultProfile"; + tooltip = "Enables Player footprints on surfaces that use this Material."; + hovertime = "1000"; + isContainer = "0"; + internalName = "showFootprintsCheckbox"; + }; + new GuiCheckBoxCtrl() { + text = "Show Dust"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "110 24"; + extent = "68 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"showDust\", $ThisControl.getValue());"; + tooltipProfile = "GuiDefaultProfile"; + tooltip = "Enables dust particles on surfaces that use this Material."; + hovertime = "1000"; + isContainer = "0"; + internalName = "showDustCheckbox"; + }; + new GuiTextCtrl() { + text = "Footstep sound"; + position = "1 43"; + extent = "77 15"; + profile = "GuiDefaultProfile"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "None"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "80 42"; + extent = "105 18"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.updateBehaviorSound(\"Footstep\", $ThisControl.getText());"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Determines the footstep sound to use when the Player walks on this Material."; + hovertime = "1000"; + isContainer = "0"; + internalName = "footstepSoundPopUp"; + }; + new GuiTextCtrl() { + text = "Impact sound"; + position = "1 63"; + extent = "64 15"; + profile = "GuiDefaultProfile"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "None"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "80 62"; + extent = "105 18"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.updateBehaviorSound(\"Impact\", $ThisControl.getText());"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Determines the impact sound to use when an object collides with this Material."; + hovertime = "1000"; + isContainer = "0"; + internalName = "impactSoundPopUp"; + }; + }; + }; + }; + }; + + }; + new GuiBitmapButtonCtrl(MatEd_phoBreadcrumb) { //Go back to previous editor + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "-1 0"; + Extent = "20 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + //Command = "materialSelector.showDialog(\"MaterialEditorGui.switchMaterial\");"; + hovertime = "1000"; + bitmap = "tools/gui/images/folderUp"; + tooltip = "Go back to previous editor"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(MatEd_editMaterial) { //Select and Edit an Existing Material + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "86 1"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "materialSelector.showDialog(\"MaterialEditorGui.switchMaterial\");"; + hovertime = "1000"; + bitmap = "tools/gui/images/open-file"; + tooltip = "Open Existing Material"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + // New Button + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "106 1"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.createNewMaterial();"; + hovertime = "1000"; + groupNum = "-1"; + text =""; + tooltip = "Create New Material"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "core/art/gui/images/new"; + }; + // Save Button + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "123 1"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.save();"; + hovertime = "1000"; + groupNum = "-1"; + text =""; + tooltip = "Save Material (ALT S)"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/save-icon"; + }; + new GuiBitmapCtrl(){ + position = "147 1"; + Extent = "2 16"; + minExtent = "2 16"; + HorizSizing = "left"; + VertSizing = "bottom"; + bitmap = "core/art/gui/images/separator-h"; + }; + // Revert Material + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "151 1"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.refreshMaterial();"; + hovertime = "1000"; + tooltip = "Revert Material to Saved"; + text = ""; + bitmap = "tools/gui/images/reset-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + // Clear Material + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "168 1"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.clearMaterial();"; + hovertime = "1000"; + tooltip = "Clear All Material Properties"; + text = ""; + bitmap = "tools/gui/images/clear-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + // Delete Material + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "185 1"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + hovertime = "1000"; + tooltip = "Delete Material from File"; + text = ""; + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + Command = "MaterialEditorGui.deleteMaterial();"; + }; + }; + }; +}; + +// Here are all of the other gui elements that were included in the original gui============================================ +// EDIT: Instead of showing the faded bitmap, were going to just go ahead and push the controls; that way they are sitting +// on top of the editor gui, while being nonmodal +new GuiControl(matEdNonModalGroup, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Profile = "GuiOverlayProfile"; + Enabled = "1"; + isContainer = "1"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl(matEdSaveDialog) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "197 221"; + Extent = "336 104"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "0"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Material Not Saved!"; + + new GuiButtonCtrl(matEd_notSavedWindow_Save) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 69"; + Extent = "121 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "matEdSaveDialog.dialogSave();"; + hovertime = "1000"; + text = "Save"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiTextCtrl(matEd_materialNotSavedText) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "7 35"; + Extent = "318 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "This material has unsaved changes. Do you wish to save?"; + maxLength = "1024"; + }; + new GuiButtonCtrl(matEd_notSavedWindow_DontSave) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "157 69"; + Extent = "80 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "matEdSaveDialog.dialogDontSave();"; + hovertime = "1000"; + text = "Don\'t Save"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl(matEd_notSavedWindow_Cancel) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "245 69"; + Extent = "80 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "matEdSaveDialog.dialogCancel();"; + hovertime = "1000"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; + new GuiWindowCtrl(matEd_changeCategoryDialog) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "288 144"; + Extent = "248 133"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "0"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Change Material Category"; + + new GuiPopUpMenuCtrl(matEd_changeCategory_categoryList) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 32"; + Extent = "183 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + new GuiButtonCtrl(matEd_changeCategory_okayBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 97"; + Extent = "137 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.okayChangeCategoryDialog();"; + hovertime = "1000"; + text = "Update Category"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl(matEd_changeCategory_cancelBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "159 97"; + Extent = "80 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.cancelChangeCategoryDialog();"; + hovertime = "1000"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl(matEd_changeCategory_addCatBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "200 60"; + Extent = "39 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.addCategory();"; + hovertime = "1000"; + text = "New"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiTextEditCtrl(matEd_changeCategory_catNameEntry) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 60"; + Extent = "183 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + }; + new GuiWindowCtrl(matEd_changeCategory_ErrorDialog) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 18"; + Extent = "232 113"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "0"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Category Change Error"; + + new GuiButtonCtrl(matEd_changeCategory_Error_Button) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "72 81"; + Extent = "80 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.okChangeCategoryErrorDialog();"; + hovertime = "1000"; + text = "Ok"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiTextCtrl(matEd_changeCategory_error_Text) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 31"; + Extent = "215 40"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Text goes here!"; + maxLength = "1024"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/materialEditor/gui/matEd_cubePreview.max b/Templates/Empty/game/tools/materialEditor/gui/matEd_cubePreview.max new file mode 100644 index 000000000..6feb85fc4 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/matEd_cubePreview.max differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/matEd_cylinderButt_d.jpg b/Templates/Empty/game/tools/materialEditor/gui/matEd_cylinderButt_d.jpg new file mode 100644 index 000000000..e61b7543a Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/matEd_cylinderButt_d.jpg differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/matEd_cylinderButt_h.jpg b/Templates/Empty/game/tools/materialEditor/gui/matEd_cylinderButt_h.jpg new file mode 100644 index 000000000..0dfc3466b Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/matEd_cylinderButt_h.jpg differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/matEd_cylinderButt_n.jpg b/Templates/Empty/game/tools/materialEditor/gui/matEd_cylinderButt_n.jpg new file mode 100644 index 000000000..f64864a13 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/matEd_cylinderButt_n.jpg differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/matEd_cylinderPreview.max b/Templates/Empty/game/tools/materialEditor/gui/matEd_cylinderPreview.max new file mode 100644 index 000000000..7259a5df0 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/matEd_cylinderPreview.max differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/matEd_mappedMat.jpg b/Templates/Empty/game/tools/materialEditor/gui/matEd_mappedMat.jpg new file mode 100644 index 000000000..4328f2a4d Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/matEd_mappedMat.jpg differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/matEd_pyramidPreview.max b/Templates/Empty/game/tools/materialEditor/gui/matEd_pyramidPreview.max new file mode 100644 index 000000000..06b4b48d1 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/matEd_pyramidPreview.max differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/matEd_sphereButt_d.jpg b/Templates/Empty/game/tools/materialEditor/gui/matEd_sphereButt_d.jpg new file mode 100644 index 000000000..b693e34d6 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/matEd_sphereButt_d.jpg differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/matEd_sphereButt_h.jpg b/Templates/Empty/game/tools/materialEditor/gui/matEd_sphereButt_h.jpg new file mode 100644 index 000000000..d3a8ca6ed Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/matEd_sphereButt_h.jpg differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/matEd_sphereButt_n.jpg b/Templates/Empty/game/tools/materialEditor/gui/matEd_sphereButt_n.jpg new file mode 100644 index 000000000..e2244ab55 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/matEd_sphereButt_n.jpg differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/matEd_spherePreview.max b/Templates/Empty/game/tools/materialEditor/gui/matEd_spherePreview.max new file mode 100644 index 000000000..71485ac86 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/matEd_spherePreview.max differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/matEd_torusKnotPreview.max b/Templates/Empty/game/tools/materialEditor/gui/matEd_torusKnotPreview.max new file mode 100644 index 000000000..4e2bfec10 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/matEd_torusKnotPreview.max differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/matEd_torusPreview.max b/Templates/Empty/game/tools/materialEditor/gui/matEd_torusPreview.max new file mode 100644 index 000000000..4e004500d Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/matEd_torusPreview.max differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/materialSelectorIcon_d.png b/Templates/Empty/game/tools/materialEditor/gui/materialSelectorIcon_d.png new file mode 100644 index 000000000..081e06e98 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/materialSelectorIcon_d.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/materialSelectorIcon_h.png b/Templates/Empty/game/tools/materialEditor/gui/materialSelectorIcon_h.png new file mode 100644 index 000000000..88795fd44 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/materialSelectorIcon_h.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/materialSelectorIcon_n.png b/Templates/Empty/game/tools/materialEditor/gui/materialSelectorIcon_n.png new file mode 100644 index 000000000..a563b88d2 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/materialSelectorIcon_n.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/mesh-selector-btn_d.png b/Templates/Empty/game/tools/materialEditor/gui/mesh-selector-btn_d.png new file mode 100644 index 000000000..81aa03f2d Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/mesh-selector-btn_d.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/mesh-selector-btn_h.png b/Templates/Empty/game/tools/materialEditor/gui/mesh-selector-btn_h.png new file mode 100644 index 000000000..5ccbd9835 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/mesh-selector-btn_h.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/mesh-selector-btn_n.png b/Templates/Empty/game/tools/materialEditor/gui/mesh-selector-btn_n.png new file mode 100644 index 000000000..62f65da52 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/mesh-selector-btn_n.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/new-material_d.png b/Templates/Empty/game/tools/materialEditor/gui/new-material_d.png new file mode 100644 index 000000000..681da25dc Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/new-material_d.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/new-material_h.png b/Templates/Empty/game/tools/materialEditor/gui/new-material_h.png new file mode 100644 index 000000000..d13a6e4a5 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/new-material_h.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/new-material_n.png b/Templates/Empty/game/tools/materialEditor/gui/new-material_n.png new file mode 100644 index 000000000..4c509a909 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/new-material_n.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/pyramidpreview.dts b/Templates/Empty/game/tools/materialEditor/gui/pyramidpreview.dts new file mode 100644 index 000000000..285f42ae2 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/pyramidpreview.dts differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/screenFaded.png b/Templates/Empty/game/tools/materialEditor/gui/screenFaded.png new file mode 100644 index 000000000..a5125a3ab Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/screenFaded.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/scrollBox.jpg b/Templates/Empty/game/tools/materialEditor/gui/scrollBox.jpg new file mode 100644 index 000000000..bd15e5fcd Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/scrollBox.jpg differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/spherepreview.dts b/Templates/Empty/game/tools/materialEditor/gui/spherepreview.dts new file mode 100644 index 000000000..e7b208f61 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/spherepreview.dts differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/torusknotpreview.dts b/Templates/Empty/game/tools/materialEditor/gui/torusknotpreview.dts new file mode 100644 index 000000000..55208ac35 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/torusknotpreview.dts differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/torusknowpreview.dts b/Templates/Empty/game/tools/materialEditor/gui/torusknowpreview.dts new file mode 100644 index 000000000..e69de29bb diff --git a/Templates/Empty/game/tools/materialEditor/gui/toruspreview.dts b/Templates/Empty/game/tools/materialEditor/gui/toruspreview.dts new file mode 100644 index 000000000..8c3153396 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/toruspreview.dts differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/unknownImage.png b/Templates/Empty/game/tools/materialEditor/gui/unknownImage.png new file mode 100644 index 000000000..21d75f311 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/unknownImage.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/unsavedWarn.png b/Templates/Empty/game/tools/materialEditor/gui/unsavedWarn.png new file mode 100644 index 000000000..cf7ecda6b Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/unsavedWarn.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/wav-none_d.png b/Templates/Empty/game/tools/materialEditor/gui/wav-none_d.png new file mode 100644 index 000000000..d7629c669 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/wav-none_d.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/wav-none_h.png b/Templates/Empty/game/tools/materialEditor/gui/wav-none_h.png new file mode 100644 index 000000000..bf14a5ecd Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/wav-none_h.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/wav-none_i.png b/Templates/Empty/game/tools/materialEditor/gui/wav-none_i.png new file mode 100644 index 000000000..7fc641c93 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/wav-none_i.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/wav-none_n.png b/Templates/Empty/game/tools/materialEditor/gui/wav-none_n.png new file mode 100644 index 000000000..e28974ad7 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/wav-none_n.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/wav-sine_d.png b/Templates/Empty/game/tools/materialEditor/gui/wav-sine_d.png new file mode 100644 index 000000000..eb8e9c684 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/wav-sine_d.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/wav-sine_h.png b/Templates/Empty/game/tools/materialEditor/gui/wav-sine_h.png new file mode 100644 index 000000000..6570fe142 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/wav-sine_h.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/wav-sine_i.png b/Templates/Empty/game/tools/materialEditor/gui/wav-sine_i.png new file mode 100644 index 000000000..0008c320e Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/wav-sine_i.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/wav-sine_n.png b/Templates/Empty/game/tools/materialEditor/gui/wav-sine_n.png new file mode 100644 index 000000000..9595622a6 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/wav-sine_n.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/wav-square_d.png b/Templates/Empty/game/tools/materialEditor/gui/wav-square_d.png new file mode 100644 index 000000000..f51cbf301 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/wav-square_d.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/wav-square_h.png b/Templates/Empty/game/tools/materialEditor/gui/wav-square_h.png new file mode 100644 index 000000000..0643cd076 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/wav-square_h.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/wav-square_i.png b/Templates/Empty/game/tools/materialEditor/gui/wav-square_i.png new file mode 100644 index 000000000..1f6d750f5 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/wav-square_i.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/wav-square_n.png b/Templates/Empty/game/tools/materialEditor/gui/wav-square_n.png new file mode 100644 index 000000000..3a99a5aac Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/wav-square_n.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/wav-triangle_d.png b/Templates/Empty/game/tools/materialEditor/gui/wav-triangle_d.png new file mode 100644 index 000000000..2ca098768 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/wav-triangle_d.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/wav-triangle_h.png b/Templates/Empty/game/tools/materialEditor/gui/wav-triangle_h.png new file mode 100644 index 000000000..42549866f Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/wav-triangle_h.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/wav-triangle_i.png b/Templates/Empty/game/tools/materialEditor/gui/wav-triangle_i.png new file mode 100644 index 000000000..b63963b77 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/wav-triangle_i.png differ diff --git a/Templates/Empty/game/tools/materialEditor/gui/wav-triangle_n.png b/Templates/Empty/game/tools/materialEditor/gui/wav-triangle_n.png new file mode 100644 index 000000000..6f05c0175 Binary files /dev/null and b/Templates/Empty/game/tools/materialEditor/gui/wav-triangle_n.png differ diff --git a/Templates/Empty/game/tools/materialEditor/main.cs b/Templates/Empty/game/tools/materialEditor/main.cs new file mode 100644 index 000000000..4751676fe --- /dev/null +++ b/Templates/Empty/game/tools/materialEditor/main.cs @@ -0,0 +1,160 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Material Editor Written by Dave Calabrese and Travis Vroman of Gaslight Studios + +function initializeMaterialEditor() +{ + echo(" % - Initializing Material Editor"); + + // Load Preview Window + exec("~/materialEditor/gui/guiMaterialPreviewWindow.ed.gui"); + + // Load Properties Window + exec("~/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui"); + + // Load Client Scripts. + exec("./scripts/materialEditor.ed.cs"); + exec("./scripts/materialEditorUndo.ed.cs"); + //exec("./gui/profiles.ed.cs"); + + MaterialEditorPreviewWindow.setVisible( false ); + matEd_cubemapEditor.setVisible( false ); + matEd_addCubemapWindow.setVisible( false ); + MaterialEditorPropertiesWindow.setVisible( false ); + + EditorGui.add( MaterialEditorPreviewWindow ); + EditorGui.add( matEd_cubemapEditor ); + EditorGui.add( matEd_addCubemapWindow ); + EditorGui.add( MaterialEditorPropertiesWindow ); +} + +function destroyMaterialEditor() +{ +} + +// Material Editor +function MaterialEditorPlugin::onWorldEditorStartup( %this ) +{ + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Material Editor", "", MaterialEditorPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "Material Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "MaterialEditorPlugin", "MaterialEditorPalette", expandFilename("tools/worldEditor/images/toolbar/matterial-editor"), %tooltip ); + + //connect editor windows + GuiWindowCtrl::attach( MaterialEditorPropertiesWindow, MaterialEditorPreviewWindow); + + %map = new ActionMap(); + %map.bindCmd( keyboard, "1", "EWorldEditorNoneModeBtn.performClick();", "" ); // Select + %map.bindCmd( keyboard, "2", "EWorldEditorMoveModeBtn.performClick();", "" ); // Move + %map.bindCmd( keyboard, "3", "EWorldEditorRotateModeBtn.performClick();", "" ); // Rotate + %map.bindCmd( keyboard, "4", "EWorldEditorScaleModeBtn.performClick();", "" ); // Scale + %map.bindCmd( keyboard, "f", "FitToSelectionBtn.performClick();", "" );// Fit Camera to Selection + %map.bindCmd( keyboard, "z", "EditorGuiStatusBar.setCamera(\"Standard Camera\");", "" );// Free Camera + %map.bindCmd( keyboard, "n", "ToggleNodeBar->renderHandleBtn.performClick();", "" );// Render Node + %map.bindCmd( keyboard, "shift n", "ToggleNodeBar->renderTextBtn.performClick();", "" );// Render Node Text + %map.bindCmd( keyboard, "alt s", "MaterialEditorGui.save();", "" );// Save Material + //%map.bindCmd( keyboard, "delete", "ToggleNodeBar->renderTextBtn.performClick();", "" );// delete Material + %map.bindCmd( keyboard, "g", "ESnapOptions-->GridSnapButton.performClick();" ); // Grid Snappping + %map.bindCmd( keyboard, "t", "SnapToBar->objectSnapDownBtn.performClick();", "" );// Terrain Snapping + %map.bindCmd( keyboard, "b", "SnapToBar-->objectSnapBtn.performClick();" ); // Soft Snappping + %map.bindCmd( keyboard, "v", "EWorldEditorToolbar->boundingBoxColBtn.performClick();", "" );// Bounds Selection + %map.bindCmd( keyboard, "o", "objectCenterDropdown->objectBoxBtn.performClick(); objectCenterDropdown.toggle();", "" );// Object Center + %map.bindCmd( keyboard, "p", "objectCenterDropdown->objectBoundsBtn.performClick(); objectCenterDropdown.toggle();", "" );// Bounds Center + %map.bindCmd( keyboard, "k", "objectTransformDropdown->objectTransformBtn.performClick(); objectTransformDropdown.toggle();", "" );// Object Transform + %map.bindCmd( keyboard, "l", "objectTransformDropdown->worldTransformBtn.performClick(); objectTransformDropdown.toggle();", "" );// World Transform + + MaterialEditorPlugin.map = %map; + + MaterialEditorGui.fileSpec = "Torque Material Files (materials.cs)|materials.cs|All Files (*.*)|*.*|"; + MaterialEditorGui.textureFormats = "Image Files (*.png, *.jpg, *.dds, *.bmp, *.gif, *.jng. *.tga)|*.png;*.jpg;*.dds;*.bmp;*.gif;*.jng;*.tga|All Files (*.*)|*.*|"; + MaterialEditorGui.modelFormats = "DTS Files (*.dts)|*.dts"; + MaterialEditorGui.lastTexturePath = ""; + MaterialEditorGui.lastTextureFile = ""; + MaterialEditorGui.lastModelPath = ""; + MaterialEditorGui.lastModelFile = ""; + MaterialEditorGui.currentMaterial = ""; + MaterialEditorGui.lastMaterial = ""; + MaterialEditorGui.currentCubemap = ""; + MaterialEditorGui.currentObject = ""; + + MaterialEditorGui.livePreview = "1"; + MaterialEditorGui.currentLayer = "0"; + MaterialEditorGui.currentMode = "Material"; + MaterialEditorGui.currentMeshMode = "EditorShape"; + + new ArrayObject(UnlistedCubemaps); + UnlistedCubemaps.add( "unlistedCubemaps", matEdCubeMapPreviewMat ); + UnlistedCubemaps.add( "unlistedCubemaps", WarnMatCubeMap ); + + //MaterialEditor persistence manager + new PersistenceManager(matEd_PersistMan); +} + +function MaterialEditorPlugin::onActivated( %this ) +{ + if($gfx::wireframe){ + $wasInWireFrameMode = true; + $gfx::wireframe = false; + }else{ + $wasInWireFrameMode = false; + } + advancedTextureMapsRollout.Expanded = false; + materialAnimationPropertiesRollout.Expanded = false; + materialAdvancedPropertiesRollout.Expanded = false; + WorldEditorPlugin.onActivated(); + + EditorGui-->MatEdPropertiesWindow.setVisible( true ); + EditorGui-->MatEdPreviewWindow.setVisible( true ); + EditorGui-->WorldEditorToolbar.setVisible( true ); + + MaterialEditorGui.currentObject = $Tools::materialEditorList; + // Execute the back end scripts that actually do the work. + MaterialEditorGui.open(); + %this.map.push(); + + Parent::onActivated(%this); +} + +function MaterialEditorPlugin::onEditMenuSelect( %this, %editMenu ) +{ + WorldEditorPlugin.onEditMenuSelect( %editMenu ); +} + +function MaterialEditorPlugin::onDeactivated( %this ) +{ + if($wasInWireFrameMode) + $gfx::wireframe = true; + + WorldEditorPlugin.onDeactivated(); + + MaterialEditorGui.quit(); + + EditorGui-->MatEdPropertiesWindow.setVisible( false ); + EditorGui-->MatEdPreviewWindow.setVisible( false ); + EditorGui-->WorldEditorToolbar.setVisible( false ); + %this.map.pop(); + + Parent::onDeactivated(%this); +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/materialEditor/scripts/materialEditor.ed.cs b/Templates/Empty/game/tools/materialEditor/scripts/materialEditor.ed.cs new file mode 100644 index 000000000..9297eec94 --- /dev/null +++ b/Templates/Empty/game/tools/materialEditor/scripts/materialEditor.ed.cs @@ -0,0 +1,2272 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Material Editor originally created by Dave Calabrese and Travis Vroman of Gaslight Studios + +function MaterialEditorGui::establishMaterials(%this) +{ + //Cubemap used to preview other cubemaps in the editor. + singleton CubemapData( matEdCubeMapPreviewMat ) + { + cubeFace[0] = "tools/materialeditor/gui/cube_xNeg"; + cubeFace[1] = "tools/materialeditor/gui/cube_xPos"; + cubeFace[2] = "tools/materialeditor/gui/cube_ZNeg"; + cubeFace[3] = "tools/materialeditor/gui/cube_ZPos"; + cubeFace[4] = "tools/materialeditor/gui/cube_YNeg"; + cubeFace[5] = "tools/materialeditor/gui/cube_YPos"; + parentGroup = "RootGroup"; + }; + + //Material used to preview other materials in the editor. + singleton Material(materialEd_previewMaterial) + { + mapTo = "matEd_mappedMat"; + diffuseMap[0] = "tools/materialeditor/gui/matEd_mappedMat"; + }; + + singleton CustomMaterial( materialEd_justAlphaMaterial ) + { + mapTo = "matEd_mappedMatB"; + texture[0] = materialEd_previewMaterial.diffuseMap[0]; + }; + + //Custom shader to allow the display of just the alpha channel. + singleton ShaderData( materialEd_justAlphaShader ) + { + DXVertexShaderFile = "shaders/alphaOnlyV.hlsl"; + DXPixelShaderFile = "shaders/alphaOnlyP.hlsl"; + pixVersion = 1.0; + }; +} + +function MaterialEditorGui::open(%this) +{ + MaterialEditorGui.establishMaterials(); + + // We hide these specific windows here due too there non-modal nature. + // These guis are also pushed onto Canvas, which means they shouldn't be parented + // by editorgui + materialSelector.setVisible(0); + matEdSaveDialog.setVisible(0); + + MaterialEditorPropertiesWindow-->matEd_cubemapEditBtn.setVisible(0); + + //Setup our dropdown menu contents. + //Blending Modes + MaterialEditorPropertiesWindow-->blendingTypePopUp.clear(); + MaterialEditorPropertiesWindow-->blendingTypePopUp.add(None,0); + MaterialEditorPropertiesWindow-->blendingTypePopUp.add(Mul,1); + MaterialEditorPropertiesWindow-->blendingTypePopUp.add(Add,2); + MaterialEditorPropertiesWindow-->blendingTypePopUp.add(AddAlpha,3); + MaterialEditorPropertiesWindow-->blendingTypePopUp.add(Sub,4); + MaterialEditorPropertiesWindow-->blendingTypePopUp.add(LerpAlpha,5); + MaterialEditorPropertiesWindow-->blendingTypePopUp.setSelected( 0, false ); + + //Reflection Types + MaterialEditorPropertiesWindow-->reflectionTypePopUp.clear(); + MaterialEditorPropertiesWindow-->reflectionTypePopUp.add("None",0); + MaterialEditorPropertiesWindow-->reflectionTypePopUp.add("cubemap",1); + MaterialEditorPropertiesWindow-->reflectionTypePopUp.setSelected( 0, false ); + + //Sounds + MaterialEditorPropertiesWindow-->footstepSoundPopup.clear(); + MaterialEditorPropertiesWindow-->impactSoundPopup.clear(); + + %sounds = "<None>" TAB "<Soft>" TAB "<Hard>" TAB "<Metal>" TAB "<Snow>"; // Default sounds + + // Get custom sound datablocks + foreach (%db in DataBlockSet) + { + if (%db.isMemberOfClass("SFXTrack")) + %sounds = %sounds TAB %db.getName(); + } + + %count = getFieldCount(%sounds); + for (%i = 0; %i < %count; %i++) + { + %name = getField(%sounds, %i); + MaterialEditorPropertiesWindow-->footstepSoundPopup.add(%name); + MaterialEditorPropertiesWindow-->impactSoundPopup.add(%name); + } + + //Preview Models + matEd_quickPreview_Popup.clear(); + matEd_quickPreview_Popup.add("Cube",0); + matEd_quickPreview_Popup.add("Sphere",1); + matEd_quickPreview_Popup.add("Pyramid",2); + matEd_quickPreview_Popup.add("Cylinder",3); + matEd_quickPreview_Popup.add("Torus",4); + matEd_quickPreview_Popup.add("Knot",5); + matEd_quickPreview_Popup.setSelected( 0, false ); + matEd_quickPreview_Popup.selected = matEd_quickPreview_Popup.getText(); + + MaterialEditorPropertiesWindow-->MaterialLayerCtrl.clear(); + MaterialEditorPropertiesWindow-->MaterialLayerCtrl.add("Layer 0",0); + MaterialEditorPropertiesWindow-->MaterialLayerCtrl.add("Layer 1",1); + MaterialEditorPropertiesWindow-->MaterialLayerCtrl.add("Layer 2",2); + MaterialEditorPropertiesWindow-->MaterialLayerCtrl.add("Layer 3",3); + MaterialEditorPropertiesWindow-->MaterialLayerCtrl.setSelected( 0, false ); + + //Sift through the RootGroup and find all loaded material items. + MaterialEditorGui.updateAllFields(); + MaterialEditorGui.updatePreviewObject(); + + // If no selected object; go to material mode. And edit the last selected material + MaterialEditorGui.setMode(); + + MaterialEditorGui.preventUndo = true; + + if( MaterialEditorGui.currentMode $= "Mesh" ) + MaterialEditorGui.prepareActiveObject( true ); + else + MaterialEditorGui.prepareActiveMaterial( "", true ); + + MaterialEditorGui.preventUndo = false; + +} + +function MaterialEditorGui::quit(%this) +{ + // if we quit, restore with notDirty + if(MaterialEditorGui.materialDirty) + { + //keep on doing this + MaterialEditorGui.copyMaterials( notDirtyMaterial, materialEd_previewMaterial ); + MaterialEditorGui.copyMaterials( notDirtyMaterial, MaterialEditorGui.currentMaterial ); + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + MaterialEditorGui.currentMaterial.flush(); + MaterialEditorGui.currentMaterial.reload(); + } + + if( isObject(MaterialEditorGui.currentMaterial) ) + { + MaterialEditorGui.lastMaterial = MaterialEditorGui.currentMaterial.getName(); + } + + MaterialEditorGui.setMaterialNotDirty(); + + // First delete the model so that it releases + // material instances that use the preview materials. + matEd_previewObjectView.deleteModel(); + + // Now we can delete the preview materials and shaders + // knowing that there are no matinstances using them. + matEdCubeMapPreviewMat.delete(); + materialEd_previewMaterial.delete(); + materialEd_justAlphaMaterial.delete(); + materialEd_justAlphaShader.delete(); +} + +function MaterialEditorGui::openFile( %this, %fileType ) +{ + switch$(%fileType) + { + case "Texture": %filters = MaterialEditorGui.textureFormats; + + if(MaterialEditorGui.lastTextureFile $= "") + %defaultFileName = "*.*"; + else + %defaultFileName = MaterialEditorGui.lastTextureFile; + + %defaultPath = MaterialEditorGui.lastTexturePath; + + case "Model": %filters = MaterialEditorGui.modelFormats; + %defaultFileName = "*.dts"; + %defaultPath = MaterialEditorGui.lastModelPath; + } + + %dlg = new OpenFileDialog() + { + Filters = %filters; + DefaultPath = %defaultPath; + DefaultFile = %defaultFileName; + ChangePath = false; + MustExist = true; + }; + + %ret = %dlg.Execute(); + if(%ret) + { + switch$(%fileType) + { + case "Texture": + MaterialEditorGui.lastTexturePath = filePath( %dlg.FileName ); + MaterialEditorGui.lastTextureFile = %filename = %dlg.FileName; + + case "Model": + MaterialEditorGui.lastModelPath = filePath( %dlg.FileName ); + MaterialEditorGui.lastModelFile = %filename = %dlg.FileName; + } + } + + %dlg.delete(); + + if(!%ret) + return; + else + return makeRelativePath( %filename, getMainDotCsDir() ); +} + +//============================================================================== +// SubMaterial(Material Target) -- Supports different ways to grab the +// material from the dropdown list. We're here either because- +// 1. We have switched over from another editor with an object locked in the +// $Tools::materialEditorList variable +// 2. We have selected an object using the Object Editor via the Material Editor + +function SubMaterialSelector::onSelect( %this ) +{ + %material = ""; + + if( MaterialEditorGui.currentMeshMode $= "Model" ) + %material = getMapEntry( %this.getText() ); + else + %material = MaterialEditorGui.currentObject.getFieldValue( %this.getText() ); + + %origMat = %material; + if(%material$="") + %origMat = %material = %this.getText(); + // if there is no material attached to that objects material field or the + // object does not have a valid method to grab a material + if( !isObject( %material ) ) + { + // look for a newMaterial name to grab + // addiitonally, convert "." to "_" in case we have something like: "base.texname" as a material name + // at the end we will have generated material name: "base_texname_mat" + %material = getUniqueName( strreplace(%material, ".", "_") @ "_mat" ); + + new Material(%material) + { + diffuseMap[0] = %origMat; + mapTo = %origMat; + parentGroup = RootGroup; + }; + + eval( "MaterialEditorGui.currentObject." @ strreplace(%this.getText(),".","_") @ " = " @ %material @ ";"); + + if( MaterialEditorGui.currentObject.isMethod("postApply") ) + MaterialEditorGui.currentObject.postApply(); + } + + MaterialEditorGui.prepareActiveMaterial( %material.getId() ); +} + +//============================================================================== +// Select object logic (deciding material/target mode) + +function MaterialEditorGui::setMode( %this ) +{ + MatEdMaterialMode.setVisible(0); + MatEdTargetMode.setVisible(0); + + if( isObject(MaterialEditorGui.currentObject) ) + { + MaterialEditorGui.currentMode = "Mesh"; + MatEdTargetMode.setVisible(1); + } + else + { + MaterialEditorGui.currentMode = "Material"; + MatEdMaterialMode.setVisible(1); + EWorldEditor.clearSelection(); + } +} + +function MaterialEditorGui::prepareActiveObject( %this, %override ) +{ + %obj = $Tools::materialEditorList; + if( MaterialEditorGui.currentObject == %obj && !%override) + return; + + // TSStatics, ShapeBase, and Interiors should have getModelFile methods + if( %obj.isMethod( "getModelFile" ) ) + { + MaterialEditorGui.currentObject = %obj; + + SubMaterialSelector.clear(); + MaterialEditorGui.currentMeshMode = "Model"; + + MaterialEditorGui.setMode(); + + if( MaterialEditorGui.currentObject.isMethod( "getNumDetailLevels" ) ) // Interiors + { + for(%j = 0; %j < MaterialEditorGui.currentObject.getNumDetailLevels(); %j++) + { + %target = "Detail Level " @ %j; + %count = SubMaterialSelector.getCount(); + SubMaterialSelector.addCategory(%target); + + for(%k = 0; %k < MaterialEditorGui.currentObject.getTargetCount(%j); %k++) + { + %target = MaterialEditorGui.currentObject.getTargetName(%j, %k); + %count = SubMaterialSelector.getCount(); + SubMaterialSelector.add(%target); + } + } + } + else // TSStatic and ShapeBase + { + for(%j = 0; %j < MaterialEditorGui.currentObject.getTargetCount(); %j++) + { + %target = MaterialEditorGui.currentObject.getTargetName(%j); + %count = SubMaterialSelector.getCount(); + SubMaterialSelector.add(%target); + } + } + } + else // Other classes that support materials if possible + { + %canSupportMaterial = false; + for( %i = 0; %i < %obj.getFieldCount(); %i++ ) + { + %fieldName = %obj.getField(%i); + + if( %obj.getFieldType(%fieldName) !$= "TypeMaterialName" ) + continue; + + if( !%canSupportMaterial ) + { + MaterialEditorGui.currentObject = %obj; + SubMaterialSelector.clear(); + SubMaterialSelector.add(%fieldName, 0); + } + else + { + %count = SubMaterialSelector.getCount(); + SubMaterialSelector.add(%fieldName, %count); + } + %canSupportMaterial = true; + } + + if( !%canSupportMaterial ) // Non-relevant classes get returned + return; + + MaterialEditorGui.currentMeshMode = "EditorShape"; + MaterialEditorGui.setMode(); + } + + %id = SubMaterialSelector.findText( MaterialEditorGui.currentMaterial.mapTo ); + if( %id != -1 ) + SubMaterialSelector.setSelected( %id ); + else + SubMaterialSelector.setSelected(0); +} + +//============================================================================== +// Helper functions to help create categories and manage category lists + +function MaterialEditorGui::updateAllFields(%this) +{ + matEd_cubemapEd_availableCubemapList.clear(); +} + +function MaterialEditorGui::updatePreviewObject(%this) +{ + %newModel = matEd_quickPreview_Popup.getValue(); + + switch$(%newModel) + { + case "sphere": + matEd_quickPreview_Popup.selected = %newModel; + matEd_previewObjectView.setModel("tools/materialeditor/gui/spherePreview.dts"); + matEd_previewObjectView.setOrbitDistance(4); + + case "cube": + matEd_quickPreview_Popup.selected = %newModel; + matEd_previewObjectView.setModel("tools/materialeditor/gui/cubePreview.dts"); + matEd_previewObjectView.setOrbitDistance(5); + + case "pyramid": + matEd_quickPreview_Popup.selected = %newModel; + matEd_previewObjectView.setModel("tools/materialeditor/gui/pyramidPreview.dts"); + matEd_previewObjectView.setOrbitDistance(5); + + case "cylinder": + matEd_quickPreview_Popup.selected = %newModel; + matEd_previewObjectView.setModel("tools/materialeditor/gui/cylinderPreview.dts"); + matEd_previewObjectView.setOrbitDistance(4.2); + + case "torus": + matEd_quickPreview_Popup.selected = %newModel; + matEd_previewObjectView.setModel("tools/materialeditor/gui/torusPreview.dts"); + matEd_previewObjectView.setOrbitDistance(4.2); + + case "knot": + matEd_quickPreview_Popup.selected = %newModel; + matEd_previewObjectView.setModel("tools/materialeditor/gui/torusknotPreview.dts"); + } +} + +//============================================================================== +// Helper functions to help load and update the preview and active material + +// Finds the selected line in the material list, then makes it active in the editor. +function MaterialEditorGui::prepareActiveMaterial(%this, %material, %override) +{ + // If were not valid, grab the first valid material out of the materialSet + if( !isObject(%material) ) + %material = MaterialSet.getObject(0); + + // Check made in order to avoid loading the same material. Overriding + // made in special cases + if(%material $= MaterialEditorGui.lastMaterial && !%override) + { + return; + } + else + { + if(MaterialEditorGui.materialDirty ) + { + MaterialEditorGui.showSaveDialog( %material ); + return; + } + + MaterialEditorGui.setActiveMaterial(%material); + } +} + +// Updates the preview material to use the same properties as the selected material, +// and makes that material active in the editor. +function MaterialEditorGui::setActiveMaterial( %this, %material ) +{ + // Warn if selecting a CustomMaterial (they can't be properly previewed or edited) + if ( isObject( %material ) && %material.isMemberOfClass( "CustomMaterial" ) ) + { + MessageBoxOK( "Warning", "The selected Material (" @ %material.getName() @ + ") is a CustomMaterial, and cannot be edited using the Material Editor." ); + return; + } + + MaterialEditorGui.currentMaterial = %material; + MaterialEditorGui.lastMaterial = %material; + + // we create or recreate a material to hold in a pristine state + singleton Material(notDirtyMaterial) + { + mapTo = "matEd_mappedMat"; + diffuseMap[0] = "tools/materialEditor/gui/matEd_mappedMat"; + }; + + // Converts the texture files into absolute paths. + MaterialEditorGui.convertTextureFields(); + + // If we're allowing for name changes, make sure to save the name seperately + %this.originalName = MaterialEditorGui.currentMaterial.name; + + // Copy materials over to other references + MaterialEditorGui.copyMaterials( MaterialEditorGui.currentMaterial, materialEd_previewMaterial ); + MaterialEditorGui.copyMaterials( MaterialEditorGui.currentMaterial, notDirtyMaterial ); + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + + // Necessary functionality in order to render correctly + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + MaterialEditorGui.currentMaterial.flush(); + MaterialEditorGui.currentMaterial.reload(); + + MaterialEditorGui.setMaterialNotDirty(); +} + +function MaterialEditorGui::isMatEditorMaterial(%this, %material) +{ + return ( %material.getFilename() $= "" || + %material.getFilename() $= "tools/gui/materialSelector.ed.gui" || + %material.getFilename() $= "tools/materialEditor/scripts/materialEditor.ed.cs" ); +} + +function MaterialEditorGui::setMaterialNotDirty(%this) +{ + %propertyText = "Material Properties"; + %previewText = "Material Preview"; + MaterialEditorPropertiesWindow.text = %propertyText; + MaterialEditorPreviewWindow.text = %previewText; + + MaterialEditorGui.materialDirty = false; + matEd_PersistMan.removeDirty(MaterialEditorGui.currentMaterial); +} + +function MaterialEditorGui::setMaterialDirty(%this) +{ + %propertyText = "Material Properties *"; + %previewText = "Material Preview *"; + MaterialEditorPropertiesWindow.text = %propertyText; + MaterialEditorPreviewWindow.text = %previewText; + + MaterialEditorGui.materialDirty = true; + + // materials created in the material selector are given that as its filename, so we run another check + if( MaterialEditorGui.isMatEditorMaterial( MaterialEditorGui.currentMaterial ) ) + { + if( MaterialEditorGui.currentMaterial.isAutoGenerated() ) + { + %obj = MaterialEditorGui.currentObject; + + if( %obj.interiorFile !$= "" ) + %shapePath = %obj.interiorFile; + else if( %obj.shapeName !$= "" ) + %shapePath = %obj.shapeName; + else if( %obj.isMethod("getDatablock") ) + { + if( %obj.getDatablock().shapeFile !$= "" ) + %shapePath = %obj.getDatablock().shapeFile; + } + + //creating toPath + %k = 0; + while( strpos( %shapePath, "/", %k ) != -1 ) + { + %pos = strpos( %shapePath, "/", %k ); + %k = %pos + 1; + } + %savePath = getSubStr( %shapePath , 0 , %k ); + %savePath = %savePath @ "materials.cs"; + + matEd_PersistMan.setDirty(MaterialEditorGui.currentMaterial, %savePath); + } + else + { + matEd_PersistMan.setDirty(MaterialEditorGui.currentMaterial, "art/materials.cs"); + } + } + else + matEd_PersistMan.setDirty(MaterialEditorGui.currentMaterial); +} + +function MaterialEditorGui::convertTextureFields(%this) +{ + // Find the absolute paths for the texture filenames so that + // we can properly wire up the preview materials and controls. + + for(%diffuseI = 0; %diffuseI < 4; %diffuseI++) + { + %diffuseMap = MaterialEditorGui.currentMaterial.diffuseMap[%diffuseI]; + %diffuseMap = MaterialEditorGui.searchForTexture(MaterialEditorGui.currentMaterial, %diffuseMap); + MaterialEditorGui.currentMaterial.diffuseMap[%diffuseI] = %diffuseMap; + } + + for(%normalI = 0; %normalI < 4; %normalI++) + { + %normalMap = MaterialEditorGui.currentMaterial.normalMap[%normalI]; + %normalMap = MaterialEditorGui.searchForTexture(MaterialEditorGui.currentMaterial, %normalMap); + MaterialEditorGui.currentMaterial.normalMap[%normalI] = %normalMap; + } + + for(%overlayI = 0; %overlayI < 4; %overlayI++) + { + %overlayMap = MaterialEditorGui.currentMaterial.overlayMap[%overlayI]; + %overlayMap = MaterialEditorGui.searchForTexture(MaterialEditorGui.currentMaterial, %overlayMap); + MaterialEditorGui.currentMaterial.overlayMap[%overlayI] = %overlayMap; + } + + for(%detailI = 0; %detailI < 4; %detailI++) + { + %detailMap = MaterialEditorGui.currentMaterial.detailMap[%detailI]; + %detailMap = MaterialEditorGui.searchForTexture(MaterialEditorGui.currentMaterial, %detailMap); + MaterialEditorGui.currentMaterial.detailMap[%detailI] = %detailMap; + } + + for(%detailNormalI = 0; %detailNormalI < 4; %detailNormalI++) + { + %detailNormalMap = MaterialEditorGui.currentMaterial.detailNormalMap[%detailNormalI]; + %detailNormalMap = MaterialEditorGui.searchForTexture(MaterialEditorGui.currentMaterial, %detailNormalMap); + MaterialEditorGui.currentMaterial.detailNormalMap[%detailNormalI] = %detailNormalMap; + } + + for(%lightI = 0; %lightI < 4; %lightI++) + { + %lightMap = MaterialEditorGui.currentMaterial.lightMap[%lightI]; + %lightMap = MaterialEditorGui.searchForTexture(MaterialEditorGui.currentMaterial, %lightMap); + MaterialEditorGui.currentMaterial.lightMap[%lightI] = %lightMap; + } + + for(%toneI = 0; %toneI < 4; %toneI++) + { + %toneMap = MaterialEditorGui.currentMaterial.toneMap[%toneI]; + %toneMap = MaterialEditorGui.searchForTexture(MaterialEditorGui.currentMaterial, %toneMap); + MaterialEditorGui.currentMaterial.toneMap[%toneI] = %toneMap; + } + + for(%specI = 0; %specI < 4; %specI++) + { + %specMap = MaterialEditorGui.currentMaterial.specularMap[%specI]; + %specMap = MaterialEditorGui.searchForTexture(MaterialEditorGui.currentMaterial, %specMap); + MaterialEditorGui.currentMaterial.specularMap[%specI] = %specMap; + } +} + +// still needs to be optimized further +function MaterialEditorGui::searchForTexture(%this,%material, %texture) +{ + if( %texture !$= "" ) + { + // set the find signal as false to start out with + %isFile = false; + // sete the formats we're going to be looping through if need be + %formats = ".png .jpg .dds .bmp .gif .jng .tga"; + + // if the texture contains the correct filepath and name right off the bat, lets use it + if( isFile(%texture) ) + %isFile = true; + else + { + + for( %i = 0; %i < getWordCount(%formats); %i++) + { + %testFileName = %texture @ getWord( %formats, %i ); + if(isFile(%testFileName)) + { + %isFile = true; + break; + } + } + } + + // if we didn't grab a proper name, lets use a string logarithm + if( !%isFile ) + { + %materialDiffuse = %texture; + %materialDiffuse2 = %texture; + + %materialPath = %material.getFilename(); + + if( strchr( %materialDiffuse, "/") $= "" ) + { + %k = 0; + while( strpos( %materialPath, "/", %k ) != -1 ) + { + %count = strpos( %materialPath, "/", %k ); + %k = %count + 1; + } + + %materialsCs = getSubStr( %materialPath , %k , 99 ); + %texture = strreplace( %materialPath, %materialsCs, %texture ); + } + else + %texture = strreplace( %materialPath, %materialPath, %texture ); + + + // lets test the pathing we came up with + if( isFile(%texture) ) + %isFile = true; + else + { + for( %i = 0; %i < getWordCount(%formats); %i++) + { + %testFileName = %texture @ getWord( %formats, %i ); + if(isFile(%testFileName)) + { + %isFile = true; + break; + } + } + } + + // as a last resort to find the proper name + // we have to resolve using find first file functions very very slow + if( !%isFile ) + { + %k = 0; + while( strpos( %materialDiffuse2, "/", %k ) != -1 ) + { + %count = strpos( %materialDiffuse2, "/", %k ); + %k = %count + 1; + } + + %texture = getSubStr( %materialDiffuse2 , %k , 99 ); + for( %i = 0; %i < getWordCount(%formats); %i++) + { + %searchString = "*" @ %texture @ getWord( %formats, %i ); + %testFileName = findFirstFile( %searchString ); + if( isFile(%testFileName) ) + { + %texture = %testFileName; + %isFile = true; + break; + } + } + } + + return %texture; + } + else + return %texture; //Texture exists and can be found - just return the input argument. + } + + return ""; //No texture associated with this property. +} + +function MaterialEditorGui::updateLivePreview(%this,%preview) +{ + // When checkbox is selected, preview the material in real time, if not; then don't + if( %preview ) + MaterialEditorGui.copyMaterials( materialEd_previewMaterial, MaterialEditorGui.currentMaterial ); + else + MaterialEditorGui.copyMaterials( notDirtyMaterial, MaterialEditorGui.currentMaterial ); + + MaterialEditorGui.currentMaterial.flush(); + MaterialEditorGui.currentMaterial.reload(); +} + +function MaterialEditorGui::copyMaterials( %this, %copyFrom, %copyTo) +{ + // Make sure we copy and restore the map to. + %mapTo = %copyTo.mapTo; + %copyTo.assignFieldsFrom( %copyFrom ); + %copyTo.mapTo = %mapTo; + +} + +function MaterialEditorGui::guiSync( %this, %material ) +{ + %this.preventUndo = true; + //Setup our headers + if( MaterialEditorGui.currentMode $= "material" ) + { + MatEdMaterialMode-->selMaterialName.setText(MaterialEditorGui.currentMaterial.name); + MatEdMaterialMode-->selMaterialMapTo.setText(MaterialEditorGui.currentMaterial.mapTo); + } + else + { + if( MaterialEditorGui.currentObject.isMethod("getModelFile") ) + { + %sourcePath = MaterialEditorGui.currentObject.getModelFile(); + if( %sourcePath !$= "" ) + { + MatEdTargetMode-->selMaterialMapTo.ToolTip = %sourcePath; + %sourceName = fileName(%sourcePath); + MatEdTargetMode-->selMaterialMapTo.setText(%sourceName); + MatEdTargetMode-->selMaterialName.setText(MaterialEditorGui.currentMaterial.name); + } + } + else + { + %info = MaterialEditorGui.currentObject.getClassName(); + MatEdTargetMode-->selMaterialMapTo.ToolTip = %info; + MatEdTargetMode-->selMaterialMapTo.setText(%info); + MatEdTargetMode-->selMaterialName.setText(MaterialEditorGui.currentMaterial.name); + } + } + + MaterialEditorPropertiesWindow-->alphaRefTextEdit.setText((%material).alphaRef); + MaterialEditorPropertiesWindow-->alphaRefSlider.setValue((%material).alphaRef); + MaterialEditorPropertiesWindow-->doubleSidedCheckBox.setValue((%material).doubleSided); + MaterialEditorPropertiesWindow-->transZWriteCheckBox.setValue((%material).translucentZWrite); + MaterialEditorPropertiesWindow-->alphaTestCheckBox.setValue((%material).alphaTest); + MaterialEditorPropertiesWindow-->castShadows.setValue((%material).castShadows); + MaterialEditorPropertiesWindow-->translucentCheckbox.setValue((%material).translucent); + + switch$((%material).translucentBlendOp) + { + case "None": %selectedNum = 0; + case "Mul": %selectedNum = 1; + case "Add": %selectedNum = 2; + case "AddAlpha": %selectedNum = 3; + case "Sub": %selectedNum = 4; + case "LerpAlpha": %selectedNum = 5; + } + MaterialEditorPropertiesWindow-->blendingTypePopUp.setSelected(%selectedNum); + + if((%material).cubemap !$= "") + { + MaterialEditorPropertiesWindow-->matEd_cubemapEditBtn.setVisible(1); + MaterialEditorPropertiesWindow-->reflectionTypePopUp.setSelected(1); + } + else if((%material).dynamiccubemap) + { + MaterialEditorPropertiesWindow-->matEd_cubemapEditBtn.setVisible(0); + MaterialEditorPropertiesWindow-->reflectionTypePopUp.setSelected(2); + } + else if((%material).planarReflection) + { + MaterialEditorPropertiesWindow-->matEd_cubemapEditBtn.setVisible(0); + MaterialEditorPropertiesWindow-->reflectionTypePopUp.setSelected(3); + } + else + { + MaterialEditorPropertiesWindow-->matEd_cubemapEditBtn.setVisible(0); + MaterialEditorPropertiesWindow-->reflectionTypePopUp.setSelected(0); + } + + MaterialEditorPropertiesWindow-->effectColor0Swatch.color = (%material).effectColor[0]; + MaterialEditorPropertiesWindow-->effectColor1Swatch.color = (%material).effectColor[1]; + MaterialEditorPropertiesWindow-->showFootprintsCheckbox.setValue((%material).showFootprints); + MaterialEditorPropertiesWindow-->showDustCheckbox.setValue((%material).showDust); + MaterialEditorGui.updateSoundPopup("Footstep", (%material).footstepSoundId, (%material).customFootstepSound); + MaterialEditorGui.updateSoundPopup("Impact", (%material).footstepSoundId, (%material).customFootstepSound); + + //layer specific controls are located here + %layer = MaterialEditorGui.currentLayer; + + if((%material).diffuseMap[%layer] $= "") + { + MaterialEditorPropertiesWindow-->diffuseMapNameText.setText( "None" ); + MaterialEditorPropertiesWindow-->diffuseMapDisplayBitmap.setBitmap( "tools/materialeditor/gui/unknownImage" ); + } + else + { + MaterialEditorPropertiesWindow-->diffuseMapNameText.setText( (%material).diffuseMap[%layer] ); + MaterialEditorPropertiesWindow-->diffuseMapDisplayBitmap.setBitmap( (%material).diffuseMap[%layer] ); + } + + if((%material).normalMap[%layer] $= "") + { + MaterialEditorPropertiesWindow-->normalMapNameText.setText( "None" ); + MaterialEditorPropertiesWindow-->normalMapDisplayBitmap.setBitmap( "tools/materialeditor/gui/unknownImage" ); + } + else + { + MaterialEditorPropertiesWindow-->normalMapNameText.setText( (%material).normalMap[%layer] ); + MaterialEditorPropertiesWindow-->normalMapDisplayBitmap.setBitmap( (%material).normalMap[%layer] ); + } + + if((%material).overlayMap[%layer] $= "") + { + MaterialEditorPropertiesWindow-->overlayMapNameText.setText( "None" ); + MaterialEditorPropertiesWindow-->overlayMapDisplayBitmap.setBitmap( "tools/materialeditor/gui/unknownImage" ); + } + else + { + MaterialEditorPropertiesWindow-->overlayMapNameText.setText( (%material).overlayMap[%layer] ); + MaterialEditorPropertiesWindow-->overlayMapDisplayBitmap.setBitmap( (%material).overlayMap[%layer] ); + } + + if((%material).detailMap[%layer] $= "") + { + MaterialEditorPropertiesWindow-->detailMapNameText.setText( "None" ); + MaterialEditorPropertiesWindow-->detailMapDisplayBitmap.setBitmap( "tools/materialeditor/gui/unknownImage" ); + } + else + { + MaterialEditorPropertiesWindow-->detailMapNameText.setText( (%material).detailMap[%layer] ); + MaterialEditorPropertiesWindow-->detailMapDisplayBitmap.setBitmap( (%material).detailMap[%layer] ); + } + + if((%material).detailNormalMap[%layer] $= "") + { + MaterialEditorPropertiesWindow-->detailNormalMapNameText.setText( "None" ); + MaterialEditorPropertiesWindow-->detailNormalMapDisplayBitmap.setBitmap( "tools/materialeditor/gui/unknownImage" ); + } + else + { + MaterialEditorPropertiesWindow-->detailNormalMapNameText.setText( (%material).detailNormalMap[%layer] ); + MaterialEditorPropertiesWindow-->detailNormalMapDisplayBitmap.setBitmap( (%material).detailNormalMap[%layer] ); + } + + if((%material).lightMap[%layer] $= "") + { + MaterialEditorPropertiesWindow-->lightMapNameText.setText( "None" ); + MaterialEditorPropertiesWindow-->lightMapDisplayBitmap.setBitmap( "tools/materialeditor/gui/unknownImage" ); + } + else + { + MaterialEditorPropertiesWindow-->lightMapNameText.setText( (%material).lightMap[%layer] ); + MaterialEditorPropertiesWindow-->lightMapDisplayBitmap.setBitmap( (%material).lightMap[%layer] ); + } + + if((%material).toneMap[%layer] $= "") + { + MaterialEditorPropertiesWindow-->toneMapNameText.setText( "None" ); + MaterialEditorPropertiesWindow-->toneMapDisplayBitmap.setBitmap( "tools/materialeditor/gui/unknownImage" ); + } + else + { + MaterialEditorPropertiesWindow-->toneMapNameText.setText( (%material).toneMap[%layer] ); + MaterialEditorPropertiesWindow-->toneMapDisplayBitmap.setBitmap( (%material).toneMap[%layer] ); + } + + if((%material).specularMap[%layer] $= "") + { + MaterialEditorPropertiesWindow-->specMapNameText.setText( "None" ); + MaterialEditorPropertiesWindow-->specMapDisplayBitmap.setBitmap( "tools/materialeditor/gui/unknownImage" ); + } + else + { + MaterialEditorPropertiesWindow-->specMapNameText.setText( (%material).specularMap[%layer] ); + MaterialEditorPropertiesWindow-->specMapDisplayBitmap.setBitmap( (%material).specularMap[%layer] ); + } + + MaterialEditorPropertiesWindow-->detailScaleTextEdit.setText( getWord((%material).detailScale[%layer], 0) ); + MaterialEditorPropertiesWindow-->detailNormalStrengthTextEdit.setText( getWord((%material).detailNormalMapStrength[%layer], 0) ); + + MaterialEditorPropertiesWindow-->colorTintSwatch.color = (%material).diffuseColor[%layer]; + MaterialEditorPropertiesWindow-->specularColorSwatch.color = (%material).specular[%layer]; + + MaterialEditorPropertiesWindow-->specularPowerTextEdit.setText((%material).specularPower[%layer]); + MaterialEditorPropertiesWindow-->specularPowerSlider.setValue((%material).specularPower[%layer]); + MaterialEditorPropertiesWindow-->pixelSpecularCheckbox.setValue((%material).pixelSpecular[%layer]); + MaterialEditorPropertiesWindow-->glowCheckbox.setValue((%material).glow[%layer]); + MaterialEditorPropertiesWindow-->emissiveCheckbox.setValue((%material).emissive[%layer]); + MaterialEditorPropertiesWindow-->parallaxTextEdit.setText((%material).parallaxScale[%layer]); + MaterialEditorPropertiesWindow-->parallaxSlider.setValue((%material).parallaxScale[%layer]); + + MaterialEditorPropertiesWindow-->useAnisoCheckbox.setValue((%material).useAnisotropic[%layer]); + MaterialEditorPropertiesWindow-->vertLitCheckbox.setValue((%material).vertLit[%layer]); + MaterialEditorPropertiesWindow-->vertColorSwatch.color = (%material).vertColor[%layer]; + MaterialEditorPropertiesWindow-->subSurfaceCheckbox.setValue((%material).subSurface[%layer]); + MaterialEditorPropertiesWindow-->subSurfaceColorSwatch.color = (%material).subSurfaceColor[%layer]; + MaterialEditorPropertiesWindow-->subSurfaceRolloffTextEdit.setText((%material).subSurfaceRolloff[%layer]); + MaterialEditorPropertiesWindow-->minnaertTextEdit.setText((%material).minnaertConstant[%layer]); + + // Animation properties + MaterialEditorPropertiesWindow-->RotationAnimation.setValue(0); + MaterialEditorPropertiesWindow-->ScrollAnimation.setValue(0); + MaterialEditorPropertiesWindow-->WaveAnimation.setValue(0); + MaterialEditorPropertiesWindow-->ScaleAnimation.setValue(0); + MaterialEditorPropertiesWindow-->SequenceAnimation.setValue(0); + + %flags = (%material).getAnimFlags(%layer); + %wordCount = getWordCount( %flags ); + for(%i = 0; %i != %wordCount; %i++) + { + switch$(getWord( %flags, %i)) + { + case "$rotate": MaterialEditorPropertiesWindow-->RotationAnimation.setValue(1); + case "$scroll": MaterialEditorPropertiesWindow-->ScrollAnimation.setValue(1); + case "$wave": MaterialEditorPropertiesWindow-->WaveAnimation.setValue(1); + case "$scale": MaterialEditorPropertiesWindow-->ScaleAnimation.setValue(1); + case "$sequence": MaterialEditorPropertiesWindow-->SequenceAnimation.setValue(1); + } + } + + MaterialEditorPropertiesWindow-->RotationTextEditU.setText( getWord((%material).rotPivotOffset[%layer], 0) ); + MaterialEditorPropertiesWindow-->RotationTextEditV.setText( getWord((%material).rotPivotOffset[%layer], 1) ); + MaterialEditorPropertiesWindow-->RotationSpeedTextEdit.setText( (%material).rotSpeed[%layer] ); + MaterialEditorPropertiesWindow-->RotationSliderU.setValue( getWord((%material).rotPivotOffset[%layer], 0) ); + MaterialEditorPropertiesWindow-->RotationSliderV.setValue( getWord((%material).rotPivotOffset[%layer], 1) ); + MaterialEditorPropertiesWindow-->RotationSpeedSlider.setValue( (%material).rotSpeed[%layer] ); + MaterialEditorPropertiesWindow-->RotationCrosshair.setPosition( 45*mAbs(getWord((%material).rotPivotOffset[%layer], 0))-2, 45*mAbs(getWord((%material).rotPivotOffset[%layer], 1))-2 ); + + MaterialEditorPropertiesWindow-->ScrollTextEditU.setText( getWord((%material).scrollDir[%layer], 0) ); + MaterialEditorPropertiesWindow-->ScrollTextEditV.setText( getWord((%material).scrollDir[%layer], 1) ); + MaterialEditorPropertiesWindow-->ScrollSpeedTextEdit.setText( (%material).scrollSpeed[%layer] ); + MaterialEditorPropertiesWindow-->ScrollSliderU.setValue( getWord((%material).scrollDir[%layer], 0) ); + MaterialEditorPropertiesWindow-->ScrollSliderV.setValue( getWord((%material).scrollDir[%layer], 1) ); + MaterialEditorPropertiesWindow-->ScrollSpeedSlider.setValue( (%material).scrollSpeed[%layer] ); + MaterialEditorPropertiesWindow-->ScrollCrosshair.setPosition( -(23 * getWord((%material).scrollDir[%layer], 0))+20, -(23 * getWord((%material).scrollDir[%layer], 1))+20); + + %waveType = (%material).waveType[%layer]; + for( %radioButton = 0; %radioButton < MaterialEditorPropertiesWindow-->WaveButtonContainer.getCount(); %radioButton++ ) + { + if( %waveType $= MaterialEditorPropertiesWindow-->WaveButtonContainer.getObject(%radioButton).waveType ) + MaterialEditorPropertiesWindow-->WaveButtonContainer.getObject(%radioButton).setStateOn(1); + } + + MaterialEditorPropertiesWindow-->WaveTextEditAmp.setText( (%material).waveAmp[%layer] ); + MaterialEditorPropertiesWindow-->WaveTextEditFreq.setText( (%material).waveFreq[%layer] ); + MaterialEditorPropertiesWindow-->WaveSliderAmp.setValue( (%material).waveAmp[%layer] ); + MaterialEditorPropertiesWindow-->WaveSliderFreq.setValue( (%material).waveFreq[%layer] ); + + %numFrames = mRound( 1 / (%material).sequenceSegmentSize[%layer] ); + + MaterialEditorPropertiesWindow-->SequenceTextEditFPS.setText( (%material).sequenceFramePerSec[%layer] ); + MaterialEditorPropertiesWindow-->SequenceTextEditSSS.setText( %numFrames ); + MaterialEditorPropertiesWindow-->SequenceSliderFPS.setValue( (%material).sequenceFramePerSec[%layer] ); + MaterialEditorPropertiesWindow-->SequenceSliderSSS.setValue( %numFrames ); + + %this.preventUndo = false; +} + +//======================================= +// Material Update Functionality + +function MaterialEditorGui::changeLayer( %this, %layer ) +{ + if( MaterialEditorGui.currentLayer == getWord(%layer, 1) ) + return; + + MaterialEditorGui.currentLayer = getWord(%layer, 1); + MaterialEditorGui.guiSync( materialEd_previewMaterial ); +} + +function MaterialEditorGui::updateActiveMaterial(%this, %propertyField, %value, %isSlider, %onMouseUp) +{ + MaterialEditorGui.setMaterialDirty(); + + if(%value $= "") + %value = "\"\""; + + // Here is where we handle undo actions with slider controls. We want to be able to + // undo every onMouseUp; so we overrite the same undo action when necessary in order + // to achieve this desired effect. + %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1); + if((%last != -1) && (%last.isSlider) && (!%last.onMouseUp)) + { + %last.field = %propertyField; + %last.isSlider = %isSlider; + %last.onMouseUp = %onMouseUp; + %last.newValue = %value; + } + else + { + %action = %this.createUndo(ActionUpdateActiveMaterial, "Update Active Material"); + %action.material = MaterialEditorGui.currentMaterial; + %action.object = MaterialEditorGui.currentObject; + %action.field = %propertyField; + %action.isSlider = %isSlider; + %action.onMouseUp = %onMouseUp; + %action.newValue = %value; + eval( "%action.oldValue = " @ MaterialEditorGui.currentMaterial @ "." @ %propertyField @ ";"); + %action.oldValue = "\"" @ %action.oldValue @ "\""; + MaterialEditorGui.submitUndo( %action ); + } + + eval("materialEd_previewMaterial." @ %propertyField @ " = " @ %value @ ";"); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + if (MaterialEditorGui.livePreview == true) + { + eval("MaterialEditorGui.currentMaterial." @ %propertyField @ " = " @ %value @ ";"); + MaterialEditorGui.currentMaterial.flush(); + MaterialEditorGui.currentMaterial.reload(); + } +} + +function MaterialEditorGui::updateActiveMaterialName(%this, %name) +{ + %action = %this.createUndo(ActionUpdateActiveMaterialName, "Update Active Material Name"); + %action.material = MaterialEditorGui.currentMaterial; + %action.object = MaterialEditorGui.currentObject; + %action.oldName = MaterialEditorGui.currentMaterial.getName(); + %action.newName = %name; + MaterialEditorGui.submitUndo( %action ); + + MaterialEditorGui.currentMaterial.setName(%name); + + // Some objects (ConvexShape, DecalRoad etc) reference Materials by name => need + // to find and update all these references so they don't break when we rename the + // Material. + MaterialEditorGui.updateMaterialReferences( MissionGroup, %action.oldName, %action.newName ); +} + +function MaterialEditorGui::updateMaterialReferences( %this, %obj, %oldName, %newName ) +{ + if ( %obj.isMemberOfClass( "SimSet" ) ) + { + // invoke on children + %count = %obj.getCount(); + for ( %i = 0; %i < %count; %i++ ) + %this.updateMaterialReferences( %obj.getObject( %i ), %oldName, %newName ); + } + else + { + %objChanged = false; + + // Change all material fields that use the old material name + %count = %obj.getFieldCount(); + for( %i = 0; %i < %count; %i++ ) + { + %fieldName = %obj.getField( %i ); + if ( ( %obj.getFieldType( %fieldName ) $= "TypeMaterialName" ) && ( %obj.getFieldValue( %fieldName ) $= %oldName ) ) + { + eval( %obj @ "." @ %fieldName @ " = " @ %newName @ ";" ); + %objChanged = true; + } + } + + EWorldEditor.isDirty |= %objChanged; + if ( %objChanged && %obj.isMethod( "postApply" ) ) + %obj.postApply(); + } +} + +// Global Material Options + +function MaterialEditorGui::updateReflectionType( %this, %type ) +{ + if( %type $= "None" ) + { + MaterialEditorPropertiesWindow-->matEd_cubemapEditBtn.setVisible(0); + //Reset material reflection settings on the preview materials + MaterialEditorGui.updateActiveMaterial( "cubeMap", "" ); + MaterialEditorGui.updateActiveMaterial( "dynamicCubemap" , false ); + MaterialEditorGui.updateActiveMaterial( "planarReflection", false ); + } + else + { + if(%type $= "cubeMap") + { + MaterialEditorPropertiesWindow-->matEd_cubemapEditBtn.setVisible(1); + MaterialEditorGui.updateActiveMaterial( %type, materialEd_previewMaterial.cubemap ); + } + else + { + MaterialEditorGui.updateActiveMaterial( %type, true ); + } + } +} + +// Per-Layer Material Options + +// For update maps +// %action : 1 = change map +// %action : 0 = remove map + +function MaterialEditorGui::updateTextureMap( %this, %type, %action ) +{ + %layer = MaterialEditorGui.currentLayer; + + %bitmapCtrl = MaterialEditorPropertiesWindow.findObjectByInternalName( %type @ "MapDisplayBitmap", true ); + %textCtrl = MaterialEditorPropertiesWindow.findObjectByInternalName( %type @ "MapNameText", true ); + + if( %action ) + { + %texture = MaterialEditorGui.openFile("texture"); + if( %texture !$= "" ) + { + %bitmapCtrl.setBitmap(%texture); + + %bitmap = %bitmapCtrl.bitmap; + %bitmap = strreplace(%bitmap,"tools/materialEditor/scripts/",""); + %bitmapCtrl.setBitmap(%bitmap); + %textCtrl.setText(%bitmap); + MaterialEditorGui.updateActiveMaterial(%type @ "Map[" @ %layer @ "]","\"" @ %bitmap @ "\""); + } + } + else + { + %textCtrl.setText("None"); + %bitmapCtrl.setBitmap("tools/materialeditor/gui/unknownImage"); + MaterialEditorGui.updateActiveMaterial(%type @ "Map[" @ %layer @ "]",""); + } +} + +function MaterialEditorGui::updateDetailScale(%this,%newScale) +{ + %layer = MaterialEditorGui.currentLayer; + + %detailScale = "\"" @ %newScale SPC %newScale @ "\""; + MaterialEditorGui.updateActiveMaterial("detailScale[" @ %layer @ "]", %detailScale); +} + +function MaterialEditorGui::updateDetailNormalStrength(%this,%newStrength) +{ + %layer = MaterialEditorGui.currentLayer; + + %detailStrength = "\"" @ %newStrength @ "\""; + MaterialEditorGui.updateActiveMaterial("detailNormalMapStrength[" @ %layer @ "]", %detailStrength); +} + +function MaterialEditorGui::updateSpecMap(%this,%action) +{ + %layer = MaterialEditorGui.currentLayer; + + if( %action ) + { + %texture = MaterialEditorGui.openFile("texture"); + if( %texture !$= "" ) + { + MaterialEditorGui.updateActiveMaterial("pixelSpecular[" @ MaterialEditorGui.currentLayer @ "]", 0); + + MaterialEditorPropertiesWindow-->specMapDisplayBitmap.setBitmap(%texture); + + %bitmap = MaterialEditorPropertiesWindow-->specMapDisplayBitmap.bitmap; + %bitmap = strreplace(%bitmap,"tools/materialEditor/scripts/",""); + MaterialEditorPropertiesWindow-->specMapDisplayBitmap.setBitmap(%bitmap); + MaterialEditorPropertiesWindow-->specMapNameText.setText(%bitmap); + MaterialEditorGui.updateActiveMaterial("specularMap[" @ %layer @ "]","\"" @ %bitmap @ "\""); + } + } + else + { + MaterialEditorPropertiesWindow-->specMapNameText.setText("None"); + MaterialEditorPropertiesWindow-->specMapDisplayBitmap.setBitmap("tools/materialeditor/gui/unknownImage"); + MaterialEditorGui.updateActiveMaterial("specularMap[" @ %layer @ "]",""); + } + + MaterialEditorGui.guiSync( materialEd_previewMaterial ); +} + +function MaterialEditorGui::updateRotationOffset(%this, %isSlider, %onMouseUp) +{ + %layer = MaterialEditorGui.currentLayer; + %X = MaterialEditorPropertiesWindow-->RotationTextEditU.getText(); + %Y = MaterialEditorPropertiesWindow-->RotationTextEditV.getText(); + MaterialEditorPropertiesWindow-->RotationCrosshair.setPosition(45*mAbs(%X)-2, 45*mAbs(%Y)-2); + + MaterialEditorGui.updateActiveMaterial("rotPivotOffset[" @ %layer @ "]","\"" @ %X SPC %Y @ "\"",%isSlider,%onMouseUp); +} + +function MaterialEditorGui::updateRotationSpeed(%this, %isSlider, %onMouseUp) +{ + %layer = MaterialEditorGui.currentLayer; + %speed = MaterialEditorPropertiesWindow-->RotationSpeedTextEdit.getText(); + MaterialEditorGui.updateActiveMaterial("rotSpeed[" @ %layer @ "]",%speed,%isSlider,%onMouseUp); +} + +function MaterialEditorGui::updateScrollOffset(%this, %isSlider, %onMouseUp) +{ + %layer = MaterialEditorGui.currentLayer; + %X = MaterialEditorPropertiesWindow-->ScrollTextEditU.getText(); + %Y = MaterialEditorPropertiesWindow-->ScrollTextEditV.getText(); + MaterialEditorPropertiesWindow-->ScrollCrosshair.setPosition( -(23 * %X)+20, -(23 * %Y)+20); + + MaterialEditorGui.updateActiveMaterial("scrollDir[" @ %layer @ "]","\"" @ %X SPC %Y @ "\"",%isSlider,%onMouseUp); +} + +function MaterialEditorGui::updateScrollSpeed(%this, %isSlider, %onMouseUp) +{ + %layer = MaterialEditorGui.currentLayer; + %speed = MaterialEditorPropertiesWindow-->ScrollSpeedTextEdit.getText(); + MaterialEditorGui.updateActiveMaterial("scrollSpeed[" @ %layer @ "]",%speed,%isSlider,%onMouseUp); +} + +function MaterialEditorGui::updateWaveType(%this) +{ + for( %radioButton = 0; %radioButton < MaterialEditorPropertiesWindow-->WaveButtonContainer.getCount(); %radioButton++ ) + { + if( MaterialEditorPropertiesWindow-->WaveButtonContainer.getObject(%radioButton).getValue() == 1 ) + %type = MaterialEditorPropertiesWindow-->WaveButtonContainer.getObject(%radioButton).waveType; + } + + %layer = MaterialEditorGui.currentLayer; + MaterialEditorGui.updateActiveMaterial("waveType[" @ %layer @ "]", %type); +} + +function MaterialEditorGui::updateWaveAmp(%this, %isSlider, %onMouseUp) +{ + %layer = MaterialEditorGui.currentLayer; + %amp = MaterialEditorPropertiesWindow-->WaveTextEditAmp.getText(); + MaterialEditorGui.updateActiveMaterial("waveAmp[" @ %layer @ "]", %amp, %isSlider, %onMouseUp); +} + +function MaterialEditorGui::updateWaveFreq(%this, %isSlider, %onMouseUp) +{ + %layer = MaterialEditorGui.currentLayer; + %freq = MaterialEditorPropertiesWindow-->WaveTextEditFreq.getText(); + MaterialEditorGui.updateActiveMaterial("waveFreq[" @ %layer @ "]", %freq, %isSlider, %onMouseUp); +} + +function MaterialEditorGui::updateSequenceFPS(%this, %isSlider, %onMouseUp) +{ + %layer = MaterialEditorGui.currentLayer; + %fps = MaterialEditorPropertiesWindow-->SequenceTextEditFPS.getText(); + MaterialEditorGui.updateActiveMaterial("sequenceFramePerSec[" @ %layer @ "]", %fps, %isSlider, %onMouseUp); +} + +function MaterialEditorGui::updateSequenceSSS(%this, %isSlider, %onMouseUp) +{ + %layer = MaterialEditorGui.currentLayer; + %sss = 1 / MaterialEditorPropertiesWindow-->SequenceTextEditSSS.getText(); + MaterialEditorGui.updateActiveMaterial("sequenceSegmentSize[" @ %layer @ "]", %sss, %isSlider, %onMouseUp); +} + +function MaterialEditorGui::updateAnimationFlags(%this) +{ + MaterialEditorGui.setMaterialDirty(); + %single = true; + + if(MaterialEditorPropertiesWindow-->RotationAnimation.getValue() == true) + { + if(%single == true) + %flags = %flags @ "$Rotate"; + else + %flags = %flags @ " | $Rotate"; + + %single = false; + } + if(MaterialEditorPropertiesWindow-->ScrollAnimation.getValue() == true) + { + if(%single == true) + %flags = %flags @ "$Scroll"; + else + %flags = %flags @ " | $Scroll"; + + %single = false; + } + if(MaterialEditorPropertiesWindow-->WaveAnimation.getValue() == true) + { + if(%single == true) + %flags = %flags @ "$Wave"; + else + %flags = %flags @ " | $Wave"; + + %single = false; + } + if(MaterialEditorPropertiesWindow-->ScaleAnimation.getValue() == true) + { + if(%single == true) + %flags = %flags @ "$Scale"; + else + %flags = %flags @ " | $Scale"; + + %single = false; + } + if(MaterialEditorPropertiesWindow-->SequenceAnimation.getValue() == true) + { + if(%single == true) + %flags = %flags @ "$Sequence"; + else + %flags = %flags @ " | $Sequence"; + + %single = false; + } + + if(%flags $= "") + %flags = "\"\""; + + %action = %this.createUndo(ActionUpdateActiveMaterialAnimationFlags, "Update Active Material"); + %action.material = MaterialEditorGui.currentMaterial; + %action.object = MaterialEditorGui.currentObject; + %action.layer = MaterialEditorGui.currentLayer; + + %action.newValue = %flags; + + %oldFlags = MaterialEditorGui.currentMaterial.getAnimFlags(MaterialEditorGui.currentLayer); + if(%oldFlags $= "") + %oldFlags = "\"\""; + + %action.oldValue = %oldFlags; + MaterialEditorGui.submitUndo( %action ); + + eval("materialEd_previewMaterial.animFlags[" @ MaterialEditorGui.currentLayer @ "] = " @ %flags @ ";"); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + if (MaterialEditorGui.livePreview == true) + { + eval("MaterialEditorGui.currentMaterial.animFlags[" @ MaterialEditorGui.currentLayer @ "] = " @ %flags @ ";"); + MaterialEditorGui.currentMaterial.flush(); + MaterialEditorGui.currentMaterial.reload(); + } +} + +//============================================================================== +// Color Picker Helpers - They are all using colorPicker.ed.gui in order to function +// These functions are mainly passed callbacks from getColorI/getColorF callbacks + +function MaterialEditorGui::syncGuiColor(%this, %guiCtrl, %propname, %color) +{ + %layer = MaterialEditorGui.currentLayer; + + %r = getWord(%color,0); + %g = getWord(%color,1); + %b = getWord(%color,2); + %a = getWord(%color,3); + + %colorSwatch = (%r SPC %g SPC %b SPC %a); + %color = "\"" @ %r SPC %g SPC %b SPC %a @ "\""; + + %guiCtrl.color = %colorSwatch; + MaterialEditorGui.updateActiveMaterial(%propName, %color); +} + +//These two functions are focused on object/layer specific functionality +function MaterialEditorGui::updateColorMultiply(%this,%color) +{ + %propName = "diffuseColor[" @ MaterialEditorGui.currentLayer @ "]"; + %this.syncGuiColor(MaterialEditorPropertiesWindow-->colorTintSwatch, %propName, %color); +} + +function MaterialEditorGui::updateSpecularCheckbox(%this,%value) +{ + MaterialEditorGui.updateActiveMaterial("pixelSpecular[" @ MaterialEditorGui.currentLayer @ "]", %value); + MaterialEditorGui.guiSync( materialEd_previewMaterial ); +} + +function MaterialEditorGui::updateSpecular(%this, %color) +{ + %propName = "specular[" @ MaterialEditorGui.currentLayer @ "]"; + %this.syncGuiColor(MaterialEditorPropertiesWindow-->specularColorSwatch, %propName, %color); +} + +function MaterialEditorGui::updateSubSurfaceColor(%this, %color) +{ + %propName = "subSurfaceColor[" @ MaterialEditorGui.currentLayer @ "]"; + %this.syncGuiColor(MaterialEditorPropertiesWindow-->subSurfaceColorSwatch, %propName, %color); +} + +function MaterialEditorGui::updateEffectColor0(%this, %color) +{ + %this.syncGuiColor(MaterialEditorPropertiesWindow-->effectColor0Swatch, "effectColor[0]", %color); +} + +function MaterialEditorGui::updateEffectColor1(%this, %color) +{ + %this.syncGuiColor(MaterialEditorPropertiesWindow-->effectColor1Swatch, "effectColor[1]", %color); +} + +function MaterialEditorGui::updateBehaviorSound(%this, %type, %sound) +{ + %defaultId = -1; + %customName = ""; + + switch$ (%sound) + { + case "<Soft>": %defaultId = 0; + case "<Hard>": %defaultId = 1; + case "<Metal>": %defaultId = 2; + case "<Snow>": %defaultId = 3; + default: %customName = %sound; + } + + %this.updateActiveMaterial(%type @ "SoundId", %defaultId); + %this.updateActiveMaterial("custom" @ %type @ "Sound", %customName); +} + +function MaterialEditorGui::updateSoundPopup(%this, %type, %defaultId, %customName) +{ + %ctrl = MaterialEditorPropertiesWindow.findObjectByInternalName( %type @ "SoundPopup", true ); + + switch (%defaultId) + { + case 0: %name = "<Soft>"; + case 1: %name = "<Hard>"; + case 2: %name = "<Metal>"; + case 3: %name = "<Snow>"; + default: + if (%customName $= "") + %name = "<None>"; + else + %name = %customName; + } + + %r = %ctrl.findText(%name); + if (%r != -1) + %ctrl.setSelected(%r, false); + else + %ctrl.setText(%name); +} + +//These two functions are focused on environment specific functionality +function MaterialEditorGui::updateLightColor(%this, %color) +{ + matEd_previewObjectView.setLightColor(%color); + matEd_lightColorPicker.color = %color; +} + +function MaterialEditorGui::updatePreviewBackground(%this,%color) +{ + matEd_previewBackground.color = %color; + MaterialPreviewBackgroundPicker.color = %color; +} + +function MaterialEditorGui::updateAmbientColor(%this,%color) +{ + matEd_previewObjectView.setAmbientLightColor(%color); + matEd_ambientLightColorPicker.color = %color; +} + +//============================================================================== +// Commands for the Cubemap Editor + +function MaterialEditorGui::selectCubemap(%this) +{ + %cubemap = MaterialEditorGui.currentCubemap; + if(!isObject(%cubemap)) + return; + + MaterialEditorGui.updateActiveMaterial( "cubemap", %cubemap.name ); + MaterialEditorGui.hideCubemapEditor(); +} + +function MaterialEditorGui::cancelCubemap(%this) +{ + %cubemap = MaterialEditorGui.currentCubemap; + + %idx = matEd_cubemapEd_availableCubemapList.findItemText( %cubemap.getName() ); + matEd_cubemapEd_availableCubemapList.setItemText( %idx, notDirtyCubemap.originalName ); + %cubemap.setName( notDirtyCubemap.originalName ); + + MaterialEditorGui.copyCubemaps( notDirtyCubemap, %cubemap ); + MaterialEditorGui.copyCubemaps( notDirtyCubemap, matEdCubeMapPreviewMat); + + %cubemap.updateFaces(); + matEdCubeMapPreviewMat.updateFaces(); +} + +function MaterialEditorGui::showCubemapEditor(%this) +{ + if (matEd_cubemapEditor.isVisible()) + return; + + MaterialEditorGui.currentCubemap = ""; + + matEd_cubemapEditor.setVisible(1); + new PersistenceManager(matEd_cubemapEdPerMan); + MaterialEditorGui.setCubemapNotDirty(); + + for( %i = 0; %i < RootGroup.getCount(); %i++ ) + { + if( RootGroup.getObject(%i).getClassName()!$= "CubemapData" ) + continue; + + for( %k = 0; %k < UnlistedCubemaps.count(); %k++ ) + { + %unlistedFound = 0; + if( UnlistedCubemaps.getValue(%k) $= RootGroup.getObject(%i).name ) + { + %unlistedFound = 1; + break; + } + } + + if( %unlistedFound ) + continue; + + matEd_cubemapEd_availableCubemapList.addItem( RootGroup.getObject(%i).name ); + } + + singleton CubemapData(notDirtyCubemap); + + // if there was no cubemap, pick the first, select, and bail, these are going to take + // care of themselves in the selected function + if( !isObject( MaterialEditorGui.currentMaterial.cubemap ) ) + { + if( matEd_cubemapEd_availableCubemapList.getItemCount() > 0 ) + { + matEd_cubemapEd_availableCubemapList.setSelected(0, true); + return; + } + else + { + // if there are no cubemaps, then create one, select, and bail + %cubemap = MaterialEditorGui.createNewCubemap(); + matEd_cubemapEd_availableCubemapList.addItem( %cubemap.name ); + matEd_cubemapEd_availableCubemapList.setSelected(0, true); + return; + } + } + + // do not directly change activeMat! + MaterialEditorGui.currentCubemap = MaterialEditorGui.currentMaterial.cubemap.getId(); + %cubemap = MaterialEditorGui.currentCubemap; + + notDirtyCubemap.originalName = %cubemap.getName(); + MaterialEditorGui.copyCubemaps( %cubemap, notDirtyCubemap); + MaterialEditorGui.copyCubemaps( %cubemap, matEdCubeMapPreviewMat); + MaterialEditorGui.syncCubemap( %cubemap ); +} + +function MaterialEditorGui::hideCubemapEditor(%this,%cancel) +{ + if(%cancel) + MaterialEditorGui.cancelCubemap(); + + matEd_cubemapEd_availableCubemapList.clearItems(); + matEd_cubemapEdPerMan.delete(); + matEd_cubemapEditor.setVisible(0); +} + +// create category and update current material if there is one +function MaterialEditorGui::addCubemap( %this,%cubemapName ) +{ + if( %cubemapName $= "" ) + { + MessageBoxOK( "Error", "Can not create a cubemap without a valid name."); + return; + } + + for(%i = 0; %i < RootGroup.getCount(); %i++) + { + if( %cubemapName $= RootGroup.getObject(%i).getName() ) + { + MessageBoxOK( "Error", "There is already an object with the same name."); + return; + } + } + + // Create and select a new cubemap + %cubemap = MaterialEditorGui.createNewCubemap( %cubemapName ); + %idx = matEd_cubemapEd_availableCubemapList.addItem( %cubemap.name ); + matEd_cubemapEd_availableCubemapList.setSelected( %idx, true ); + + // material category text field to blank + matEd_addCubemapWindow-->cubemapName.setText(""); +} + +function MaterialEditorGui::createNewCubemap( %this, %cubemap ) +{ + if( %cubemap $= "" ) + { + for(%i = 0; ; %i++) + { + %cubemap = "newCubemap_" @ %i; + if( !isObject(%cubemap) ) + break; + } + } + + new CubemapData(%cubemap) + { + cubeFace[0] = "tools/materialeditor/gui/cube_xNeg"; + cubeFace[1] = "tools/materialeditor/gui/cube_xPos"; + cubeFace[2] = "tools/materialeditor/gui/cube_ZNeg"; + cubeFace[3] = "tools/materialeditor/gui/cube_ZPos"; + cubeFace[4] = "tools/materialeditor/gui/cube_YNeg"; + cubeFace[5] = "tools/materialeditor/gui/cube_YPos"; + + parentGroup = RootGroup; + }; + + matEd_cubemapEdPerMan.setDirty( %cubemap, "art/materials.cs" ); + matEd_cubemapEdPerMan.saveDirty(); + + return %cubemap; +} + +function MaterialEditorGui::setCubemapDirty(%this) +{ + %propertyText = "Create Cubemap *"; + matEd_cubemapEditor.text = %propertyText; + matEd_cubemapEditor.dirty = true; + matEd_cubemapEditor-->saveCubemap.setActive(true); + + %cubemap = MaterialEditorGui.currentCubemap; + + // materials created in the materail selector are given that as its filename, so we run another check + if( MaterialEditorGui.isMatEditorMaterial( %cubemap ) ) + matEd_cubemapEdPerMan.setDirty(%cubemap, "art/materials.cs"); + else + matEd_cubemapEdPerMan.setDirty(%cubemap); +} + +function MaterialEditorGui::setCubemapNotDirty(%this) +{ + %propertyText= strreplace("Create Cubemap" , "*" , ""); + matEd_cubemapEditor.text = %propertyText; + matEd_cubemapEditor.dirty = false; + matEd_cubemapEditor-->saveCubemap.setActive(false); + + %cubemap = MaterialEditorGui.currentCubemap; + matEd_cubemapEdPerMan.removeDirty(%cubemap); +} + +function MaterialEditorGui::showDeleteCubemapDialog(%this) +{ + %idx = matEd_cubemapEd_availableCubemapList.getSelectedItem(); + %cubemap = matEd_cubemapEd_availableCubemapList.getItemText( %idx ); + %cubemap = %cubemap.getId(); + + if( %cubemap == -1 || !isObject(%cubemap) ) + return; + + if( isObject( %cubemap ) ) + { + MessageBoxYesNoCancel("Delete Cubemap?", + "Are you sure you want to delete<br><br>" @ %cubemap.getName() @ "<br><br> Cubemap deletion won't take affect until the engine is quit.", + "MaterialEditorGui.deleteCubemap( " @ %cubemap @ ", " @ %idx @ " );", + "", + "" ); + } +} + +function MaterialEditorGui::deleteCubemap( %this, %cubemap, %idx ) +{ + matEd_cubemapEd_availableCubemapList.deleteItem( %idx ); + + UnlistedCubemaps.add( "unlistedCubemaps", %cubemap.getName() ); + + if( !MaterialEditorGui.isMatEditorMaterial( %cubemap ) ) + { + matEd_cubemapEdPerMan.removeDirty( %cubemap ); + matEd_cubemapEdPerMan.removeObjectFromFile( %cubemap ); + } + + if( matEd_cubemapEd_availableCubemapList.getItemCount() > 0 ) + { + matEd_cubemapEd_availableCubemapList.setSelected(0, true); + } + else + { + // if there are no cubemaps, then create one, select, and bail + %cubemap = MaterialEditorGui.createNewCubemap(); + matEd_cubemapEd_availableCubemapList.addItem( %cubemap.getName() ); + matEd_cubemapEd_availableCubemapList.setSelected(0, true); + } +} + +function matEd_cubemapEd_availableCubemapList::onSelect( %this, %id, %cubemap ) +{ + %cubemap = %cubemap.getId(); + if( MaterialEditorGui.currentCubemap $= %cubemap ) + return; + + if( matEd_cubemapEditor.dirty ) + { + %savedCubemap = MaterialEditorGui.currentCubemap; + MessageBoxYesNoCancel("Save Existing Cubemap?", + "Do you want to save changes to <br><br>" @ %savedCubemap.getName(), + "MaterialEditorGui.saveCubemap(" @ true @ ");", + "MaterialEditorGui.saveCubemapDialogDontSave(" @ %cubemap @ ");", + "MaterialEditorGui.saveCubemapDialogCancel();" ); + } + else + MaterialEditorGui.changeCubemap( %cubemap ); +} + +function MaterialEditorGui::showSaveCubemapDialog( %this ) +{ + %cubemap = MaterialEditorGui.currentCubemap; + if( !isObject(%cubemap) ) + return; + + MessageBoxYesNoCancel("Save Cubemap?", + "Do you want to save changes to <br><br>" @ %cubemap.getName(), + "MaterialEditorGui.saveCubemap( " @ %cubemap @ " );", + "", + "" ); +} + +function MaterialEditorGui::saveCubemap( %this, %cubemap ) +{ + notDirtyCubemap.originalName = %cubemap.getName(); + MaterialEditorGui.copyCubemaps( %cubemap, notDirtyCubemap ); + MaterialEditorGui.copyCubemaps( %cubemap, matEdCubeMapPreviewMat); + + matEd_cubemapEdPerMan.saveDirty(); + + MaterialEditorGui.setCubemapNotDirty(); +} + +function MaterialEditorGui::saveCubemapDialogDontSave( %this, %newCubemap) +{ + //deal with old cubemap first + %oldCubemap = MaterialEditorGui.currentCubemap; + + %idx = matEd_cubemapEd_availableCubemapList.findItemText( %oldCubemap.getName() ); + matEd_cubemapEd_availableCubemapList.setItemText( %idx, notDirtyCubemap.originalName ); + %oldCubemap.setName( notDirtyCubemap.originalName ); + + MaterialEditorGui.copyCubemaps( notDirtyCubemap, %oldCubemap); + MaterialEditorGui.copyCubemaps( notDirtyCubemap, matEdCubeMapPreviewMat); + MaterialEditorGui.syncCubemap( %oldCubemap ); + + MaterialEditorGui.changeCubemap( %newCubemap ); +} + +function MaterialEditorGui::saveCubemapDialogCancel( %this ) +{ + %cubemap = MaterialEditorGui.currentCubemap; + %idx = matEd_cubemapEd_availableCubemapList.findItemText( %cubemap.getName() ); + matEd_cubemapEd_availableCubemapList.clearSelection(); + matEd_cubemapEd_availableCubemapList.setSelected( %idx, true ); +} + +function MaterialEditorGui::changeCubemap( %this, %cubemap ) +{ + MaterialEditorGui.setCubemapNotDirty(); + MaterialEditorGui.currentCubemap = %cubemap; + + notDirtyCubemap.originalName = %cubemap.getName(); + MaterialEditorGui.copyCubemaps( %cubemap, notDirtyCubemap); + MaterialEditorGui.copyCubemaps( %cubemap, matEdCubeMapPreviewMat); + MaterialEditorGui.syncCubemap( %cubemap ); +} + +function MaterialEditorGui::editCubemapImage( %this, %face ) +{ + MaterialEditorGui.setCubemapDirty(); + + %cubemap = MaterialEditorGui.currentCubemap; + %bitmap = MaterialEditorGui.openFile("texture"); + if( %bitmap !$= "" && %bitmap !$= "tools/materialEditor/gui/cubemapBtnBorder" ) + { + %cubemap.cubeFace[%face] = %bitmap; + MaterialEditorGui.copyCubemaps( %cubemap, matEdCubeMapPreviewMat); + MaterialEditorGui.syncCubemap( %cubemap ); + } +} + +function MaterialEditorGui::editCubemapName( %this, %newName ) +{ + MaterialEditorGui.setCubemapDirty(); + + %cubemap = MaterialEditorGui.currentCubemap; + + %idx = matEd_cubemapEd_availableCubemapList.findItemText( %cubemap.getName() ); + matEd_cubemapEd_availableCubemapList.setItemText( %idx, %newName ); + %cubemap.setName(%newName); + + MaterialEditorGui.syncCubemap( %cubemap ); +} + +function MaterialEditorGui::syncCubemap( %this, %cubemap ) +{ + %xpos = MaterialEditorGui.searchForTexture(%cubemap.getName(), %cubemap.cubeFace[0]); + if( %xpos !$= "" ) + matEd_cubemapEd_XPos.setBitmap( %xpos ); + + %xneg = MaterialEditorGui.searchForTexture(%cubemap.getName(), %cubemap.cubeFace[1]); + if( %xneg !$= "" ) + matEd_cubemapEd_XNeg.setBitmap( %xneg ); + + %yneg = MaterialEditorGui.searchForTexture(%cubemap.getName(), %cubemap.cubeFace[2]); + if( %yneg !$= "" ) + matEd_cubemapEd_YNeG.setBitmap( %yneg ); + + %ypos = MaterialEditorGui.searchForTexture(%cubemap.getName(), %cubemap.cubeFace[3]); + if( %ypos !$= "" ) + matEd_cubemapEd_YPos.setBitmap( %ypos ); + + %zpos = MaterialEditorGui.searchForTexture(%cubemap.getName(), %cubemap.cubeFace[4]); + if( %zpos !$= "" ) + matEd_cubemapEd_ZPos.setBitmap( %zpos ); + + %zneg = MaterialEditorGui.searchForTexture(%cubemap.getName(), %cubemap.cubeFace[5]); + if( %zneg !$= "" ) + matEd_cubemapEd_ZNeg.setBitmap( %zneg ); + + matEd_cubemapEd_activeCubemapNameTxt.setText(%cubemap.getName()); + + %cubemap.updateFaces(); + matEdCubeMapPreviewMat.updateFaces(); +} + +function MaterialEditorGui::copyCubemaps( %this, %copyFrom, %copyTo) +{ + %copyTo.cubeFace[0] = %copyFrom.cubeFace[0]; + %copyTo.cubeFace[1] = %copyFrom.cubeFace[1]; + %copyTo.cubeFace[2] = %copyFrom.cubeFace[2]; + %copyTo.cubeFace[3] = %copyFrom.cubeFace[3]; + %copyTo.cubeFace[4] = %copyFrom.cubeFace[4]; + %copyTo.cubeFace[5] = %copyFrom.cubeFace[5]; +} + + +//============================================================================== +// showSaveDialog logic + +function MaterialEditorGui::showSaveDialog( %this, %toMaterial ) +{ + MessageBoxYesNoCancel("Save Material?", + "The material " @ MaterialEditorGui.currentMaterial.getName() @ " has unsaved changes. <br>Do you want to save?", + "MaterialEditorGui.saveDialogSave(" @ %toMaterial @ ");", + "MaterialEditorGui.saveDialogDontSave(" @ %toMaterial @ ");", + "MaterialEditorGui.saveDialogCancel();" ); +} + +function MaterialEditorGui::showMaterialChangeSaveDialog( %this, %toMaterial ) +{ + %fromMaterial = MaterialEditorGui.currentMaterial; + + MessageBoxYesNoCancel("Save Material?", + "The material " @ %fromMaterial.getName() @ " has unsaved changes. <br>Do you want to save before changing the material?", + "MaterialEditorGui.saveDialogSave(" @ %toMaterial @ "); MaterialEditorGui.changeMaterial(" @ %fromMaterial @ ", " @ %toMaterial @ ");", + "MaterialEditorGui.saveDialogDontSave(" @ %toMaterial @ "); MaterialEditorGui.changeMaterial(" @ %fromMaterial @ ", " @ %toMaterial @ ");", + "MaterialEditorGui.saveDialogCancel();" ); +} + +/* +function MaterialEditorGui::showCreateNewMaterialSaveDialog( %this, %toMaterial ) +{ + MessageBoxYesNoCancel("Save Material?", + "The material " @ MaterialEditorGui.currentMaterial.getName() @ " has unsaved changes. <br>Do you want to save before changing the material?", + "MaterialEditorGui.save(); MaterialEditorGui.createNewMaterial(" @ %toMaterial @ ");", + "MaterialEditorGui.saveDialogDontSave(" @ %toMaterial @ "); MaterialEditorGui.changeMaterial(" @ %toMaterial @ ");", + "MaterialEditorGui.saveDialogCancel();" ); +} +*/ + +function MaterialEditorGui::saveDialogCancel( %this ) +{ + MaterialEditorGui.guiSync( materialEd_previewMaterial ); +} + +function MaterialEditorGui::saveDialogDontSave( %this, %material ) +{ + MaterialEditorGui.currentMaterial.setName( %this.originalName ); + + //restore to defaults + MaterialEditorGui.copyMaterials( notDirtyMaterial, MaterialEditorGui.currentMaterial ); + MaterialEditorGui.copyMaterials( notDirtyMaterial, materialEd_previewMaterial ); + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + MaterialEditorGui.currentMaterial.flush(); + MaterialEditorGui.currentMaterial.reload(); + + MaterialEditorGui.setMaterialNotDirty(); + + MaterialEditorGui.setActiveMaterial( %material ); +} + +function MaterialEditorGui::saveDialogSave( %this, %material ) +{ + MaterialEditorGui.save(); + MaterialEditorGui.setActiveMaterial( %material ); +} + +function MaterialEditorGui::save( %this ) +{ + if( MaterialEditorGui.currentMaterial.getName() $= "" ) + { + MessageBoxOK("Cannot perform operation", "Saved materials cannot be named \"\". A name must be given before operation is performed" ); + return; + } + + // Update the live object regardless in this case + MaterialEditorGui.updateLivePreview(true); + + %currentMaterial = MaterialEditorGui.currentMaterial; + if( %currentMaterial == -1 ) + { + MessageBoxOK("Cannot perform operation", "Could not locate material" ); + return; + } + + // Specifically for materials autogenerated from shapes. + if( %currentMaterial.isAutoGenerated() ) + %currentMaterial.setAutoGenerated( false ); + + // Save the material using the persistence manager + matEd_PersistMan.saveDirty(); + + // Clean up the Material Editor + MaterialEditorGui.copyMaterials( materialEd_previewMaterial, notDirtyMaterial ); + MaterialEditorGui.setMaterialNotDirty(); +} + +//============================================================================== +// Create New and Delete Material + +function MaterialEditorGui::createNewMaterial( %this ) +{ + %action = %this.createUndo(ActionCreateNewMaterial, "Create New Material"); + %action.object = ""; + + %material = getUniqueName( "newMaterial" ); + new Material(%material) + { + diffuseMap[0] = "core/art/warnmat"; + mapTo = "unmapped_mat"; + parentGroup = RootGroup; + }; + + %action.newMaterial = %material.getId(); + %action.oldMaterial = MaterialEditorGui.currentMaterial; + + MaterialEditorGui.submitUndo( %action ); + + MaterialEditorGui.currentObject = ""; + MaterialEditorGui.setMode(); + MaterialEditorGui.prepareActiveMaterial( %material.getId(), true ); +} + +function MaterialEditorGui::deleteMaterial( %this ) +{ + %action = %this.createUndo(ActionDeleteMaterial, "Delete Material"); + %action.object = MaterialEditorGui.currentObject; + %action.currentMode = MaterialEditorGui.currentMode; + + /* + if( MaterialEditorGui.currentMode $= "Mesh" ) + { + %materialTarget = SubMaterialSelector.text; + %action.materialTarget = %materialTarget; + + //create the stub material + %toMaterial = getUniqueName( "newMaterial" ); + new Material(%toMaterial) + { + diffuseMap[0] = "core/art/warnmat"; + mapTo = "unmapped_mat"; + parentGroup = RootGroup; + }; + + %action.toMaterial = %toMaterial.getId(); + %action.fromMaterial = MaterialEditorGui.currentMaterial; + %action.fromMaterialOldFname = MaterialEditorGui.currentMaterial.getFilename(); + } + else + { + // Grab first material we see; if theres not one, create one + %toMaterial = MaterialSet.getObject(0); + if( !isObject( %toMaterial ) ) + { + %toMaterial = getUniqueName( "newMaterial" ); + new Material(%toMaterial) + { + diffuseMap[0] = "core/art/warnmat"; + mapTo = "unmapped_mat"; + parentGroup = RootGroup; + }; + } + + %action.toMaterial = %toMaterial.getId(); + %action.fromMaterial = MaterialEditorGui.currentMaterial; + } + */ + + // Grab first material we see; if theres not one, create one + %newMaterial = getUniqueName( "newMaterial" ); + new Material(%newMaterial) + { + diffuseMap[0] = "core/art/warnmat"; + mapTo = "unmapped_mat"; + parentGroup = RootGroup; + }; + + // Setup vars + %action.newMaterial = %newMaterial.getId(); + %action.oldMaterial = MaterialEditorGui.currentMaterial; + %action.oldMaterialFname = MaterialEditorGui.currentMaterial.getFilename(); + + // Submit undo + MaterialEditorGui.submitUndo( %action ); + + // Delete the material from file + if( !MaterialEditorGui.isMatEditorMaterial( MaterialEditorGui.currentMaterial ) ) + { + matEd_PersistMan.removeObjectFromFile(MaterialEditorGui.currentMaterial); + matEd_PersistMan.removeDirty(MaterialEditorGui.currentMaterial); + } + + // Delete the material as seen through the material selector. + UnlistedMaterials.add( "unlistedMaterials", MaterialEditorGui.currentMaterial.getName() ); + + // Loadup another material + MaterialEditorGui.currentObject = ""; + MaterialEditorGui.setMode(); + MaterialEditorGui.prepareActiveMaterial( %newMaterial.getId(), true ); +} + +//============================================================================== +// Clear and Refresh Material + +function MaterialEditorGui::clearMaterial(%this) +{ + %action = %this.createUndo(ActionClearMaterial, "Clear Material"); + %action.material = MaterialEditorGui.currentMaterial; + %action.object = MaterialEditorGui.currentObject; + + pushInstantGroup(); + %action.oldMaterial = new Material(); + %action.newMaterial = new Material(); + popInstantGroup(); + + MaterialEditorGui.submitUndo( %action ); + + MaterialEditorGui.copyMaterials( MaterialEditorGui.currentMaterial, %action.oldMaterial ); + + %tempMat = new Material() + { + name = "tempMaterial"; + mapTo = "unmapped_mat"; + parentGroup = RootGroup; + }; + + MaterialEditorGui.copyMaterials( %tempMat, materialEd_previewMaterial ); + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + if (MaterialEditorGui.livePreview == true) + { + MaterialEditorGui.copyMaterials( %tempMat, MaterialEditorGui.currentMaterial ); + MaterialEditorGui.currentMaterial.flush(); + MaterialEditorGui.currentMaterial.reload(); + } + + MaterialEditorGui.setMaterialDirty(); + + %tempMat.delete(); +} + +function MaterialEditorGui::refreshMaterial(%this) +{ + %action = %this.createUndo(ActionRefreshMaterial, "Refresh Material"); + %action.material = MaterialEditorGui.currentMaterial; + %action.object = MaterialEditorGui.currentObject; + + pushInstantGroup(); + %action.oldMaterial = new Material(); + %action.newMaterial = new Material(); + popInstantGroup(); + + MaterialEditorGui.copyMaterials( MaterialEditorGui.currentMaterial, %action.oldMaterial ); + MaterialEditorGui.copyMaterials( notDirtyMaterial, %action.newMaterial ); + + %action.oldName = MaterialEditorGui.currentMaterial.getName(); + %action.newName = %this.originalName; + + MaterialEditorGui.submitUndo( %action ); + + MaterialEditorGui.currentMaterial.setName( %this.originalName ); + MaterialEditorGui.copyMaterials( notDirtyMaterial, materialEd_previewMaterial ); + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + if (MaterialEditorGui.livePreview == true) + { + MaterialEditorGui.copyMaterials( notDirtyMaterial, MaterialEditorGui.currentMaterial ); + MaterialEditorGui.currentMaterial.flush(); + MaterialEditorGui.currentMaterial.reload(); + } + + MaterialEditorGui.setMaterialNotDirty(); +} + +//============================================================================== +// Switching and Changing Materials + +function MaterialEditorGui::switchMaterial( %this, %material ) +{ + //MaterialEditorGui.currentMaterial = %material.getId(); + MaterialEditorGui.currentObject = ""; + MaterialEditorGui.setMode(); + MaterialEditorGui.prepareActiveMaterial( %material.getId(), true ); +} + +/*------------------------------------------------------------------------------ + This changes the map to's of possibly two materials (%fromMaterial, %toMaterial) + and updates the engines libraries accordingly in order to make this change per + object/per objects instances/per target. Before this functionality is enacted, + there is a popup beforehand that will ask if you are sure if you want to make + this change. Making this change will physically alter possibly two materials.cs + files in order to move the (%fromMaterial, %toMaterial), replacing the + (%fromMaterials)'s mapTo to "unmapped_mat". +-------------------------------------------------------------------------------*/ + +function MaterialEditorGui::changeMaterial(%this, %fromMaterial, %toMaterial) +{ + %action = %this.createUndo(ActionChangeMaterial, "Change Material"); + %action.object = MaterialEditorGui.currentObject; + + %materialTarget = SubMaterialSelector.text; + %action.materialTarget = %materialTarget; + + %action.fromMaterial = %fromMaterial; + %action.toMaterial = %toMaterial; + %action.toMaterialOldFname = %toMaterial.getFilename(); + %action.object = MaterialEditorGui.currentObject; + + if( MaterialEditorGui.currentMeshMode $= "Model" ) // Models + { + %action.mode = "model"; + + MaterialEditorGui.currentObject.changeMaterial( %materialTarget, %fromMaterial.getName(), %toMaterial.getName() ); + + if( MaterialEditorGui.currentObject.interiorFile !$= "" ) + %sourcePath = MaterialEditorGui.currentObject.interiorFile; + else if( MaterialEditorGui.currentObject.shapeName !$= "" ) + %sourcePath = MaterialEditorGui.currentObject.shapeName; + else if( MaterialEditorGui.currentObject.isMethod("getDatablock") ) + { + if( MaterialEditorGui.currentObject.getDatablock().shapeFile !$= "" ) + %sourcePath = MaterialEditorGui.currentObject.getDatablock().shapeFile; + } + + // Creating "to" path + %k = 0; + while( strpos( %sourcePath, "/", %k ) != -1 ) + { + %count = strpos( %sourcePath, "/", %k ); + %k = %count + 1; + } + %fileName = getSubStr( %sourcePath , 0 , %k ); + %fileName = %fileName @ "materials.cs"; + + %action.toMaterialNewFname = %fileName; + + MaterialEditorGui.prepareActiveMaterial( %toMaterial, true ); + if( !MaterialEditorGui.isMatEditorMaterial( %toMaterial ) ) + { + matEd_PersistMan.removeObjectFromFile(%toMaterial); + } + + matEd_PersistMan.setDirty(%fromMaterial); + matEd_PersistMan.setDirty(%toMaterial, %fileName); + matEd_PersistMan.saveDirty(); + + matEd_PersistMan.removeDirty(%fromMaterial); + matEd_PersistMan.removeDirty(%toMaterial); + } + else // EditorShapes + { + %action.mode = "editorShapes"; + + eval("MaterialEditorGui.currentObject." @ SubMaterialSelector.getText() @ " = " @ %toMaterial.getName() @ ";"); + if( MaterialEditorGui.currentObject.isMethod("postApply") ) + MaterialEditorGui.currentObject.postApply(); + + MaterialEditorGui.prepareActiveMaterial( %toMaterial, true ); + } + + MaterialEditorGui.submitUndo( %action ); +} + +//============================================================================== +// Image thumbnail right-clicks. + +// not yet functional +function MaterialEditorMapThumbnail::onRightClick( %this ) +{ + if( !isObject( "MaterialEditorMapThumbnailPopup" ) ) + new PopupMenu( MaterialEditorMapThumbnailPopup ) + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Open File" TAB "" TAB "openFile( %this.filePath );"; + item[ 1 ] = "Open Folder" TAB "" TAB "openFolder( filePath( %this.filePath ) );"; + + filePath = ""; + }; + + // Find the text control containing the filename. + + %textCtrl = %this.parentGroup.findObjectByInternalName( %this.fileNameTextCtrl, true ); + if( !%textCtrl ) + return; + + %fileName = %textCtrl.getText(); + %fullPath = makeFullPath( %fileName, getMainDotCsDir() ); + + // Construct a full path. + + %isValid = isFile( %fullPath ); + if( !%isValid ) + { + if( isFile( %fileName ) ) + { + %fullPath = %fileName; + %isValid = true; + } + else + { + // Try material-relative path. + + %material = MaterialEditorGui.currentMaterial; + if( isObject( %material ) ) + { + %materialPath = filePath( makeFullPath( %material.getFilename(), getMainDotCsDir() ) ); + %fullPath = makeFullPath( %fileName, %materialPath ); + %isValid = isFile( %fullPath ); + } + } + } + + %popup = MaterialEditorMapThumbnailPopup; + %popup.enableItem( 0, %isValid ); + %popup.enableItem( 1, %isValid ); + %popup.filePath = %fullPath; + + %popup.showPopup( Canvas ); +} diff --git a/Templates/Empty/game/tools/materialEditor/scripts/materialEditorUndo.ed.cs b/Templates/Empty/game/tools/materialEditor/scripts/materialEditorUndo.ed.cs new file mode 100644 index 000000000..184f02ce4 --- /dev/null +++ b/Templates/Empty/game/tools/materialEditor/scripts/materialEditorUndo.ed.cs @@ -0,0 +1,477 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function MaterialEditorGui::createUndo(%this, %class, %desc) +{ + pushInstantGroup(); + %action = new UndoScriptAction() + { + class = %class; + superClass = BaseMaterialEdAction; + actionName = %desc; + }; + popInstantGroup(); + return %action; +} + +function MaterialEditorGui::submitUndo(%this, %action) +{ + if(!%this.preventUndo) + %action.addToManager(Editor.getUndoManager()); +} + +function BaseMaterialEdAction::redo(%this) +{ + %this.redo(); +} + +function BaseMaterialEdAction::undo(%this) +{ +} + +// Generic updateActiveMaterial redo/undo + +function ActionUpdateActiveMaterial::redo(%this) +{ + if( MaterialEditorPreviewWindow.isVisible() && MaterialEditorGui.currentMaterial == %this.material ) + { + /* + if( MaterialEditorGui.currentMaterial != %this.material ) + { + MaterialEditorGui.currentObject = %this.object; + MaterialEditorGui.setMode(); + MaterialEditorGui.setActiveMaterial(%this.material); + } + */ + eval("materialEd_previewMaterial." @ %this.field @ " = " @ %this.newValue @ ";"); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + if (MaterialEditorGui.livePreview == true) + { + eval("%this.material." @ %this.field @ " = " @ %this.newValue @ ";"); + MaterialEditorGui.currentMaterial.flush(); + MaterialEditorGui.currentMaterial.reload(); + } + + MaterialEditorGui.preventUndo = true; + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + MaterialEditorGui.setMaterialDirty(); + MaterialEditorGui.preventUndo = false; + } + else + { + eval("%this.material." @ %this.field @ " = " @ %this.newValue @ ";"); + %this.material.flush(); + %this.material.reload(); + } +} + +function ActionUpdateActiveMaterial::undo(%this) +{ + MaterialEditorGui.preventUndo = true; + if( MaterialEditorPreviewWindow.isVisible() && MaterialEditorGui.currentMaterial == %this.material ) + { + /* + if( MaterialEditorGui.currentMaterial != %this.material ) + { + MaterialEditorGui.currentObject = %this.object; + MaterialEditorGui.setMode(); + MaterialEditorGui.setActiveMaterial(%this.material); + } + */ + + eval("materialEd_previewMaterial." @ %this.field @ " = " @ %this.oldValue @ ";"); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + if (MaterialEditorGui.livePreview == true) + { + eval("%this.material." @ %this.field @ " = " @ %this.oldValue @ ";"); + MaterialEditorGui.currentMaterial.flush(); + MaterialEditorGui.currentMaterial.reload(); + } + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + MaterialEditorGui.setMaterialDirty(); + } + else + { + eval("%this.material." @ %this.field @ " = " @ %this.oldValue @ ";"); + %this.material.flush(); + %this.material.reload(); + } + + MaterialEditorGui.preventUndo = false; +} + +// Special case updateActiveMaterial redo/undo + +function ActionUpdateActiveMaterialAnimationFlags::redo(%this) +{ + if( MaterialEditorPreviewWindow.isVisible() && MaterialEditorGui.currentMaterial == %this.material ) + { + /* + if( MaterialEditorGui.currentMaterial != %this.material ) + { + MaterialEditorGui.currentObject = %this.object; + MaterialEditorGui.setMode(); + MaterialEditorGui.setActiveMaterial(%this.material); + } + */ + + eval("materialEd_previewMaterial.animFlags[" @ %this.layer @ "] = " @ %this.newValue @ ";"); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + if (MaterialEditorGui.livePreview == true) + { + eval("%this.material.animFlags[" @ %this.layer @ "] = " @ %this.newValue @ ";"); + MaterialEditorGui.currentMaterial.flush(); + MaterialEditorGui.currentMaterial.reload(); + } + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + MaterialEditorGui.setMaterialDirty(); + } + else + { + eval("%this.material.animFlags[" @ %this.layer @ "] = " @ %this.newValue @ ";"); + %this.material.flush(); + %this.material.reload(); + } +} + +function ActionUpdateActiveMaterialAnimationFlags::undo(%this) +{ + if( MaterialEditorPreviewWindow.isVisible() && MaterialEditorGui.currentMaterial == %this.material ) + { + eval("materialEd_previewMaterial.animFlags[" @ %this.layer @ "] = " @ %this.oldValue @ ";"); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + if (MaterialEditorGui.livePreview == true) + { + eval("%this.material.animFlags[" @ %this.layer @ "] = " @ %this.oldValue @ ";"); + MaterialEditorGui.currentMaterial.flush(); + MaterialEditorGui.currentMaterial.reload(); + } + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + MaterialEditorGui.setMaterialDirty(); + } + else + { + eval("%this.material.animFlags[" @ %this.layer @ "] = " @ %this.oldValue @ ";"); + %this.material.flush(); + %this.material.reload(); + } +} + +function ActionUpdateActiveMaterialName::redo(%this) +{ + %this.material.setName(%this.newName); + MaterialEditorGui.updateMaterialReferences( MissionGroup, %this.oldName, %this.newName ); + + if( MaterialEditorPreviewWindow.isVisible() && MaterialEditorGui.currentMaterial == %this.material ) + { + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + MaterialEditorGui.setMaterialDirty(); + } +} + +function ActionUpdateActiveMaterialName::undo(%this) +{ + %this.material.setName(%this.oldName); + MaterialEditorGui.updateMaterialReferences( MissionGroup, %this.newName, %this.oldName ); + + if( MaterialEditorPreviewWindow.isVisible() && MaterialEditorGui.currentMaterial == %this.material ) + { + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + MaterialEditorGui.setMaterialDirty(); + } +} + +function ActionRefreshMaterial::redo(%this) +{ + if( MaterialEditorPreviewWindow.isVisible() && MaterialEditorGui.currentMaterial == %this.material ) + { + %this.material.setName( %this.newName ); + + MaterialEditorGui.copyMaterials( %this.newMaterial, materialEd_previewMaterial ); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + if (MaterialEditorGui.livePreview == true) + { + MaterialEditorGui.copyMaterials( %this.newMaterial , %this.material ); + %this.material.flush(); + %this.material.reload(); + } + + + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + MaterialEditorGui.setMaterialNotDirty(); + } + else + { + MaterialEditorGui.copyMaterials( %this.newMaterial, %this.material ); + %this.material.flush(); + %this.material.reload(); + } +} + +function ActionRefreshMaterial::undo(%this) +{ + if( MaterialEditorPreviewWindow.isVisible() && MaterialEditorGui.currentMaterial == %this.material ) + { + %this.material.setName( %this.oldName ); + + MaterialEditorGui.copyMaterials( %this.oldMaterial, materialEd_previewMaterial ); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + if (MaterialEditorGui.livePreview == true) + { + MaterialEditorGui.copyMaterials( %this.oldMaterial, %this.material ); + %this.material.flush(); + %this.material.reload(); + } + + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + MaterialEditorGui.setMaterialDirty(); + } + else + { + MaterialEditorGui.copyMaterials( %this.oldMaterial, %this.material ); + %this.material.flush(); + %this.material.reload(); + } +} + +function ActionClearMaterial::redo(%this) +{ + if( MaterialEditorPreviewWindow.isVisible() && MaterialEditorGui.currentMaterial == %this.material ) + { + MaterialEditorGui.copyMaterials( %this.newMaterial, materialEd_previewMaterial ); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + if (MaterialEditorGui.livePreview == true) + { + MaterialEditorGui.copyMaterials( %this.newMaterial, %this.material ); + %this.material.flush(); + %this.material.reload(); + } + + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + MaterialEditorGui.setMaterialDirty(); + } + else + { + MaterialEditorGui.copyMaterials( %this.newMaterial, %this.material ); + %this.material.flush(); + %this.material.reload(); + } +} + +function ActionClearMaterial::undo(%this) +{ + if( MaterialEditorPreviewWindow.isVisible() && MaterialEditorGui.currentMaterial == %this.material ) + { + MaterialEditorGui.copyMaterials( %this.oldMaterial, materialEd_previewMaterial ); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + if (MaterialEditorGui.livePreview == true) + { + MaterialEditorGui.copyMaterials( %this.oldMaterial, %this.material ); + %this.material.flush(); + %this.material.reload(); + } + + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + MaterialEditorGui.setMaterialDirty(); + } + else + { + MaterialEditorGui.copyMaterials( %this.oldMaterial, %this.material ); + %this.material.flush(); + %this.material.reload(); + } +} + +function ActionChangeMaterial::redo(%this) +{ + if( %this.mode $= "model" ) + { + %this.object.changeMaterial( %this.materialTarget, %this.fromMaterial.getName(), %this.toMaterial.getName() ); + + MaterialEditorGui.currentObject = %this.object; + + if( %this.toMaterial.getFilename() !$= "tools/gui/materialSelector.ed.gui" || + %this.toMaterial.getFilename() !$= "tools/materialEditor/scripts/materialEditor.ed.cs") + { + matEd_PersistMan.removeObjectFromFile(%this.toMaterial); + } + + matEd_PersistMan.setDirty(%this.fromMaterial); + matEd_PersistMan.setDirty(%this.toMaterial, %this.toMaterialNewFname); + matEd_PersistMan.saveDirty(); + + matEd_PersistMan.removeDirty(%this.fromMaterial); + matEd_PersistMan.removeDirty(%this.toMaterial); + } + else + { + eval("%this.object." @ %this.materialTarget @ " = " @ %this.toMaterial.getName() @ ";"); + MaterialEditorGui.currentObject.postApply(); + } + + if( MaterialEditorPreviewWindow.isVisible() ) + MaterialEditorGui.setActiveMaterial( %this.toMaterial ); +} + +function ActionChangeMaterial::undo(%this) +{ + if( %this.mode $= "model" ) + { + %this.object.changeMaterial( %this.materialTarget, %this.toMaterial.getName(), %this.fromMaterial.getName() ); + + MaterialEditorGui.currentObject = %this.object; + + if( %this.toMaterial.getFilename() !$= "tools/gui/materialSelector.ed.gui" || + %this.toMaterial.getFilename() !$= "tools/materialEditor/scripts/materialEditor.ed.cs") + { + matEd_PersistMan.removeObjectFromFile(%this.toMaterial); + } + + + matEd_PersistMan.setDirty(%this.fromMaterial); + matEd_PersistMan.setDirty(%this.toMaterial, %this.toMaterialOldFname); + matEd_PersistMan.saveDirty(); + + matEd_PersistMan.removeDirty(%this.fromMaterial); + matEd_PersistMan.removeDirty(%this.toMaterial); + } + else + { + eval("%this.object." @ %this.materialTarget @ " = " @ %this.fromMaterial.getName() @ ";"); + MaterialEditorGui.currentObject.postApply(); + } + + if( MaterialEditorPreviewWindow.isVisible() ) + MaterialEditorGui.setActiveMaterial( %this.fromMaterial ); +} + +function ActionCreateNewMaterial::redo(%this) +{ + if( MaterialEditorPreviewWindow.isVisible() ) + { + if( MaterialEditorGui.currentMaterial != %this.newMaterial ) + { + MaterialEditorGui.currentObject = ""; + MaterialEditorGui.setMode(); + MaterialEditorGui.setActiveMaterial(%this.newMaterial); + } + + MaterialEditorGui.copyMaterials( %this.newMaterial, materialEd_previewMaterial ); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + } + + %idx = UnlistedMaterials.getIndexFromValue( %this.newMaterial.getName() ); + UnlistedMaterials.erase( %idx ); +} + +function ActionCreateNewMaterial::undo(%this) +{ + if( MaterialEditorPreviewWindow.isVisible() ) + { + if( MaterialEditorGui.currentMaterial != %this.oldMaterial ) + { + MaterialEditorGui.currentObject = ""; + MaterialEditorGui.setMode(); + MaterialEditorGui.setActiveMaterial(%this.oldMaterial); + } + + MaterialEditorGui.copyMaterials( %this.oldMaterial, materialEd_previewMaterial ); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + } + + UnlistedMaterials.add( "unlistedMaterials", %this.newMaterial.getName() ); +} + +function ActionDeleteMaterial::redo(%this) +{ + if( MaterialEditorPreviewWindow.isVisible() ) + { + if( MaterialEditorGui.currentMaterial != %this.newMaterial ) + { + MaterialEditorGui.currentObject = ""; + MaterialEditorGui.setMode(); + MaterialEditorGui.setActiveMaterial(%this.newMaterial); + } + + MaterialEditorGui.copyMaterials( %this.newMaterial, materialEd_previewMaterial ); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + } + + if( %this.oldMaterial.getFilename() !$= "tools/gui/materialSelector.ed.gui" || + %this.oldMaterial.getFilename() !$= "tools/materialEditor/scripts/materialEditor.ed.cs") + { + matEd_PersistMan.removeObjectFromFile(%this.oldMaterial); + } + + UnlistedMaterials.add( "unlistedMaterials", %this.oldMaterial.getName() ); +} + +function ActionDeleteMaterial::undo(%this) +{ + if( MaterialEditorPreviewWindow.isVisible() ) + { + if( MaterialEditorGui.currentMaterial != %this.oldMaterial ) + { + MaterialEditorGui.currentObject = ""; + MaterialEditorGui.setMode(); + MaterialEditorGui.setActiveMaterial(%this.oldMaterial); + } + + MaterialEditorGui.copyMaterials( %this.oldMaterial, materialEd_previewMaterial ); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + } + + matEd_PersistMan.setDirty(%this.oldMaterial, %this.oldMaterialFname); + matEd_PersistMan.saveDirty(); + matEd_PersistMan.removeDirty(%this.oldMaterial); + + %idx = UnlistedMaterials.getIndexFromValue( %this.oldMaterial.getName() ); + UnlistedMaterials.erase( %idx ); +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/meshRoadEditor/main.cs b/Templates/Empty/game/tools/meshRoadEditor/main.cs new file mode 100644 index 000000000..d101e50b0 --- /dev/null +++ b/Templates/Empty/game/tools/meshRoadEditor/main.cs @@ -0,0 +1,225 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function initializeMeshRoadEditor() +{ + echo(" % - Initializing Mesh Road Editor"); + + exec( "./meshRoadEditor.cs" ); + exec( "./meshRoadEditorGui.gui" ); + exec( "./meshRoadEditorToolbar.gui"); + exec( "./meshRoadEditorGui.cs" ); + + MeshRoadEditorGui.setVisible( false ); + MeshRoadEditorOptionsWindow.setVisible( false ); + MeshRoadEditorToolbar.setVisible( false ); + MeshRoadEditorTreeWindow.setVisible( false ); + + EditorGui.add( MeshRoadEditorGui ); + EditorGui.add( MeshRoadEditorOptionsWindow ); + EditorGui.add( MeshRoadEditorToolbar ); + EditorGui.add( MeshRoadEditorTreeWindow ); + + new ScriptObject( MeshRoadEditorPlugin ) + { + superClass = "EditorPlugin"; + editorGui = MeshRoadEditorGui; + }; + + %map = new ActionMap(); + %map.bindCmd( keyboard, "backspace", "MeshRoadEditorGui.deleteNode();", "" ); + %map.bindCmd( keyboard, "1", "MeshRoadEditorGui.prepSelectionMode();", "" ); + %map.bindCmd( keyboard, "2", "ToolsPaletteArray->MeshRoadEditorMoveMode.performClick();", "" ); + %map.bindCmd( keyboard, "3", "ToolsPaletteArray->MeshRoadEditorRotateMode.performClick();", "" ); + %map.bindCmd( keyboard, "4", "ToolsPaletteArray->MeshRoadEditorScaleMode.performClick();", "" ); + %map.bindCmd( keyboard, "5", "ToolsPaletteArray->MeshRoadEditorAddRoadMode.performClick();", "" ); + %map.bindCmd( keyboard, "=", "ToolsPaletteArray->MeshRoadEditorInsertPointMode.performClick();", "" ); + %map.bindCmd( keyboard, "numpadadd", "ToolsPaletteArray->MeshRoadEditorInsertPointMode.performClick();", "" ); + %map.bindCmd( keyboard, "-", "ToolsPaletteArray->MeshRoadEditorRemovePointMode.performClick();", "" ); + %map.bindCmd( keyboard, "numpadminus", "ToolsPaletteArray->MeshRoadEditorRemovePointMode.performClick();", "" ); + %map.bindCmd( keyboard, "z", "MeshRoadEditorShowSplineBtn.performClick();", "" ); + %map.bindCmd( keyboard, "x", "MeshRoadEditorWireframeBtn.performClick();", "" ); + %map.bindCmd( keyboard, "v", "MeshRoadEditorShowRoadBtn.performClick();", "" ); + MeshRoadEditorPlugin.map = %map; + + MeshRoadEditorPlugin.initSettings(); +} + +function destroyMeshRoadEditor() +{ +} + +function MeshRoadEditorPlugin::onWorldEditorStartup( %this ) +{ + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Mesh Road Editor", "", MeshRoadEditorPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "Mesh Road Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "MeshRoadEditorPlugin", "MeshRoadEditorPalette", expandFilename("tools/worldEditor/images/toolbar/mesh-road-editor"), %tooltip ); + + //connect editor windows + GuiWindowCtrl::attach( MeshRoadEditorOptionsWindow, MeshRoadEditorTreeWindow); + + // Add ourselves to the Editor Settings window + exec( "./meshRoadEditorSettingsTab.gui" ); + ESettingsWindow.addTabPage( EMeshRoadEditorSettingsPage ); +} + +function MeshRoadEditorPlugin::onActivated( %this ) +{ + %this.readSettings(); + + ToolsPaletteArray->MeshRoadEditorAddRoadMode.performClick(); + EditorGui.bringToFront( MeshRoadEditorGui ); + MeshRoadEditorGui.setVisible( true ); + MeshRoadEditorGui.makeFirstResponder( true ); + MeshRoadEditorOptionsWindow.setVisible( true ); + MeshRoadEditorToolbar.setVisible( true ); + MeshRoadEditorTreeWindow.setVisible( true ); + MeshRoadTreeView.open(ServerMeshRoadSet,true); + %this.map.push(); + + // Store this on a dynamic field + // in order to restore whatever setting + // the user had before. + %this.prevGizmoAlignment = GlobalGizmoProfile.alignment; + + // The DecalEditor always uses Object alignment. + GlobalGizmoProfile.alignment = "Object"; + + // Set the status bar here until all tool have been hooked up + EditorGuiStatusBar.setInfo("Mesh road editor."); + EditorGuiStatusBar.setSelection(""); + + Parent::onActivated(%this); +} + +function MeshRoadEditorPlugin::onDeactivated( %this ) +{ + %this.writeSettings(); + + MeshRoadEditorGui.setVisible( false ); + MeshRoadEditorOptionsWindow.setVisible( false ); + MeshRoadEditorToolbar.setVisible( false ); + MeshRoadEditorTreeWindow.setVisible( false ); + %this.map.pop(); + + // Restore the previous Gizmo + // alignment settings. + GlobalGizmoProfile.alignment = %this.prevGizmoAlignment; + + Parent::onDeactivated(%this); +} + +function MeshRoadEditorPlugin::onEditMenuSelect( %this, %editMenu ) +{ + %hasSelection = false; + + if( isObject( MeshRoadEditorGui.road ) ) + %hasSelection = true; + + %editMenu.enableItem( 3, false ); // Cut + %editMenu.enableItem( 4, false ); // Copy + %editMenu.enableItem( 5, false ); // Paste + %editMenu.enableItem( 6, %hasSelection ); // Delete + %editMenu.enableItem( 8, false ); // Deselect +} + +function MeshRoadEditorPlugin::handleDelete( %this ) +{ + MeshRoadEditorGui.deleteNode(); +} + +function MeshRoadEditorPlugin::handleEscape( %this ) +{ + return MeshRoadEditorGui.onEscapePressed(); +} + +function MeshRoadEditorPlugin::isDirty( %this ) +{ + return MeshRoadEditorGui.isDirty; +} + +function MeshRoadEditorPlugin::onSaveMission( %this, %missionFile ) +{ + if( MeshRoadEditorGui.isDirty ) + { + MissionGroup.save( %missionFile ); + MeshRoadEditorGui.isDirty = false; + } +} + +//----------------------------------------------------------------------------- +// Settings +//----------------------------------------------------------------------------- + +function MeshRoadEditorPlugin::initSettings( %this ) +{ + EditorSettings.beginGroup( "MeshRoadEditor", true ); + + EditorSettings.setDefaultValue( "DefaultWidth", "10" ); + EditorSettings.setDefaultValue( "DefaultDepth", "5" ); + EditorSettings.setDefaultValue( "DefaultNormal", "0 0 1" ); + EditorSettings.setDefaultValue( "HoverSplineColor", "255 0 0 255" ); + EditorSettings.setDefaultValue( "SelectedSplineColor", "0 255 0 255" ); + EditorSettings.setDefaultValue( "HoverNodeColor", "255 255 255 255" ); //<-- Not currently used + EditorSettings.setDefaultValue( "TopMaterialName", "DefaultRoadMaterialTop" ); + EditorSettings.setDefaultValue( "BottomMaterialName", "DefaultRoadMaterialOther" ); + EditorSettings.setDefaultValue( "SideMaterialName", "DefaultRoadMaterialOther" ); + + EditorSettings.endGroup(); +} + +function MeshRoadEditorPlugin::readSettings( %this ) +{ + EditorSettings.beginGroup( "MeshRoadEditor", true ); + + MeshRoadEditorGui.DefaultWidth = EditorSettings.value("DefaultWidth"); + MeshRoadEditorGui.DefaultDepth = EditorSettings.value("DefaultDepth"); + MeshRoadEditorGui.DefaultNormal = EditorSettings.value("DefaultNormal"); + MeshRoadEditorGui.HoverSplineColor = EditorSettings.value("HoverSplineColor"); + MeshRoadEditorGui.SelectedSplineColor = EditorSettings.value("SelectedSplineColor"); + MeshRoadEditorGui.HoverNodeColor = EditorSettings.value("HoverNodeColor"); + MeshRoadEditorGui.topMaterialName = EditorSettings.value("TopMaterialName"); + MeshRoadEditorGui.bottomMaterialName = EditorSettings.value("BottomMaterialName"); + MeshRoadEditorGui.sideMaterialName = EditorSettings.value("SideMaterialName"); + + EditorSettings.endGroup(); +} + +function MeshRoadEditorPlugin::writeSettings( %this ) +{ + EditorSettings.beginGroup( "MeshRoadEditor", true ); + + EditorSettings.setValue( "DefaultWidth", MeshRoadEditorGui.DefaultWidth ); + EditorSettings.setValue( "DefaultDepth", MeshRoadEditorGui.DefaultDepth ); + EditorSettings.setValue( "DefaultNormal", MeshRoadEditorGui.DefaultNormal ); + EditorSettings.setValue( "HoverSplineColor", MeshRoadEditorGui.HoverSplineColor ); + EditorSettings.setValue( "SelectedSplineColor", MeshRoadEditorGui.SelectedSplineColor ); + EditorSettings.setValue( "HoverNodeColor", MeshRoadEditorGui.HoverNodeColor ); + EditorSettings.setValue( "TopMaterialName", MeshRoadEditorGui.topMaterialName ); + EditorSettings.setValue( "BottomMaterialName", MeshRoadEditorGui.bottomMaterialName ); + EditorSettings.setValue( "SideMaterialName", MeshRoadEditorGui.sideMaterialName ); + + EditorSettings.endGroup(); +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/meshRoadEditor/meshRoadEditor.cs b/Templates/Empty/game/tools/meshRoadEditor/meshRoadEditor.cs new file mode 100644 index 000000000..112562d82 --- /dev/null +++ b/Templates/Empty/game/tools/meshRoadEditor/meshRoadEditor.cs @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +singleton GuiControlProfile( MeshRoadEditorProfile ) +{ + canKeyFocus = true; + opaque = true; + fillColor = "192 192 192 192"; + category = "Editor"; +}; + +singleton GuiControlProfile (GuiDisabledTextEditProfile) +{ + opaque = false; + border = 0; + bitmap = "./textEdit"; + borderColor = "255 255 255 200"; + fontColor = "0 0 0"; + fontColorHL = "255 255 255"; + fontColorNA = "128 128 128"; + textOffset = "4 2"; + autoSizeWidth = false; + autoSizeHeight = false; + tab = false; + canKeyFocus = false; + category = "Editor"; +}; + +singleton GuiControlProfile (GuiSimpleBorderProfile) +{ + opaque = false; + border = 1; + category = "Editor"; +}; \ No newline at end of file diff --git a/Templates/Empty/game/tools/meshRoadEditor/meshRoadEditorGui.cs b/Templates/Empty/game/tools/meshRoadEditor/meshRoadEditorGui.cs new file mode 100644 index 000000000..9d2985e25 --- /dev/null +++ b/Templates/Empty/game/tools/meshRoadEditor/meshRoadEditorGui.cs @@ -0,0 +1,256 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +$MeshRoad::wireframe = true; +$MeshRoad::showSpline = true; +$MeshRoad::showReflectPlane = false; +$MeshRoad::showRoad = true; +$MeshRoad::breakAngle = 3.0; + +function MeshRoadEditorGui::onWake( %this ) +{ + $MeshRoad::EditorOpen = true; + + %count = EWorldEditor.getSelectionSize(); + for ( %i = 0; %i < %count; %i++ ) + { + %obj = EWorldEditor.getSelectedObject(%i); + if ( %obj.getClassName() !$= "MeshRoad" ) + EWorldEditor.unselectObject(); + else + %this.setSelectedRoad( %obj ); + } + + //%this-->TabBook.selectPage(0); + + %this.onNodeSelected(-1); +} + +function MeshRoadEditorGui::onSleep( %this ) +{ + $MeshRoad::EditorOpen = false; +} + +function MeshRoadEditorGui::paletteSync( %this, %mode ) +{ + %evalShortcut = "ToolsPaletteArray-->" @ %mode @ ".setStateOn(1);"; + eval(%evalShortcut); +} +function MeshRoadEditorGui::onEscapePressed( %this ) +{ + if( %this.getMode() $= "MeshRoadEditorAddNodeMode" ) + { + %this.prepSelectionMode(); + return true; + } + return false; +} +function MeshRoadEditorGui::onRoadSelected( %this, %road ) +{ + %this.road = %road; + + // Update the materialEditorList + if( isObject( %road ) ) + $Tools::materialEditorList = %road.getId(); + + MeshRoadInspector.inspect( %road ); + MeshRoadTreeView.buildVisibleTree(true); + if( MeshRoadTreeView.getSelectedObject() != %road ) + { + MeshRoadTreeView.clearSelection(); + %treeId = MeshRoadTreeView.findItemByObjectId( %road ); + MeshRoadTreeView.selectItem( %treeId ); + } +} + +function MeshRoadEditorGui::onNodeSelected( %this, %nodeIdx ) +{ + if ( %nodeIdx == -1 ) + { + MeshRoadEditorOptionsWindow-->position.setActive( false ); + MeshRoadEditorOptionsWindow-->position.setValue( "" ); + + MeshRoadEditorOptionsWindow-->rotation.setActive( false ); + MeshRoadEditorOptionsWindow-->rotation.setValue( "" ); + + MeshRoadEditorOptionsWindow-->width.setActive( false ); + MeshRoadEditorOptionsWindow-->width.setValue( "" ); + + MeshRoadEditorOptionsWindow-->depth.setActive( false ); + MeshRoadEditorOptionsWindow-->depth.setValue( "" ); + } + else + { + MeshRoadEditorOptionsWindow-->position.setActive( true ); + MeshRoadEditorOptionsWindow-->position.setValue( %this.getNodePosition() ); + + MeshRoadEditorOptionsWindow-->rotation.setActive( true ); + MeshRoadEditorOptionsWindow-->rotation.setValue( %this.getNodeNormal() ); + + MeshRoadEditorOptionsWindow-->width.setActive( true ); + MeshRoadEditorOptionsWindow-->width.setValue( %this.getNodeWidth() ); + + MeshRoadEditorOptionsWindow-->depth.setActive( true ); + MeshRoadEditorOptionsWindow-->depth.setValue( %this.getNodeDepth() ); + } +} + + +function MeshRoadEditorGui::onNodeModified( %this, %nodeIdx ) +{ + MeshRoadEditorOptionsWindow-->position.setValue( %this.getNodePosition() ); + MeshRoadEditorOptionsWindow-->rotation.setValue( %this.getNodeNormal() ); + MeshRoadEditorOptionsWindow-->width.setValue( %this.getNodeWidth() ); + MeshRoadEditorOptionsWindow-->depth.setValue( %this.getNodeDepth() ); +} + +function MeshRoadEditorGui::editNodeDetails( %this ) +{ + + %this.setNodePosition( MeshRoadEditorOptionsWindow-->position.getText() ); + %this.setNodeNormal( MeshRoadEditorOptionsWindow-->rotation.getText() ); + %this.setNodeWidth( MeshRoadEditorOptionsWindow-->width.getText() ); + %this.setNodeDepth( MeshRoadEditorOptionsWindow-->depth.getText() ); +} + +function MeshRoadEditorGui::onBrowseClicked( %this ) +{ + //%filename = RETextureFileCtrl.getText(); + + %dlg = new OpenFileDialog() + { + Filters = "All Files (*.*)|*.*|"; + DefaultPath = MeshRoadEditorGui.lastPath; + DefaultFile = %filename; + ChangePath = false; + MustExist = true; + }; + + %ret = %dlg.Execute(); + if(%ret) + { + MeshRoadEditorGui.lastPath = filePath( %dlg.FileName ); + %filename = %dlg.FileName; + MeshRoadEditorGui.setTextureFile( %filename ); + MeshRoadEditorTextureFileCtrl.setText( %filename ); + } + + %dlg.delete(); +} + +function MeshRoadInspector::inspect( %this, %obj ) +{ + %name = ""; + if ( isObject( %obj ) ) + %name = %obj.getName(); + else + MeshFieldInfoControl.setText( "" ); + + //RiverInspectorNameEdit.setValue( %name ); + Parent::inspect( %this, %obj ); +} + +function MeshRoadInspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ) +{ + // Same work to do as for the regular WorldEditor Inspector. + Inspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ); +} + +function MeshRoadInspector::onFieldSelected( %this, %fieldName, %fieldTypeStr, %fieldDoc ) +{ + MeshFieldInfoControl.setText( "<font:ArialBold:14>" @ %fieldName @ "<font:ArialItalic:14> (" @ %fieldTypeStr @ ") " NL "<font:Arial:14>" @ %fieldDoc ); +} + +function MeshRoadTreeView::onInspect(%this, %obj) +{ + MeshRoadInspector.inspect(%obj); +} + +function MeshRoadTreeView::onSelect(%this, %obj) +{ + MeshRoadEditorGui.road = %obj; + MeshRoadInspector.inspect( %obj ); + if(%obj != MeshRoadEditorGui.getSelectedRoad()) + { + MeshRoadEditorGui.setSelectedRoad( %obj ); + } +} + +function MeshRoadEditorGui::prepSelectionMode( %this ) +{ + %mode = %this.getMode(); + + if ( %mode $= "MeshRoadEditorAddNodeMode" ) + { + if ( isObject( %this.getSelectedRoad() ) ) + %this.deleteNode(); + } + + %this.setMode( "MeshRoadEditorSelectMode" ); + ToolsPaletteArray-->MeshRoadEditorSelectMode.setStateOn(1); +} + +//------------------------------------------------------------------------------ +function EMeshRoadEditorSelectModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function EMeshRoadEditorAddModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function EMeshRoadEditorMoveModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function EMeshRoadEditorRotateModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function EMeshRoadEditorScaleModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function EMeshRoadEditorInsertModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function EMeshRoadEditorRemoveModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function MeshRoadDefaultWidthSliderCtrlContainer::onWake(%this) +{ + MeshRoadDefaultWidthSliderCtrlContainer-->slider.setValue(MeshRoadDefaultWidthTextEditContainer-->textEdit.getText()); +} + +function MeshRoadDefaultDepthSliderCtrlContainer::onWake(%this) +{ + MeshRoadDefaultDepthSliderCtrlContainer-->slider.setValue(MeshRoadDefaultDepthTextEditContainer-->textEdit.getText()); +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/meshRoadEditor/meshRoadEditorGui.gui b/Templates/Empty/game/tools/meshRoadEditor/meshRoadEditorGui.gui new file mode 100644 index 000000000..a08e664d7 --- /dev/null +++ b/Templates/Empty/game/tools/meshRoadEditor/meshRoadEditorGui.gui @@ -0,0 +1,361 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiMeshRoadEditorCtrl(MeshRoadEditorGui,EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "MeshRoadEditorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "None"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + cameraZRot = "0"; + forceFOV = "0"; + renderMissionArea = "0"; + missionAreaFillColor = "255 0 0 20"; + missionAreaFrameColor = "255 0 0 128"; + allowBorderMove = "0"; + borderMovePixelSize = "20"; + borderMoveSpeed = "0.1"; + consoleFrameColor = "255 0 0 255"; + consoleFillColor = "0 0 0 0"; + consoleSphereLevel = "1"; + consoleCircleSegments = "32"; + consoleLineWidth = "1"; + GizmoProfile = "GlobalGizmoProfile"; + DefaultWidth = "10"; + HoverSplineColor = "0 255 0 255"; + SelectedSplineColor = "255 0 255 255"; + HoverNodeColor = "255 255 255 255"; + + new GuiWindowCollapseCtrl(MeshRoadEditorTreeWindow) { + internalName = ""; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) - 1; + Extent = "210 167"; + MinExtent = "210 100"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "EditorGui.setEditor( WorldEditorInspectorPlugin );"; + EdgeSnap = "1"; + text = "Mesh Roads"; + + new GuiContainer(){ + profile = GuiDefaultProfile; + Position = "5 25"; + Extent = "200 120"; + Docking = "Client"; + Margin = "3 1 3 3 "; + HorizSizing = "width"; + VertSizing = "height"; + isContainer = "1"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "200 118"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiTreeViewCtrl(MeshRoadTreeView) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "193 21"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "0"; + showRoot = "0"; + internalNamesOnly = "0"; + }; + }; + }; + }; + new GuiWindowCollapseCtrl(MeshRoadEditorOptionsWindow) { + internalName = "Window"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) + getWord(MeshRoadEditorTreeWindow.extent, 1) - 2; + Extent = "210 530"; + MinExtent = "210 298"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "EditorGui.setEditor( WorldEditorPlugin );"; + EdgeSnap = "1"; + text = "Properties"; + + new GuiContainer(){ //Node Properties + isContainer = "1"; + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 24"; + Extent = "202 85"; + Docking = "Top"; + Margin = "3 3 3 3"; + + new GuiTextCtrl(){ + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 0"; + Extent = "86 18"; + text = "Node Properties"; + }; + + new GuiTextCtrl(){ + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 21"; + Extent = "46 18"; + text = "Position"; + }; + new GuiTextEditCtrl(){ + internalName = "position"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "57 21"; + Extent = "141 18"; + text = ""; + AltCommand = "MeshRoadEditorGui.editNodeDetails();"; + }; + new GuiTextCtrl(){ + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 42"; + Extent = "46 18"; + text = "Rotation"; + }; + new GuiTextEditCtrl(){ + internalName = "rotation"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "57 42"; + Extent = "141 18"; + text = ""; + AltCommand = "MeshRoadEditorGui.editNodeDetails();"; + }; + new GuiTextCtrl(){ + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 63"; + Extent = "46 18"; + text = "Width"; + }; + new GuiTextEditCtrl(){ + internalName = "width"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "57 63"; + Extent = "52 18"; + text = ""; + AltCommand = "MeshRoadEditorGui.editNodeDetails();"; + }; + new GuiTextCtrl(){ + Profile = "GuiTextRightProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "110 63"; + Extent = "32 18"; + text = "Depth"; + }; + new GuiTextEditCtrl(){ + internalName = "depth"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "146 63"; + Extent = "52 18"; + text = ""; + AltCommand = "MeshRoadEditorGui.editNodeDetails();"; + }; + }; + new GuiContainer(){ //Mesh Road Properties + isContainer = "1"; + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 112"; + Extent = "202 31"; + Docking = "Top"; + Margin = "0 0 3 3"; + + new GuiTextCtrl(){ + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 0"; + Extent = "121 18"; + text = "Mesh Road Properties"; + }; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "4 129"; + Extent = "202 357"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "-14 41 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiInspector(MeshRoadInspector) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + name = "MeshRoadInspector"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "179 16"; + MinExtent = "16 16"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + dividerMargin = "5"; + }; + }; + new GuiMLTextCtrl(MeshFieldInfoControl) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorFieldInfoMLTextProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "1 485"; + Extent = "202 42"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + }; + }; + +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/meshRoadEditor/meshRoadEditorSettingsTab.gui b/Templates/Empty/game/tools/meshRoadEditor/meshRoadEditorSettingsTab.gui new file mode 100644 index 000000000..6f8f32806 --- /dev/null +++ b/Templates/Empty/game/tools/meshRoadEditor/meshRoadEditorSettingsTab.gui @@ -0,0 +1,697 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(MeshRoadEditorSettingsTab,EditorGuiGroup) { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiTabPageCtrl(EMeshRoadEditorSettingsPage) { + fitBook = "1"; + text = "Mesh Road Editor"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiSolidDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "208 400"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "208 400"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + extent = "208 210"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Defaults"; + Margin = "0 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Width:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditNumericProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "MeshRoadEditorPlugin.readSettings();"; + editorSettingsValue = "MeshRoadEditor/DefaultWidth"; + editorSettingsWrite = "MeshRoadEditorPlugin.writeSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Depth:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditNumericProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "MeshRoadEditorPlugin.readSettings();"; + editorSettingsValue = "MeshRoadEditor/DefaultDepth"; + editorSettingsWrite = "MeshRoadEditorPlugin.writeSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Normal:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "MeshRoadEditorPlugin.readSettings();"; + editorSettingsValue = "MeshRoadEditor/DefaultNormal"; + editorSettingsWrite = "MeshRoadEditorPlugin.writeSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Top Material:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "MeshRoadEditorPlugin.readSettings();"; + editorSettingsValue = "MeshRoadEditor/TopMaterialName"; + editorSettingsWrite = "MeshRoadEditorPlugin.writeSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Bottom Material:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "MeshRoadEditorPlugin.readSettings();"; + editorSettingsValue = "MeshRoadEditor/BottomMaterialName"; + editorSettingsWrite = "MeshRoadEditorPlugin.writeSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Side Material:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "MeshRoadEditorPlugin.readSettings();"; + editorSettingsValue = "MeshRoadEditor/SideMaterialName"; + editorSettingsWrite = "MeshRoadEditorPlugin.writeSettings();"; + }; + }; + }; + }; + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Colors"; + Margin = "0 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiControl() { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + extent = "208 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + className = "ESettingsWindowColor"; + editorSettingsRead = "MeshRoadEditorPlugin.readSettings();"; + editorSettingsValue = "MeshRoadEditor/HoverSplineColor"; + editorSettingsWrite = "MeshRoadEditorPlugin.writeSettings();"; + + new GuiTextCtrl() { + text = "Hover Spline:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + profile = "GuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 2"; + extent = "70 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + profile = "GuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "80 0"; + extent = "104 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + className = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + className = "ESettingsWindowColorButton"; + }; + }; + new GuiControl() { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "208 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + className = "ESettingsWindowColor"; + editorSettingsRead = "MeshRoadEditorPlugin.readSettings();"; + editorSettingsValue = "MeshRoadEditor/SelectedSplineColor"; + editorSettingsWrite = "MeshRoadEditorPlugin.writeSettings();"; + + new GuiTextCtrl() { + text = "Sel. Spline:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + profile = "GuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 2"; + extent = "70 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + profile = "GuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "80 0"; + extent = "104 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + className = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + className = "ESettingsWindowColorButton"; + }; + }; + }; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/meshRoadEditor/meshRoadEditorToolbar.gui b/Templates/Empty/game/tools/meshRoadEditor/meshRoadEditorToolbar.gui new file mode 100644 index 000000000..2fb25724e --- /dev/null +++ b/Templates/Empty/game/tools/meshRoadEditor/meshRoadEditorToolbar.gui @@ -0,0 +1,322 @@ +%guiContent = new GuiControl(MeshRoadEditorToolbar,EditorGuiGroup) { + canSaveDynamicFields = "0"; + internalName = "MeshRoadEditorToolbar"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "306 0"; + Extent = "800 32"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "6 6"; + extent = "100 20"; + minExtent = "8 8"; + visible = "1"; + text = "Mesh Road Settings"; + maxLength = "255"; + helpTag = "0"; + }; + new GuiDynamicCtrlArrayControl(){ + Position = "116 3"; + extent = "111 32"; + colCount = "31"; + colSize = "29"; + rowCount = "1"; + RowSize = "27"; + rowSpacing = "2"; + colspacing = "4"; + + new GuiBitmapButtonCtrl(MeshRoadEditorShowSplineBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "167 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Variable = "$MeshRoad::showSpline"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + toolTip = "Show Spline (Z)"; + bitmap = "tools/worldEditor/images/road-river/menubar/show-spline"; + groupNum = "7"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiBitmapButtonCtrl(MeshRoadEditorWireframeBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "253 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Variable = "$MeshRoad::wireframe"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + toolTip = "Show Wireframe (X)"; + bitmap = "tools/worldEditor/images/road-river/menubar/show-wireframe"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiBitmapButtonCtrl(MeshRoadEditorShowRoadBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefalutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "89 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Variable = "$MeshRoad::showRoad"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + toolTip = "Show Road Texture (V)"; + bitmap = "tools/worldEditor/images/road-river/menubar/show-texture"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + }; + new GuiControl(MeshRoadDefaultWidthTextEditContainer) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "230 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 6"; + Extent = "68 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Default Width"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + isContainer = "0"; + profile="GuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "67 2"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "MeshRoadEditorGui.DefaultWidth = $ThisControl.getValue();"; + hovertime = "1000"; + text = "10"; + maxLength = "3"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "101 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(MeshRoadDefaultWidthSliderCtrlContainer);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Changes Default Road Width"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "core/art/gui/images/dropslider"; + }; + }; + new GuiControl(MeshRoadDefaultDepthTextEditContainer) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "360 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 6"; + Extent = "68 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Default Depth"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + isContainer = "0"; + profile="GuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "67 2"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "MeshRoadEditorGui.DefaultDepth = $ThisControl.getValue();"; + hovertime = "1000"; + text = "10"; + maxLength = "3"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "101 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(MeshRoadDefaultDepthSliderCtrlContainer);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Changes Default Road Depth"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "core/art/gui/images/dropslider"; + }; + }; +}; +new GuiMouseEventCtrl(MeshRoadDefaultWidthSliderCtrlContainer, EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "GuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(MeshRoadDefaultWidthTextEditContainer.position) + firstWord(MeshRoadEditorToolbar.position) + 10 SPC + (getWord(MeshRoadDefaultWidthTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "MeshRoadDefaultWidthTextEditContainer-->textEdit.setValue( mFloatLength($ThisControl.getValue(), 2)); MeshRoadEditorGui.DefaultWidth = $ThisControl.getValue();"; + range = "0 100"; + ticks = "0"; + value = "10"; + }; +}; +new GuiMouseEventCtrl(MeshRoadDefaultDepthSliderCtrlContainer, EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "GuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(MeshRoadDefaultDepthTextEditContainer.position) + firstWord(MeshRoadEditorToolbar.position) + 10 SPC + (getWord(MeshRoadDefaultDepthTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "MeshRoadDefaultDepthTextEditContainer-->textEdit.setValue( mFloatLength($ThisControl.getValue(), 2)); MeshRoadEditorGui.DefaultDepth = $ThisControl.getValue();"; + range = "0 100"; + ticks = "0"; + value = "10"; + }; +}; \ No newline at end of file diff --git a/Templates/Empty/game/tools/missionAreaEditor/images/DefaultHandle.png b/Templates/Empty/game/tools/missionAreaEditor/images/DefaultHandle.png new file mode 100644 index 000000000..c32ed3fb8 Binary files /dev/null and b/Templates/Empty/game/tools/missionAreaEditor/images/DefaultHandle.png differ diff --git a/Templates/Empty/game/tools/missionAreaEditor/images/mission-area_d.png b/Templates/Empty/game/tools/missionAreaEditor/images/mission-area_d.png new file mode 100644 index 000000000..356cf1f41 Binary files /dev/null and b/Templates/Empty/game/tools/missionAreaEditor/images/mission-area_d.png differ diff --git a/Templates/Empty/game/tools/missionAreaEditor/images/mission-area_h.png b/Templates/Empty/game/tools/missionAreaEditor/images/mission-area_h.png new file mode 100644 index 000000000..b96012a60 Binary files /dev/null and b/Templates/Empty/game/tools/missionAreaEditor/images/mission-area_h.png differ diff --git a/Templates/Empty/game/tools/missionAreaEditor/images/mission-area_n.png b/Templates/Empty/game/tools/missionAreaEditor/images/mission-area_n.png new file mode 100644 index 000000000..5612871e7 Binary files /dev/null and b/Templates/Empty/game/tools/missionAreaEditor/images/mission-area_n.png differ diff --git a/Templates/Empty/game/tools/missionAreaEditor/main.cs b/Templates/Empty/game/tools/missionAreaEditor/main.cs new file mode 100644 index 000000000..196a2d515 --- /dev/null +++ b/Templates/Empty/game/tools/missionAreaEditor/main.cs @@ -0,0 +1,131 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function initializeMissionAreaEditor() +{ + echo(" % - Initializing Mission Area Editor"); + + exec( "./missionAreaEditor.ed.cs" ); + exec( "./missionAreaEditorGui.ed.gui" ); + exec( "./missionAreaEditorGui.ed.cs" ); + + // Add ourselves to EditorGui, where all the other tools reside + MissionAreaEditorGui.setVisible( false ); + MissionAreaEditorTerrainWindow.setVisible( false ); + MissionAreaEditorPropertiesWindow.setVisible( false ); + + EditorGui.add( MissionAreaEditorGui ); + EditorGui.add( MissionAreaEditorTerrainWindow ); + EditorGui.add( MissionAreaEditorPropertiesWindow ); + + new ScriptObject( MissionAreaEditorPlugin ) + { + superClass = "EditorPlugin"; + editorGui = MissionAreaEditorGui; + }; + + MissionAreaEditorPlugin.initSettings(); +} + +function destroyMissionAreaEditor() +{ +} + +function MissionAreaEditorPlugin::onWorldEditorStartup( %this ) +{ + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Mission Area Editor", "", MissionAreaEditorPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "Mission Area Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "MissionAreaEditorPlugin", "MissionAreaEditorPalette", expandFilename("tools/missionAreaEditor/images/mission-area"), %tooltip ); + + //connect editor windows + GuiWindowCtrl::attach( MissionAreaEditorPropertiesWindow, MissionAreaEditorTerrainWindow); +} + +function MissionAreaEditorPlugin::onActivated( %this ) +{ + %this.readSettings(); + + EditorGui.bringToFront( MissionAreaEditorGui ); + + MissionAreaEditorGui.setVisible(true); + MissionAreaEditorGui.makeFirstResponder( true ); + + MissionAreaEditorTerrainWindow.setVisible( true ); + MissionAreaEditorPropertiesWindow.setVisible( true ); + + // Set the status bar here until all tool have been hooked up + EditorGuiStatusBar.setInfo("Mission Area Editor."); + EditorGuiStatusBar.setSelection(""); + + // Allow the Gui to setup. + MissionAreaEditorGui.onEditorActivated(); + + Parent::onActivated(%this); +} + +function MissionAreaEditorPlugin::onDeactivated( %this ) +{ + %this.writeSettings(); + + MissionAreaEditorGui.setVisible(false); + MissionAreaEditorTerrainWindow.setVisible( false ); + MissionAreaEditorPropertiesWindow.setVisible( false ); + + // Allow the Gui to cleanup. + MissionAreaEditorGui.onEditorDeactivated(); + + Parent::onDeactivated(%this); +} + +//----------------------------------------------------------------------------- +// Settings +//----------------------------------------------------------------------------- + +function MissionAreaEditorPlugin::initSettings( %this ) +{ + EditorSettings.beginGroup( "MissionAreaEditor", true ); + + EditorSettings.setDefaultValue( "MissionBoundsColor", "255 255 255" ); + + EditorSettings.endGroup(); +} + +function MissionAreaEditorPlugin::readSettings( %this ) +{ + EditorSettings.beginGroup( "MissionAreaEditor", true ); + + MissionAreaEditorTerrainEditor.missionBoundsColor = EditorSettings.value("MissionBoundsColor"); + + EditorSettings.endGroup(); +} + +function MissionAreaEditorPlugin::writeSettings( %this ) +{ + EditorSettings.beginGroup( "MissionAreaEditor", true ); + + EditorSettings.setValue( "MissionBoundsColor", MissionAreaEditorTerrainEditor.missionBoundsColor ); + + EditorSettings.endGroup(); +} diff --git a/Templates/Empty/game/tools/missionAreaEditor/missionAreaEditor.ed.cs b/Templates/Empty/game/tools/missionAreaEditor/missionAreaEditor.ed.cs new file mode 100644 index 000000000..dfdeaf970 --- /dev/null +++ b/Templates/Empty/game/tools/missionAreaEditor/missionAreaEditor.ed.cs @@ -0,0 +1,29 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +singleton GuiControlProfile( MissionAreaEditorProfile ) +{ + canKeyFocus = true; + opaque = true; + fillColor = "192 192 192"; + category = "Editor"; +}; diff --git a/Templates/Empty/game/tools/missionAreaEditor/missionAreaEditorGui.ed.cs b/Templates/Empty/game/tools/missionAreaEditor/missionAreaEditorGui.ed.cs new file mode 100644 index 000000000..81c39eda3 --- /dev/null +++ b/Templates/Empty/game/tools/missionAreaEditor/missionAreaEditorGui.ed.cs @@ -0,0 +1,81 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function MissionAreaEditorGui::onEditorActivated( %this ) +{ + EWorldEditor.clearSelection(); + + %ma = getMissionAreaServerObject(); + EWorldEditor.selectObject( %ma ); + EWorldEditor.syncGui(); + MissionAreaEditorTerrainEditor.updateTerrain(); + %this.setSelectedMissionArea( %ma ); + %this.onMissionAreaSelected( %this.getSelectedMissionArea() ); +} + +function MissionAreaEditorGui::onEditorDeactivated( %this ) +{ +} + +function MissionAreaEditorGui::onMissionAreaSelected( %this, %missionArea ) +{ + %this.missionArea = %missionArea; + MissionAreaEditorTerrainEditor.setMissionArea( %missionArea ); + MissionAreaInspector.inspect( %missionArea ); +} + +//----------------------------------------------------------------------------- + +function MissionAreaEditorTerrainEditor::onMissionAreaModified( %this ) +{ + MissionAreaInspector.refresh(); +} + +function MissionAreaEditorTerrainEditor::onUndo( %this ) +{ + MissionAreaInspector.refresh(); +} + +//----------------------------------------------------------------------------- + +function MissionAreaInspector::inspect( %this, %obj ) +{ + %name = ""; + if ( isObject( %obj ) ) + %name = %obj.getName(); + else + MissionAreaFieldInfoControl.setText( "" ); + + //RiverInspectorNameEdit.setValue( %name ); + Parent::inspect( %this, %obj ); +} + +function MissionAreaInspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ) +{ + // Same work to do as for the regular WorldEditor Inspector. + Inspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ); +} + +function MissionAreaInspector::onFieldSelected( %this, %fieldName, %fieldTypeStr, %fieldDoc ) +{ + MissionAreaFieldInfoControl.setText( "<font:ArialBold:14>" @ %fieldName @ "<font:ArialItalic:14> (" @ %fieldTypeStr @ ") " NL "<font:Arial:14>" @ %fieldDoc ); +} diff --git a/Templates/Empty/game/tools/missionAreaEditor/missionAreaEditorGui.ed.gui b/Templates/Empty/game/tools/missionAreaEditor/missionAreaEditorGui.ed.gui new file mode 100644 index 000000000..ac9e4e352 --- /dev/null +++ b/Templates/Empty/game/tools/missionAreaEditor/missionAreaEditorGui.ed.gui @@ -0,0 +1,245 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiMissionAreaEditorCtrl(MissionAreaEditorGui, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "MissionAreaEditorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "None"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + cameraZRot = "0"; + forceFOV = "0"; + renderMissionArea = "0"; + missionAreaFillColor = "255 0 0 20"; + missionAreaFrameColor = "255 0 0 128"; + allowBorderMove = "0"; + borderMovePixelSize = "20"; + borderMoveSpeed = "0.1"; + consoleFrameColor = "255 0 0 255"; + consoleFillColor = "0 0 0 0"; + consoleSphereLevel = "1"; + consoleCircleSegments = "32"; + consoleLineWidth = "1"; + GizmoProfile = "GlobalGizmoProfile"; + + new GuiWindowCollapseCtrl(MissionAreaEditorTerrainWindow) { + internalName = ""; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) - 1; + Extent = "210 230"; + MinExtent = "210 100"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Mission Area"; + + new GuiContainer(){ + profile = GuiDefaultProfile; + Position = "5 25"; + Extent = "200 200"; + Docking = "Client"; + Margin = "3 1 3 3 "; + HorizSizing = "width"; + VertSizing = "height"; + isContainer = "1"; + + new GuiMissionAreaCtrl(MissionAreaEditorTerrainEditor) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "EditorDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "200 200"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + wrap = "0"; + enableMirroring = "0"; + mirrorIndex = "0"; + mirrorLineColor = "255 0 255 255"; + mirrorArrowColor = "255 0 255 128"; + handleFrameColor = "255 255 255 255"; + handleFillColor = "0 0 0 255"; + defaultObjectColor = "0 255 0 100"; + waterObjectColor = "0 0 255 100"; + missionBoundsColor = "255 0 0 255"; + cameraColor = "255 0 0 255"; + squareBitmap = "1"; + enableEditing = "0"; + renderCamera = "1"; + handleBitmap = "tools/missionAreaEditor/images/DefaultHandle.png"; + }; + }; + }; + new GuiWindowCollapseCtrl(MissionAreaEditorPropertiesWindow) { + internalName = "Window"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) + getWord(MissionAreaEditorTerrainWindow.extent, 1) - 2; + Extent = "210 466"; + MinExtent = "210 300"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Properties"; + + new GuiContainer(){ //Mission Area Properties + isContainer = "1"; + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 112"; + Extent = "202 31"; + Docking = "Top"; + Margin = "0 0 3 3"; + + new GuiTextCtrl(){ + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 0"; + Extent = "121 18"; + text = "Mission Area Properties"; + }; + }; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "4 129"; + Extent = "202 357"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "-14 0 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiInspector(MissionAreaInspector) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + name = "MissionAreaInspector"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "1 1"; + Extent = "178 16"; + MinExtent = "16 16"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + dividerMargin = "5"; + }; + }; + new GuiContainer(){ //Mission Area Properties + isContainer = "1"; + Profile = GuiDefaultProfile; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 0"; + Extent = "202 42"; + Docking = "Bottom"; + Margin = "0 0 3 3"; + + new GuiMLTextCtrl(MissionAreaFieldInfoControl) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorFieldInfoMLTextProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "0 0"; + Extent = "202 42"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + }; + }; + }; +}; diff --git a/Templates/Empty/game/tools/particleEditor/ParticleEditor.ed.gui b/Templates/Empty/game/tools/particleEditor/ParticleEditor.ed.gui new file mode 100644 index 000000000..c2537e470 --- /dev/null +++ b/Templates/Empty/game/tools/particleEditor/ParticleEditor.ed.gui @@ -0,0 +1,3060 @@ +//----------------------------------------------------------------------------- +// Torque +// Copyright GarageGames, LLC 2011 +//----------------------------------------------------------------------------- + +$PE_guielement_pos_single_container = "0 0"; +$PE_guielement_ext_single_container = "184 20"; +$PE_guielement_pos_name = "1 0"; +$PE_guielement_ext_name = "70 18"; +$PE_guielement_pos_slider = "74 2"; +$PE_guielement_ext_slider = "58 12"; +$PE_guielement_pos_value = "138 0"; +$PE_guielement_ext_value = "36 18"; +$PE_guielement_pos_textedit = "74 0"; +$PE_guielement_ext_textedit = "100 18"; +$PE_guielement_ext_checkbox_name = "156 18"; +$PE_guielement_pos_checkbox = "161 0"; +$PE_guielement_ext_checkbox = "15 18"; +$PE_guielement_pos_colorpicker = "158 0"; +$PE_guielement_ext_colorpicker = "18 18"; + +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiWindowCollapseCtrl(PE_Window) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + Position = firstWord($pref::Video::mode) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) -1; + Extent = "210 696"; + MinExtent = "210 140"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = ""; + EdgeSnap = "0"; + text = "Particle Editor"; + + new GuiTabBookCtrl(PE_TabBook) { + canSaveDynamicFields = "0"; + isContainer = "1"; + internalName = "EditorTabBook"; + Profile = "GuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "6 27"; + Extent = "197 289"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "3 2 3 3"; + Docking = "client"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + TabPosition = "Top"; + TabMargin = "0"; + MinTabWidth = "64"; + + new GuiTabPageCtrl(PE_EmitterEditor) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "EditorTabPage"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 19"; + Extent = "197 271"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Emitter"; + maxLength = "1024"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "197 271"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = false; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "197 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl(PEE_EmitterSelector_Control){ // PEE_EmitterSelector + class = "QuickEditDropDownTextEditCtrl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = "197 26" ; + + new GuiPopUpMenuCtrl(PEE_EmitterSelector) { + internalName = "PopUpMenu"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "4 4"; + Extent = "123 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor::onNewEmitter();"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + new GuiTextEditCtrl() { + internalName = "TextEdit"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDropdownTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "4 4"; + Extent = "107 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl);"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "131 5"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.showNewDialog();"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "core/art/gui/images/new"; + tooltip = "Create New Emitter"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "147 5"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/save-icon"; + command = "PE_EmitterEditor.saveEmitter( " @ PE_EmitterEditor.currEmitter @ " ); PE_ParticleEditor.saveParticle( PE_ParticleEditor.currParticle );"; + tooltip = "Save Current Emitter"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "164 5"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.showDeleteDialog();"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + tooltip = "Delete Current Emitter"; + }; + }; + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "197 0"; + Caption = "Basic"; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "197 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl(){ // Emitter PEE_lifetimeMS + isContainer = "1"; + class = "AggregateControl"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Life"; + maxLength = "255"; + }; + new GuiSliderCtrl(PEE_lifetimeMS) { + internalName = "PEE_lifetimeMS_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.updateLifeFields( false, $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateLifeFields( false, $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 1000"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_lifetimeMS_textEdit"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateLifeFields( false, $ThisControl.getValue() );"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + }; + }; + + new GuiControl(){ // Emitter PEE_lifetimeVarianceMS + isContainer = "1"; + class = "AggregateControl"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Life Random"; + maxLength = "255"; + }; + new GuiSliderCtrl(PEE_lifetimeVarianceMS) { + internalName = "PEE_lifetimeVarianceMS_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.updateLifeFields( true, $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateLifeFields( true, $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 1000"; + ticks = "0"; + value = ""; + }; + new GuiTextEditCtrl() { + internalName = "PEE_lifetimeVarianceMS_textEdit"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateLifeFields( true, $ThisControl.getValue() );"; + }; + }; + + new GuiControl(){ // Emitter Infinite Loop + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_checkbox_name; + text = "Infinite Loop"; + }; + new GuiCheckBoxCtrl() { + internalName = "PEE_infiniteLoop"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_checkbox; + Extent = $PE_guielement_ext_checkbox; + Command = "PE_EmitterEditor.updateLifeFieldsInfiniteLoop();"; + text = ""; + }; + }; + + new GuiControl(){ // Spacer ---------------------------- + isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8"; + new GuiBitmapCtrl(){ + position="0 3"; extent ="188 2"; HorizSizing = "width"; + bitmap ="core/art/gui/images/separator-v"; + }; + };// end spacer ---------------------------------------- + + new GuiControl(){ // Emitter Amount + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Amount"; + }; + new GuiSliderCtrl(PEE_ejectionPeriodMS) { + internalName = "PEE_ejectionPeriodMS_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.updateAmountFields( false, $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateAmountFields( false, $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "1 1000"; + ticks = "0"; + value = "1"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_ejectionPeriodMS_textEdit"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateAmountFields( false, $ThisControl.getValue() );"; + }; + }; + new GuiControl(){ // Emitter Amount Random + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Amount Random"; + }; + new GuiSliderCtrl(PEE_periodVarianceMS) { + internalName = "PEE_periodVarianceMS_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.updateAmountFields( true, $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateAmountFields( true, $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 999"; + ticks = "0"; + value = "1"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_periodVarianceMS_textEdit"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateAmountFields( true, $ThisControl.getValue() );"; + }; + }; + };// end stack + }; // end "basic" rollout + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "197 0"; + Caption = "Motion"; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "197 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl(){ // Emitter speed + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Speed"; + }; + new GuiSliderCtrl(PEE_ejectionVelocity) { + internalName = "PEE_ejectionVelocity_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.updateSpeedFields( false, $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateSpeedFields( false, $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 100"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_ejectionVelocity_textEdit"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateSpeedFields( false, $ThisControl.getValue() );"; + }; + }; + new GuiControl(){ // Emitter speed random + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Speed Random"; + }; + new GuiSliderCtrl(PEE_velocityVariance) { + internalName = "PEE_velocityVariance_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.updateSpeedFields( true, $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateSpeedFields( true, $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 100"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_velocityVariance_textEdit"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateSpeedFields( true, $ThisControl.getValue() );"; + }; + }; + + new GuiControl(){ // Spacer ---------------------------- + isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8"; + new GuiBitmapCtrl(){ + position="0 3"; extent ="188 2"; HorizSizing = "width"; + bitmap ="core/art/gui/images/separator-v"; + }; + };// end spacer ---------------------------------------- + + new GuiControl(){ // Emitter Orient to Movment Direction + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_checkbox_name; + text = "Orient to Movment Direction"; + }; + new GuiCheckBoxCtrl() { + internalName = "PEE_orientParticles"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_checkbox; + Extent = $PE_guielement_ext_checkbox; + text = ""; + command = "PE_EmitterEditor.updateEmitter( \"orientParticles\", $ThisControl.getValue());"; + }; + }; + new GuiControl(){ // Emitter Align to a Direction + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_checkbox_name; + text = "Align to a Direction"; + }; + new GuiCheckBoxCtrl() { + internalName = "PEE_alignParticles"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_checkbox; + Extent = $PE_guielement_ext_checkbox; + text = ""; + command = "PE_EmitterEditor.updateEmitter( \"alignParticles\", $ThisControl.getValue());"; + }; + }; + new GuiControl(){ // Emitter Align Direction + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Align Direction"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_alignDirection"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_textedit; + Extent = $PE_guielement_ext_textedit; + text = "0 0 0"; + altCommand = "PE_EmitterEditor.updateEmitter( \"alignDirection\", $ThisControl.getText());"; + }; + }; + }; // end stack + }; // end "motion" rollout + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "197 0"; + Caption = "Spread"; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "197 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl(){ // Emitter Angle Min + isContainer = "1"; + class = "AggregateControl"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiBitmapCtrl(){ // 0 Degrees + HorizSizing = "left"; + position = getWord($PE_guielement_pos_slider,0)+4 SPC "0"; + Extent = "2 18"; + minExtent = "0 0"; + bitmap = "core/art/gui/images/separator-h"; + tooltip = "0 Degrees ( Up )"; + }; + new GuiBitmapCtrl(){ // 90 Degrees + HorizSizing = "left"; + position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/4)+1 SPC "0"; + Extent = "2 18"; + minExtent = "0 0"; + bitmap = "core/art/gui/images/separator-h"; + tooltip = "90 Degrees ( Left )"; + }; + new GuiBitmapCtrl(){ // 180 Degrees + HorizSizing = "left"; + position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/2)-1 SPC "0"; + Extent = "2 18"; + minExtent = "0 0"; + bitmap = "core/art/gui/images/separator-h"; + tooltip = "180 Degrees ( Down )"; + }; + new GuiBitmapCtrl(){ // 270 Degrees + HorizSizing = "left"; + position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/2+mCeil(getWord($PE_guielement_ext_slider,0)/4))-4 SPC "0"; + Extent = "2 18"; + minExtent = "0 0"; + bitmap = "core/art/gui/images/separator-h"; + tooltip = "270 Degrees ( Right )"; + }; + new GuiBitmapCtrl(){ // 360 Degrees + HorizSizing = "left"; + position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0))-5 SPC "0"; + Extent = "2 18"; + minExtent = "0 0"; + bitmap = "core/art/gui/images/separator-h"; + tooltip = "360 Degrees ( Up )"; + }; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Angle Min"; + }; + new GuiSliderCtrl(PEE_thetaMin) { + internalName = "PEE_thetaMin_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.updateEmitter( \"thetaMin\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"thetaMin\", $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 180"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalname = "PEE_thetaMin_textEdit"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"thetaMin\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // Emitter Angle Max + isContainer = "1"; + class = "AggregateControl"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiBitmapCtrl(){ // 0 Degrees + HorizSizing = "left"; + position = getWord($PE_guielement_pos_slider,0)+4 SPC "0"; + Extent = "2 18"; + minExtent = "0 0"; + bitmap = "core/art/gui/images/separator-h"; + tooltip = "0 Degrees ( Up )"; + }; + new GuiBitmapCtrl(){ // 90 Degrees + HorizSizing = "left"; + position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/4)+1 SPC "0"; + Extent = "2 18"; + minExtent = "0 0"; + bitmap = "core/art/gui/images/separator-h"; + tooltip = "90 Degrees ( Left )"; + }; + new GuiBitmapCtrl(){ // 180 Degrees + HorizSizing = "left"; + minExtent = "0 0"; + position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/2)-1 SPC "0"; + Extent = "2 18"; + bitmap = "core/art/gui/images/separator-h"; + tooltip = "180 Degrees ( Down )"; + }; + new GuiBitmapCtrl(){ // 270 Degrees + HorizSizing = "left"; + position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/2+mCeil(getWord($PE_guielement_ext_slider,0)/4))-4 SPC "0"; + Extent = "2 18"; + minExtent = "0 0"; + bitmap = "core/art/gui/images/separator-h"; + tooltip = "270 Degrees ( Right )"; + }; + new GuiBitmapCtrl(){ // 360 Degrees + HorizSizing = "left"; + position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0))-5 SPC "0"; + Extent = "2 18"; + minExtent = "0 0"; + bitmap = "core/art/gui/images/separator-h"; + tooltip = "360 Degrees ( Up )"; + }; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Angle Max"; + }; + new GuiSliderCtrl(PEE_thetaMax) { + internalName = "PEE_thetaMax_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.updateEmitter( \"thetaMax\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"thetaMax\", $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 180"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_thetaMax_textEdit"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"thetaMax\", $ThisControl.getText());"; + }; + }; + + new GuiControl(){ // Spacer ---------------------------- + isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8"; + new GuiBitmapCtrl(){ + position="0 3"; extent ="188 2"; HorizSizing = "width"; + bitmap ="core/art/gui/images/separator-v"; + }; + };// end spacer ---------------------------------------- + + new GuiControl(){ // Emitter Depth + isContainer = "1"; + class = "AggregateControl"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Depth"; + }; + new GuiSliderCtrl(PEE_phiVariance) { + internalName = "PEE_phiVariance_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.updateEmitter( \"phiVariance\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"phiVariance\", $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 360"; + ticks = "0"; + value = "360"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_phiVariance_textEdit"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"phiVariance\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // Emitter Offset + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Offset"; + }; + new GuiSliderCtrl(PEE_ejectionOffset) { + internalName = "PEE_ejectionOffset_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.updateEmitter( \"ejectionOffset\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"ejectionOffset\", $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 10"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_ejectionOffset_textEdit"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"ejectionOffset\", $ThisControl.getText());"; + }; + }; + }; // end stack + }; // end "spread" rollout + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "197 0"; + Caption = "Particles"; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "197 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl(PEE_EmitterParticle1){ // emmiter particle 1 + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Particle 1"; + }; + new GuiPopUpMenuCtrl(PEE_EmitterParticleSelector1) { + internalName = "PopUpMenu"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_textedit; + Extent = $PE_guielement_ext_textedit; + text = ""; + command = "PE_EmitterEditor.updateParticlesFields($ThisControl);"; + }; + }; + new GuiControl(PEE_EmitterParticle2){ // emmiter particle 2 + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Particle 2"; + }; + new GuiPopUpMenuCtrl(PEE_EmitterParticleSelector2) { + internalName = "PopUpMenu"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_textedit; + Extent = $PE_guielement_ext_textedit; + text = "None"; + command = "PE_EmitterEditor.updateParticlesFields();"; + }; + // Clear particle 2 + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "56 1"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "%particleId = PEE_EmitterParticle2-->PopUpMenu.findText( \"None\" ); PEE_EmitterParticle2-->PopUpMenu.setSelected( %particleId );PE_EmitterEditor.updateParticlesFields();"; + hovertime = "1000"; + tooltip = "Clear Particle 2 from Emitter"; + text = ""; + bitmap = "tools/gui/images/clear-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; + new GuiControl(PEE_EmitterParticle3){ // emmiter particle 3 + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Particle 3"; + }; + new GuiPopUpMenuCtrl(PEE_EmitterParticleSelector3) { + internalName = "PopUpMenu"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_textedit; + Extent = $PE_guielement_ext_textedit; + text = "None"; + command = "PE_EmitterEditor.updateParticlesFields();"; + }; + // Clear particle 3 + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "56 1"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "%particleId = PEE_EmitterParticle3-->PopUpMenu.findText( \"None\" ); PEE_EmitterParticle3-->PopUpMenu.setSelected( %particleId );PE_EmitterEditor.updateParticlesFields();"; + hovertime = "1000"; + tooltip = "Clear Particle 3 from Emitter"; + text = ""; + bitmap = "tools/gui/images/clear-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; + new GuiControl(PEE_EmitterParticle4){ // emmiter particle 4 + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Particle 4"; + }; + new GuiPopUpMenuCtrl(PEE_EmitterParticleSelector4) { + internalName = "PopUpMenu"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_textedit; + Extent = $PE_guielement_ext_textedit; + text = "None"; + command = "PE_EmitterEditor.updateParticlesFields();"; + }; + // Clear particle 4 + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "56 1"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "%particleId = PEE_EmitterParticle4-->PopUpMenu.findText( \"None\" ); PEE_EmitterParticle4-->PopUpMenu.setSelected( %particleId );PE_EmitterEditor.updateParticlesFields();"; + hovertime = "1000"; + tooltip = "Clear Particle 4 from Emitter"; + text = ""; + bitmap = "tools/gui/images/clear-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; + }; // end stack + }; // end "particles" rollout + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "197 0"; + Caption = "Blending"; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "197 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl(){ // Blend type + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Blend Type"; + }; + new GuiPopUpMenuCtrl() { + internalName = "PEE_blendType"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_textedit; + Extent = $PE_guielement_ext_textedit; + command = "PE_EmitterEditor.updateEmitter( \"blendStyle\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // softness Distance + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Softness Distance "; + }; + new GuiSliderCtrl() { + internalName = "PEE_softnessDistance_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + hovertime = "1000"; + range = "0 1000"; + ticks = "0"; + value = "0"; + Command = "PE_EmitterEditor.updateEmitter( \"softnessDistance\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"softnessDistance\", $ThisControl.getValue(), true, false );"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_softnessDistance_textEdit"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"softnessDistance\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // Ambient Factor + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Ambient Factor"; + }; + new GuiSliderCtrl() { + internalName = "PEE_ambientFactor_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + hovertime = "1000"; + range = "0 10"; + ticks = "0"; + value = "0"; + Command = "PE_EmitterEditor.updateEmitter( \"ambientFactor\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"ambientFactor\", $ThisControl.getValue(), true, false );"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_ambientFactor_textEdit"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"ambientFactor\", $ThisControl.getText));"; + }; + }; + + new GuiControl(){ // Spacer ---------------------------- + isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8"; + new GuiBitmapCtrl(){ + position="0 3"; extent ="188 2"; HorizSizing = "width"; + bitmap ="core/art/gui/images/separator-v"; + }; + };// end spacer ---------------------------------------- + + new GuiControl(){ // Sort Particles + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_checkbox_name; + text = "Sort Particles"; + }; + new GuiCheckBoxCtrl() { + internalName = "PEE_softParticles"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_checkbox; + Extent = $PE_guielement_ext_checkbox; + text = ""; + command = "PE_EmitterEditor.updateEmitter( \"softParticles\", $ThisControl.getValue());"; + }; + }; + new GuiControl(){ // Emitter Reverse Order + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_checkbox_name; + text = "Reverse Order"; + }; + new GuiCheckBoxCtrl() { + internalName = "PEE_reverseOrder"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_checkbox; + Extent = $PE_guielement_ext_checkbox; + text = ""; + command = "PE_EmitterEditor.updateEmitter( \"reverseOrder\", $ThisControl.getValue());"; + }; + }; + new GuiControl(){ // Emitter Use Emitter Size + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_checkbox_name; + text = "Use Emitter Size"; + }; + new GuiCheckBoxCtrl(PEE_useEmitterSizes) { + internalName = "PEE_useEmitterSizes"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_checkbox; + Extent = $PE_guielement_ext_checkbox; + text = ""; + command = "PE_EmitterEditor.updateEmitter( \"useEmitterSizes\", $ThisControl.getValue());"; + }; + }; + new GuiControl(){ // Emitter use Material Effect Color + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_checkbox_name; + text = "Use Material Effect Color"; + }; + new GuiCheckBoxCtrl(PEE_useEmitterColors) { + internalName = "PEE_useEmitterColors"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_checkbox; + Extent = $PE_guielement_ext_checkbox; + text = ""; + command = "PE_EmitterEditor.updateEmitter( \"useEmitterColors\", $ThisControl.getValue());"; + }; + }; + }; // end stack + }; // end "Blending" rollout + };// end stack "Emitter" + };// end scroll "Emitter" + };// end tab page "Emitter" + new GuiTabPageCtrl(PE_ParticleEditor) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "EditorTabPage"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 19"; + Extent = "197 271"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Particle"; + maxLength = "1024"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "197 271"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = false; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "197 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl(PEP_ParticleSelector_Control){ // PEP_ParticleSelector + isContainer = "1"; + class = "QuickEditDropDownTextEditCtrl"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = "197 26" ; + + new GuiPopUpMenuCtrl(PEP_ParticleSelector) { + internalName = "PopUpMenu"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "4 4"; + Extent = "123 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.onNewParticle();"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + new GuiTextEditCtrl() { + internalName = "TextEdit"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDropdownTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "4 4"; + Extent = "107 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl);"; + }; + new GuiBitmapButtonCtrl( PEP_NewParticleButton ) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "131 5"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "core/art/gui/images/new"; + tooltip = "Add New Particle To Current Emitter"; + useModifiers = "1"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "147 5"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/save-icon"; + command = "PE_ParticleEditor.saveParticle( PE_ParticleEditor.currParticle );"; + tooltip = "Save Current Particle"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "164 5"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_ParticleEditor.showDeleteDialog();"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + tooltip = "Delete Current Particle"; + }; + }; + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "197 0"; + Caption = "Basic"; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "197 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ // particle texture map + profile="GuiDefaultProfile"; + isContainer = "1"; + position = "0 0"; + Extent = "185 52"; + HorizSizing = "width"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialeditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -2"; + Extent = "72 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Texture Map"; + maxLength = "1024"; + }; + new GuiBitmapButtonCtrl() { + internalName = "PEP_previewImage"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Edit Selected Particle."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Edit Selected Particle."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + Command = "PE_ParticleEditor.updateParticleTexture(1);"; + }; + new GuiCheckBoxCtrl() { + internalName = "PEP_inverseAlpha"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "55 14"; + Extent = "84 18"; + MinExtent = "8 2"; + text = "Inverse Alpha"; + command = "PE_ParticleEditor.updateParticle( \"useInvAlpha\", $ThisControl.getValue());"; + }; + new GuiTextEditCtrl(PEP_textureName) { + internalName = "PEP_previewImageName"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "55 31"; + Extent = "120 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiButtonCtrl(){ + profile="GuiButtonProfile"; + text ="Edit"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "138 0"; + Extent = "36 18" ; + buttonType = "PushButton"; + Command = "PE_ParticleEditor.updateParticleTexture(1);"; + }; + }; + + new GuiControl(){ // Spacer ---------------------------- + isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8"; + //visible = false; + new GuiBitmapCtrl(){ + position="0 3"; extent ="188 2"; HorizSizing = "width"; + bitmap ="core/art/gui/images/separator-v"; + }; + };// end spacer ---------------------------------------- + + new GuiControl(){ // particle life + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Life"; + maxLength = "255"; + }; + new GuiSliderCtrl(PEP_lifetimeMS) { + internalName = "PEP_lifetimeMS_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_ParticleEditor.updateLifeFields( false, $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateLifeFields( false, $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "1 9000"; + ticks = "0"; + value = "3000"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_lifetimeMS_textEdit"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateLifeFields( false, $ThisControl.getText() );"; + }; + }; + new GuiControl(){ // particle life Random + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Life Random"; + maxLength = "255"; + }; + new GuiSliderCtrl(PEP_lifetimeVarianceMS) { + internalName = "PEP_lifetimeVarianceMS_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_ParticleEditor.updateLifeFields( true, $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateLifeFields( true, $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 8999"; + ticks = "0"; + value = "3000"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_lifetimeVarianceMS_textEdit"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateLifeFields( true, $ThisControl.getText() );"; + }; + }; + }; // end stack + }; // end "Particles Basic" rollout + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "197 0"; + Caption = "Motion"; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "197 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl(){ // Particle Initial speed + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Initial Speed"; + }; + new GuiSliderCtrl(PEP_inheritedVelFactor) { + internalName = "PEP_inheritedVelFactor_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_ParticleEditor.updateParticle( \"inheritedVelFactor\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"inheritedVelFactor\", $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 10"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_inheritedVelFactor_textEdit"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"inheritedVelFactor\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // Particle Acceleration + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Acceleration"; + }; + new GuiSliderCtrl(PEP_constantAcceleration) { + internalName = "PEP_constantAcceleration_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_ParticleEditor.updateParticle( \"constantAcceleration\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"constantAcceleration\", $ThisControl.getValue(), true, false);"; + hovertime = "1000"; + range = "-10 10"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_constantAcceleration_textEdit"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"constantAcceleration\", $ThisControl.getText());"; + }; + }; + + new GuiControl(){ // Spacer ---------------------------- + isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8"; + new GuiBitmapCtrl(){ + position="0 3"; extent ="188 2"; HorizSizing = "width"; + bitmap ="core/art/gui/images/separator-v"; + }; + };// end spacer ---------------------------------------- + + new GuiControl(){ // Particle Gravity + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiBitmapCtrl(){ // 0 Gravity + HorizSizing = "left"; + position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/2)-1 SPC "0"; + Extent = "2 18"; + minExtent = "0 0"; + bitmap = "core/art/gui/images/separator-h"; + tooltip = "0 Gravity"; + }; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Gravity"; + }; + new GuiSliderCtrl(PEP_gravityCoefficient) { + internalName = "PEP_gravityCoefficient_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_ParticleEditor.updateParticle( \"gravityCoefficient\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"gravityCoefficient\", $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "-1 1"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_gravityCoefficient_textEdit"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"gravityCoefficient\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // Particle Drag + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Drag"; + }; + new GuiSliderCtrl(PEP_dragCoefficient) { + internalName = "PEP_dragCoefficient_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_ParticleEditor.updateParticle( \"dragCoefficient\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"dragCoefficient\", $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 1"; + ticks = "0"; + value = "0.298143"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_dragCoefficient_textEdit"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"dragCoefficient\", $ThisControl.getText());"; + }; + }; + }; // end stack + }; // end "motion" rollout + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "197 0"; + Caption = "Spin"; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "197 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl(){ // Particle spin Min + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiBitmapCtrl(){ // No Spin + HorizSizing = "left"; + position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/2)-1 SPC "0"; + Extent = "2 18"; + minExtent = "0 0"; + bitmap = "core/art/gui/images/separator-h"; + tooltip = "No Spin"; + }; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Spin Min"; + }; + new GuiSliderCtrl(PEP_spinRandomMin) { + internalName = "PEP_spinRandomMin_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_ParticleEditor.updateSpinFields( true, $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateSpinFields( true, $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "-1000 999"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_spinRandomMin_textEdit"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateSpinFields( true, $ThisControl.getText() );"; + }; + }; + new GuiControl(){ // Particle Spin Max + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiBitmapCtrl(){ // No Spin + HorizSizing = "left"; + position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/2)-1 SPC "0"; + Extent = "2 18"; + minExtent = "0 0"; + bitmap = "core/art/gui/images/separator-h"; + tooltip = "No Spin"; + }; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Spin Max"; + }; + new GuiSliderCtrl(PEP_spinRandomMax) { + internalName = "PEP_spinRandomMax_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_ParticleEditor.updateSpinFields( false, $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateSpinFields( false, $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "-999 1000"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_spinRandomMax_textEdit"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateSpinFields( false, $ThisControl.getText() );"; + }; + }; + + new GuiControl(){ // Spacer ---------------------------- + isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8"; + new GuiBitmapCtrl(){ + position="0 3"; extent ="188 2"; HorizSizing = "width"; + bitmap ="core/art/gui/images/separator-v"; + }; + };// end spacer ---------------------------------------- + + new GuiControl(){ // Particle spin Speed + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Spin Speed"; + }; + new GuiSliderCtrl(PEP_spinSpeed) { + internalName = "PEP_spinSpeed_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + range = "0 1"; + ticks = "0"; + value = "0"; + Command = "PE_ParticleEditor.updateParticle( \"spinSpeed\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"spinSpeed\", $ThisControl.getValue(), true, false );"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_spinSpeed_textEdit"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"spinSpeed\", $ThisControl.getText());"; + }; + }; + }; // end stack + }; // end "Spin" rollout + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "197 0"; + Caption = "Overtime"; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "197 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl(){ // Particle Point Colors + class = ""; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Colors"; + }; + new GuiSwatchButtonCtrl(PE_ColorTintSwatch0) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorSwatchButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "75 0"; + Extent = $PE_guielement_ext_colorpicker; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "getColorF( PE_ParticleEditor.currParticle.colors[0], \"PE_ColorTintSwatch0.updateParticleColor\");"; + altCommand = "$ThisControl.updateParticleColor( $ThisControl.color );"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + arrayNum = "0"; + class = "PE_ColorTintSwatch"; + }; + new GuiSwatchButtonCtrl(PE_ColorTintSwatch1) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorSwatchButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "102 0"; + Extent = $PE_guielement_ext_colorpicker; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "getColorF( PE_ParticleEditor.currParticle.colors[1], \"PE_ColorTintSwatch1.updateParticleColor\");"; + altCommand = "$ThisControl.updateParticleColor( $ThisControl.color );"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + arrayNum = "1"; + class = "PE_ColorTintSwatch"; + }; + new GuiSwatchButtonCtrl(PE_ColorTintSwatch2) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorSwatchButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "129 0"; + Extent = $PE_guielement_ext_colorpicker; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "getColorF( PE_ParticleEditor.currParticle.colors[2], \"PE_ColorTintSwatch2.updateParticleColor\");"; + altCommand = "$ThisControl.updateParticleColor( $ThisControl.color );"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + arrayNum = "2"; + class = "PE_ColorTintSwatch"; + }; + new GuiSwatchButtonCtrl(PE_ColorTintSwatch3) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorSwatchButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "156 0"; + Extent = $PE_guielement_ext_colorpicker; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "getColorF( PE_ParticleEditor.currParticle.colors[3], \"PE_ColorTintSwatch3.updateParticleColor\");"; + altCommand = "$ThisControl.updateParticleColor( $ThisControl.color );"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + arrayNum = "3"; + class = "PE_ColorTintSwatch"; + }; + }; + + new GuiControl(){ // Spacer ---------------------------- + isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8"; + new GuiBitmapCtrl(){ + position="0 3"; extent ="188 2"; HorizSizing = "width"; + bitmap ="core/art/gui/images/separator-v"; + }; + };// end spacer ---------------------------------------- + + new GuiControl(){ // Particle Point Size + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Size 1"; + }; + new GuiSliderCtrl() { + internalName = "PEP_pointSize_slider0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + hovertime = "1000"; + range = "0 50"; + ticks = "0"; + value = "0"; + Command = "PE_ParticleEditor.updateParticle( \"sizes[0]\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[0]\", $ThisControl.getValue(), true, false );"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_pointSize_textEdit0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[0]\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // Particle Point Size + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Size 2"; + }; + new GuiSliderCtrl() { + internalName = "PEP_pointSize_slider1"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + hovertime = "1000"; + range = "0 50"; + ticks = "0"; + value = "0"; + Command = "PE_ParticleEditor.updateParticle( \"sizes[1]\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[1]\", $ThisControl.getValue(), true, false );"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_pointSize_textEdit1"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[1]\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // Particle Point Size + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Size 3"; + }; + new GuiSliderCtrl() { + internalName = "PEP_pointSize_slider2"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + hovertime = "1000"; + range = "0 50"; + ticks = "0"; + value = "0"; + Command = "PE_ParticleEditor.updateParticle( \"sizes[2]\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[2]\", $ThisControl.getValue(), true, false );"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_pointSize_textEdit2"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[2]\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // Particle Point Size + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Size 4"; + }; + new GuiSliderCtrl() { + internalName = "PEP_pointSize_slider3"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + hovertime = "1000"; + range = "0 50"; + ticks = "0"; + value = "0"; + Command = "PE_ParticleEditor.updateParticle( \"sizes[3]\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[3]\", $ThisControl.getValue(), true, false );"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_pointSize_textEdit3"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[3]\", $ThisControl.getText());"; + }; + }; + + new GuiControl(){ // Spacer ---------------------------- + isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8"; + new GuiBitmapCtrl(){ + position="0 3"; extent ="188 2"; HorizSizing = "width"; + bitmap ="core/art/gui/images/separator-v"; + }; + };// end spacer ---------------------------------------- + + new GuiControl(){ // Particle Point Time + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Time 1"; + }; + new GuiSliderCtrl() { + internalName = "PEP_pointTime_slider0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + hovertime = "1000"; + range = "0 1"; + ticks = "0"; + value = "0"; + Command = "PE_ParticleEditor.updateParticle( \"times[0]\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[0]\", $ThisControl.getValue(), true, false );"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_pointTime_textEdit0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.setText(mClamp( $ThisControl.getValue(), 0.0, 1.0)); $ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[0]\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // Particle Point Time + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Time 2"; + }; + new GuiSliderCtrl() { + internalName = "PEP_pointTime_slider1"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + hovertime = "1000"; + range = "0 1"; + ticks = "0"; + value = "0"; + Command = "PE_ParticleEditor.updateParticle( \"times[1]\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[1]\", $ThisControl.getValue(), true, false );"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_pointTime_textEdit1"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.setText(mClamp( $ThisControl.getValue(), 0.0, 1.0)); $ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[1]\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // Particle Point Time + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Time 3"; + }; + new GuiSliderCtrl() { + internalName = "PEP_pointTime_slider2"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + hovertime = "1000"; + range = "0 1"; + ticks = "0"; + value = "0"; + Command = "PE_ParticleEditor.updateParticle( \"times[2]\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[2]\", $ThisControl.getValue(), true, false );"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_pointTime_textEdit2"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.setText(mClamp( $ThisControl.getValue(), 0.0, 1.0)); $ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[2]\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // Particle Point Time + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Time 4"; + }; + new GuiSliderCtrl() { + internalName = "PEP_pointTime_slider3"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + hovertime = "1000"; + range = "0 1"; + ticks = "0"; + value = "0"; + Command = "PE_ParticleEditor.updateParticle( \"times[3]\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[3]\", $ThisControl.getValue(), true, false );"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_pointTime_textEdit3"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.setText(mClamp( $ThisControl.getValue(), 0.0, 1.0)); $ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[3]\", $ThisControl.getText());"; + }; + }; + }; // end stack + }; // end "Overtime" rollout + };// end stack "Particles" + };// end scroll "Particles" + };// end tab page "Particles" + };// end tab book + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "169 25"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ParticleEditor.updateEmitterNode();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Play Particle Effect from Start"; + hovertime = "1000"; + bitmap = "tools/particleEditor/images/play_btn"; + buttonType = "PushButton"; + groupNum = "-1"; + text = ""; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "189 26"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ParticleEditor.resetEmitterNode();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Drops Particle Effect in front of the Camera"; + hovertime = "1000"; + bitmap = "tools/classIcons/camera"; + buttonType = "PushButton"; + groupNum = "-1"; + text = ""; + useMouseEvents = "0"; + }; +};// end window +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/particleEditor/images/play_btn_d.png b/Templates/Empty/game/tools/particleEditor/images/play_btn_d.png new file mode 100644 index 000000000..518a15685 Binary files /dev/null and b/Templates/Empty/game/tools/particleEditor/images/play_btn_d.png differ diff --git a/Templates/Empty/game/tools/particleEditor/images/play_btn_h.png b/Templates/Empty/game/tools/particleEditor/images/play_btn_h.png new file mode 100644 index 000000000..87543b362 Binary files /dev/null and b/Templates/Empty/game/tools/particleEditor/images/play_btn_h.png differ diff --git a/Templates/Empty/game/tools/particleEditor/images/play_btn_n.png b/Templates/Empty/game/tools/particleEditor/images/play_btn_n.png new file mode 100644 index 000000000..7fadf843d Binary files /dev/null and b/Templates/Empty/game/tools/particleEditor/images/play_btn_n.png differ diff --git a/Templates/Empty/game/tools/particleEditor/main.cs b/Templates/Empty/game/tools/particleEditor/main.cs new file mode 100644 index 000000000..0283b35c3 --- /dev/null +++ b/Templates/Empty/game/tools/particleEditor/main.cs @@ -0,0 +1,178 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Initialization and shutdown code for particle editor plugin. + + +//--------------------------------------------------------------------------------------------- + +function initializeParticleEditor() +{ + echo( " % - Initializing Particle Editor" ); + + exec( "./ParticleEditor.ed.gui" ); + exec( "./particleEditor.ed.cs" ); + exec( "./particleEditorUndo.ed.cs" ); + exec( "./particleEmitterEditor.ed.cs" ); + exec( "./particleParticleEditor.ed.cs" ); + + PE_Window.setVisible( false ); + EditorGui.add( PE_Window ); + + new ScriptObject( ParticleEditorPlugin ) + { + superClass = "WorldEditorPlugin"; + editorGui = EWorldEditor; + }; + + %map = new ActionMap(); + %map.bindCmd( keyboard, "1", "EWorldEditorNoneModeBtn.performClick();", "" ); // Select + %map.bindCmd( keyboard, "2", "EWorldEditorMoveModeBtn.performClick();", "" ); // Move + %map.bindCmd( keyboard, "3", "EWorldEditorRotateModeBtn.performClick();", "" ); // Rotate + %map.bindCmd( keyboard, "4", "EWorldEditorScaleModeBtn.performClick();", "" ); // Scale + + ParticleEditorPlugin.map = %map; + + new ScriptObject( ParticleEditor ); + + new PersistenceManager( PE_EmitterSaver ); + new PersistenceManager( PE_ParticleSaver ); + + new SimSet( PE_UnlistedParticles ); + new SimSet( PE_UnlistedEmitters ); +} + +//--------------------------------------------------------------------------------------------- + +function destroyParticleEditor() +{ +} + +//============================================================================================= +// ParticleEditorPlugin. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ParticleEditorPlugin::onWorldEditorStartup( %this ) +{ + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Particle Editor", "", ParticleEditorPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "Particle Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "ParticleEditorPlugin", "ParticleEditorPalette", expandFilename("tools/worldEditor/images/toolbar/particleeditor"), %tooltip ); +} + +//--------------------------------------------------------------------------------------------- + +function ParticleEditorPlugin::onActivated( %this ) +{ + if( !ParticleEditor.isInitialized ) + { + ParticleEditor.initEditor(); + ParticleEditor.isInitialized = true; + } + + EditorGui-->WorldEditorToolbar.setVisible( true ); + EditorGui.bringToFront( PE_Window); + PE_Window.setVisible( true ); + PE_Window.makeFirstResponder( true ); + + %this.map.push(); + + ParticleEditor.resetEmitterNode(); + + // Set the status bar here + EditorGuiStatusBar.setInfo( "Particle editor." ); + EditorGuiStatusBar.setSelection( "" ); + + Parent::onActivated( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ParticleEditorPlugin::onDeactivated( %this ) +{ + EditorGui-->WorldEditorToolbar.setVisible( false ); + PE_Window.setVisible( false ); + + if( isObject( $ParticleEditor::emitterNode) ) + $ParticleEditor::emitterNode.delete(); + + %this.map.pop(); + + Parent::onDeactivated( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ParticleEditorPlugin::onExitMission( %this ) +{ + // Force Particle Editor to re-initialize. + ParticleEditor.isInitialized = false; + + Parent::onExitMission( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ParticleEditorPlugin::initSettings( %this ) +{ + EditorSettings.beginGroup( "ParticleEditor", true ); + + EditorSettings.setDefaultValue( "selectedTab", 0 ); + + EditorSettings.endGroup(); +} + +//--------------------------------------------------------------------------------------------- + +function ParticleEditorPlugin::readSettings( %this ) +{ + EditorSettings.beginGroup( "ParticleEditor", true ); + + %selectedEmitter = EditorSettings.value( "selectedEmitter" ); + if( isObject( %selectedEmitter ) ) + PEE_EmitterSelector.setSelected( %selectedEmitter.getId() ); + + %selectedParticle = EditorSettings.value( "selectedParticle" ); + if( isObject( %selectedParticle ) ) + PEP_ParticleSelector.setSelected( %selectedParticle.getId() ); + + PE_TabBook.selectPage( EditorSettings.value( "selectedPage" ) ); + + EditorSettings.endGroup(); +} + +//--------------------------------------------------------------------------------------------- + +function ParticleEditorPlugin::writeSettings( %this ) +{ + EditorSettings.beginGroup( "ParticleEditor", true ); + + EditorSettings.setValue( "selectedEmitter", PEE_EmitterSelector.getText() ); + EditorSettings.setValue( "selectedParticle", PEP_ParticleSelector.getText() ); + EditorSettings.setValue( "selectedTab", PE_TabBook.getSelectedPage() ); + + EditorSettings.endGroup(); +} diff --git a/Templates/Empty/game/tools/particleEditor/particleEditor.ed.cs b/Templates/Empty/game/tools/particleEditor/particleEditor.ed.cs new file mode 100644 index 000000000..a01d36af4 --- /dev/null +++ b/Templates/Empty/game/tools/particleEditor/particleEditor.ed.cs @@ -0,0 +1,255 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +// Open the particle editor to spawn a test emitter in front of the player. +// Edit the sliders, check boxes, and text fields and see the results in +// realtime. Switch between emitters and particles with the buttons in the +// top left corner. When in particle mode, the only particles available will +// be those assigned to the current emitter to avoid confusion. In the top +// right corner, there is a button marked "Drop Emitter", which will spawn the +// test emitter in front of the player again, and a button marked "Restart +// Emitter", which will play the particle animation again. + + +//============================================================================================= +// ParticleEditor. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ParticleEditor::initEditor( %this ) +{ + echo( "Initializing ParticleEmitterData and ParticleData DataBlocks..." ); + + datablock ParticleEmitterData(PE_EmitterEditor_NotDirtyEmitter) + { + particles = "RocketProjSmokeTrail"; + }; + datablock ParticleData(PE_ParticleEditor_NotDirtyParticle) + { + textureName = "art/shapes/particles/smoke"; + }; + + PE_UnlistedEmitters.add( PE_EmitterEditor_NotDirtyEmitter ); + PE_UnlistedEmitters.add( PE_ParticleEditor_NotDirtyParticle ); + + PEE_EmitterSelector.clear(); + PEE_EmitterParticleSelector1.clear(); + PEE_EmitterParticleSelector2.clear(); + PEE_EmitterParticleSelector3.clear(); + PEE_EmitterParticleSelector4.clear(); + + PEP_ParticleSelector.clear(); + + ParticleEditor.createParticleList(); + + PEE_EmitterParticleSelector2.add( "None", 0 ); + PEE_EmitterParticleSelector3.add( "None", 0 ); + PEE_EmitterParticleSelector4.add( "None", 0 ); + + PEE_EmitterParticleSelector1.sort(); + PEE_EmitterParticleSelector2.sort(); + PEE_EmitterParticleSelector3.sort(); + PEE_EmitterParticleSelector4.sort(); + + PE_EmitterEditor-->PEE_blendType.clear(); + PE_EmitterEditor-->PEE_blendType.add( "NORMAL", 0 ); + PE_EmitterEditor-->PEE_blendType.add( "ADDITIVE", 1 ); + PE_EmitterEditor-->PEE_blendType.add( "SUBTRACTIVE", 2 ); + PE_EmitterEditor-->PEE_blendType.add( "PREMULTALPHA", 3 ); + + + PEE_EmitterSelector.setFirstSelected(); + + PE_Window-->EditorTabBook.selectPage( 0 ); +} + +function ParticleEditor::createParticleList( %this ) +{ + // This function creates the list of all particles and particle emitters + + %emitterCount = 0; + %particleCount = 0; + + foreach( %obj in DatablockGroup ) + { + if( %obj.isMemberOfClass( "ParticleEmitterData" ) ) + { + // Filter out emitters on the PE_UnlistedEmitters list. + + %unlistedFound = false; + foreach( %unlisted in PE_UnlistedEmitters ) + if( %unlisted.getId() == %obj.getId() ) + { + %unlistedFound = true; + break; + } + + if( %unlistedFound ) + continue; + + // To prevent our default emitters from getting changed, + // prevent them from populating the list. Default emitters + // should only be used as a template for creating new ones. + if ( %obj.getName() $= "DefaultEmitter") + continue; + + PEE_EmitterSelector.add( %obj.getName(), %obj.getId() ); + %emitterCount ++; + } + else if( %obj.isMemberOfClass( "ParticleData" ) ) + { + %unlistedFound = false; + foreach( %unlisted in PE_UnlistedParticles ) + if( %unlisted.getId() == %obj.getId() ) + { + %unlistedFound = true; + break; + } + + if( %unlistedFound ) + continue; + + %name = %obj.getName(); + %id = %obj.getId(); + + if ( %name $= "DefaultParticle") + continue; + + // Add to particle dropdown selectors. + + PEE_EmitterParticleSelector1.add( %name, %id ); + PEE_EmitterParticleSelector2.add( %name, %id ); + PEE_EmitterParticleSelector3.add( %name, %id ); + PEE_EmitterParticleSelector4.add( %name, %id ); + + %particleCount ++; + } + } + + PEE_EmitterSelector.sort(); + PEE_EmitterParticleSelector1.sort(); + PEE_EmitterParticleSelector2.sort(); + PEE_EmitterParticleSelector3.sort(); + PEE_EmitterParticleSelector4.sort(); + + echo( "Found" SPC %emitterCount SPC "emitters and" SPC %particleCount SPC "particles." ); +} + +//--------------------------------------------------------------------------------------------- + +function ParticleEditor::openEmitterPane( %this ) +{ + PE_Window.text = "Particle Editor - Emitters"; + PE_EmitterEditor.guiSync(); + ParticleEditor.activeEditor = PE_EmitterEditor; + + if( !PE_EmitterEditor.dirty ) + PE_EmitterEditor.setEmitterNotDirty(); +} + +//--------------------------------------------------------------------------------------------- + +function ParticleEditor::openParticlePane( %this ) +{ + PE_Window.text = "Particle Editor - Particles"; + + PE_ParticleEditor.guiSync(); + ParticleEditor.activeEditor = PE_ParticleEditor; + + if( !PE_ParticleEditor.dirty ) + PE_ParticleEditor.setParticleNotDirty(); +} + +//--------------------------------------------------------------------------------------------- + +function ParticleEditor::resetEmitterNode( %this ) +{ + %tform = ServerConnection.getControlObject().getEyeTransform(); + %vec = VectorNormalize( ServerConnection.getControlObject().getForwardVector() ); + %vec = VectorScale( %vec, 4 ); + %tform = setWord( %tform, 0, getWord( %tform, 0 ) + getWord( %vec, 0 ) ); + %tform = setWord( %tform, 1, getWord( %tform, 1 ) + getWord( %vec, 1 ) ); + %tform = setWord( %tform, 2, getWord( %tform, 2 ) + getWord( %vec, 2 ) ); + + if( !isObject( $ParticleEditor::emitterNode ) ) + { + if( !isObject( TestEmitterNodeData ) ) + { + datablock ParticleEmitterNodeData( TestEmitterNodeData ) + { + timeMultiple = 1; + }; + } + + $ParticleEditor::emitterNode = new ParticleEmitterNode() + { + emitter = PEE_EmitterSelector.getText(); + velocity = 1; + position = getWords( %tform, 0, 2 ); + rotation = getWords( %tform, 3, 6 ); + datablock = TestEmitterNodeData; + parentGroup = MissionCleanup; + }; + } + else + { + $ParticleEditor::emitterNode.setTransform( %tform ); + + %clientObject = $ParticleEditor::emitterNode.getClientObject(); + if( isObject( %clientObject ) ) + %clientObject.setTransform( %tform ); + + ParticleEditor.updateEmitterNode(); + } +} + +//--------------------------------------------------------------------------------------------- + +function ParticleEditor::updateEmitterNode( %this ) +{ + if( isObject( $ParticleEditor::emitterNode ) ) + { + %id = PEE_EmitterSelector_Control-->PopUpMenu.getSelected(); + + %clientObject = $ParticleEditor::emitterNode.getClientObject(); + if( isObject( %clientObject ) ) + %clientObject.setEmitterDataBlock( %id ); + } + else + %this.resetEmitterNode(); +} + +//============================================================================================= +// PE_TabBook. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function PE_TabBook::onTabSelected( %this, %text, %idx ) +{ + if( %idx == 0 ) + ParticleEditor.openEmitterPane(); + else + ParticleEditor.openParticlePane(); +} diff --git a/Templates/Empty/game/tools/particleEditor/particleEditorUndo.ed.cs b/Templates/Empty/game/tools/particleEditor/particleEditorUndo.ed.cs new file mode 100644 index 000000000..f1e753d5e --- /dev/null +++ b/Templates/Empty/game/tools/particleEditor/particleEditorUndo.ed.cs @@ -0,0 +1,606 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +//============================================================================================= +// ParticleEditor. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ParticleEditor::createUndo( %this, %class, %desc ) +{ + pushInstantGroup(); + %action = new UndoScriptAction() + { + class = %class; + superClass = BaseParticleEdAction; + actionName = %desc; + }; + popInstantGroup(); + return %action; +} + +//--------------------------------------------------------------------------------------------- + +function ParticleEditor::submitUndo( %this, %action ) +{ + %action.addToManager( Editor.getUndoManager() ); +} + +//============================================================================================= +// BaseParticleEdAction. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function BaseParticleEdAction::sync( %this ) +{ + // Sync particle state. + + if( isObject( %this.particle ) ) + { + %this.particle.reload(); + PE_ParticleEditor.guiSync(); + + if( %this.particle.getId() == PE_ParticleEditor.currParticle.getId() ) + PE_ParticleEditor.setParticleDirty(); + } + + // Sync emitter state. + + if( isObject( %this.emitter ) ) + { + %this.emitter.reload(); + + PE_EmitterEditor.guiSync(); + + if( %this.emitter.getId() == PE_EmitterEditor.currEmitter.getId() ) + PE_EmitterEditor.setEmitterDirty(); + } +} + +//--------------------------------------------------------------------------------------------- + +function BaseParticleEdAction::redo( %this ) +{ + %this.sync(); +} + +//--------------------------------------------------------------------------------------------- + +function BaseParticleEdAction::undo( %this ) +{ + %this.sync(); +} + +//============================================================================================= +// ActionRenameEmitter. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +//TODO + +//============================================================================================= +// ActionCreateNewEmitter. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionCreateNewEmitter::redo( %this ) +{ + %emitter = %this.emitter; + + // Assign name. + + %emitter.name = %this.emitterName; + + // Remove from unlisted. + + PE_UnlistedEmitters.remove( %emitter ); + + // Drop it in the dropdown and select it. + + %popup = PEE_EmitterSelector; + + %popup.add( %emitter.getName(), %emitter.getId() ); + %popup.sort(); + %popup.setSelected( %emitter.getId() ); + + // Sync up. + + Parent::redo( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ActionCreateNewEmitter::undo( %this ) +{ + %emitter = %this.emitter; + + // Prevent a save dialog coming up on the emitter. + + if( %emitter == PE_EmitterEditor.currEmitter ) + PE_EmitterEditor.setEmitterNotDirty(); + + // Add to unlisted. + + PE_UnlistedEmitters.add( %emitter ); + + // Remove it from in the dropdown and select prev emitter. + + %popup = PEE_EmitterSelector; + + if( isObject( %this.prevEmitter ) ) + %popup.setSelected( %this.prevEmitter.getId() ); + else + %popup.setFirstSelected(); + + %popup.clearEntry( %emitter.getId() ); + + // Unassign name. + + %this.emitterName = %emitter.name; + %emitter.name = ""; + + // Sync up. + + Parent::undo( %this ); +} + +//============================================================================================= +// ActionDeleteEmitter. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionDeleteEmitter::redo( %this ) +{ + %emitter = %this.emitter; + + // Unassign name. + + %this.emitterName = %emitter.name; + %emitter.name = ""; + + // Add to unlisted. + + PE_UnlistedEmitters.add( %emitter ); + + // Remove from file. + + if( %emitter.getFileName() !$= "" + && %emitter.getFilename() !$= "tools/particleEditor/particleEmitterEditor.ed.cs" ) + PE_EmitterSaver.removeObjectFromFile( %emitter ); + + // Select DefaultEmitter or first in list. + + %popup = PEE_EmitterSelector_Control-->PopUpMenu; + + %popup.setFirstSelected(); + + // Remove from dropdown. + + %popup.clearEntry( %emitter ); + + // Sync up. + + Parent::redo( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ActionDeleteEmitter::undo( %this ) +{ + %emitter = %this.emitter; + + // Re-assign name. + + %emitter.name = %this.emitterName; + + // Remove from unlisted. + + PE_UnlistedEmitters.remove( %emitter ); + + // Resave to file. + + if( %this.emitterFname !$= "" + && %this.emitterFname !$= "tools/particleEditor/particleEmitterEditor.ed.gui" ) + { + PE_EmitterSaver.setDirty( %emitter, %this.emitterFname ); + PE_EmitterSaver.saveDirty(); + } + + // Add it to the dropdown and selet it. + + %popup = PEE_EmitterSelector_Control-->PopUpMenu; + %popup.add( %emitter.getName(), %emitter.getId() ); + %popup.sort(); + %popup.setSelected( %emitter.getId() ); + + // Sync up. + + Parent::undo( %this ); +} + +//============================================================================================= +// ActionUpdateActiveEmitter. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveEmitter::redo( %this ) +{ + %emitter = %this.emitter; + %emitter.setFieldValue( %this.field, %this.newValue ); + + Parent::redo( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveEmitter::undo( %this ) +{ + %emitter = %this.emitter; + %emitter.setFieldValue( %this.field, %this.oldValue ); + + Parent::undo( %this ); +} + +//============================================================================================= +// ActionUpdateActiveEmitterLifeFields. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveEmitterLifeFields::redo( %this ) +{ + %emitter = %this.emitter; + + %emitter.lifetimeMS = %this.newValueLifetimeMS; + %emitter.lifetimeVarianceMS = %this.newValueLifetimeVarianceMS; + + Parent::redo( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveEmitterLifeFields::undo( %this ) +{ + %emitter = %this.emitter; + + %emitter.lifetimeMS = %this.oldValueLifetimeMS; + %emitter.lifetimeVarianceMS = %this.oldValueLifetimeVarianceMS; + + Parent::undo( %this ); +} + +//============================================================================================= +// ActionUpdateActiveEmitterAmountFields. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveEmitterAmountFields::redo( %this ) +{ + %emitter = %this.emitter; + + %emitter.ejectionPeriodMS = %this.newValueEjectionPeriodMS; + %emitter.periodVarianceMS = %this.newValuePeriodVarianceMS; + + Parent::redo( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveEmitterAmountFields::undo( %this ) +{ + %emitter = %this.emitter; + + %emitter.ejectionPeriodMS = %this.oldValueEjectionPeriodMS; + %emitter.periodVarianceMS = %this.oldValuePeriodVarianceMS; + + Parent::undo( %this ); +} + +//============================================================================================= +// ActionUpdateActiveEmitterSpeedFields. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveEmitterSpeedFields::redo( %this ) +{ + %emitter = %this.emitter; + + %emitter.ejectionVelocity = %this.newValueEjectionVelocity; + %emitter.velocityVariance = %this.newValueVelocityVariance; + + Parent::redo( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveEmitterSpeedFields::undo( %this ) +{ + %emitter = %this.emitter; + + %emitter.ejectionVelocity = %this.oldValueEjectionVelocity; + %emitter.velocityVariance = %this.oldValueVelocityVariance; + + Parent::undo( %this ); +} + +//============================================================================================= +// ActionCreateNewParticle. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionCreateNewParticle::redo( %this ) +{ + %particle = %this.particle.getName(); + %particleId = %this.particle.getId(); + %particleIndex = %this.particleIndex; + %emitter = %this.emitter; + + // Remove from unlisted. + + PE_UnlistedParticles.remove( %particleId ); + + // Add it to the dropdown. + + PEP_ParticleSelector.add( %particle, %particleId ); + PEP_ParticleSelector.sort(); + PEP_ParticleSelector.setSelected( %particleId, false ); + + // Add particle to dropdowns in the emitter editor. + + for( %i = 1; %i < 5; %i ++ ) + { + %emitterParticle = "PEE_EmitterParticle" @ %i; + %popup = %emitterParticle-->PopupMenu; + + %popup.add( %particle, %particleId ); + %popup.sort(); + + if( %i == %particleIndex + 1 ) + %popup.setSelected( %particleId ); + } + + // Sync up. + + PE_ParticleEditor.loadNewParticle(); + Parent::redo( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ActionCreateNewParticle::undo( %this ) +{ + %particle = %this.particle.getName(); + %particleId = %this.particle.getId(); + %emitter = %this.emitter; + + // Add to unlisted. + + PE_UnlistedParticles.add( %particleId ); + + // Remove from dropdown. + + PEP_ParticleSelector.clearEntry( %particleId ); + PEP_ParticleSelector.setFirstSelected( false ); + + // Remove from particle dropdowns in emitter editor. + + for( %i = 1; %i < 5; %i ++ ) + { + %emitterParticle = "PEE_EmitterParticle" @ %i; + %popup = %emitterParticle-->PopUpMenu; + + if( %popup.getSelected() == %particleId ) + %popup.setSelected( %this.prevParticle ); + + %popup.clearEntry( %particleId ); + } + + // Sync up. + + PE_ParticleEditor.loadNewParticle(); + Parent::undo( %this ); +} + +//============================================================================================= +// ActionDeleteParticle. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionDeleteParticle::redo( %this ) +{ + %particle = %this.particle.getName(); + %particleId = %this.particle.getId(); + %emitter = %this.emitter; + + // Add to unlisted. + + PE_UnlistedParticles.add( %particleId ); + + // Remove from file. + + if( %particle.getFileName() !$= "" + && %particle.getFilename() !$= "tools/particleEditor/particleParticleEditor.ed.cs" ) + PE_ParticleSaver.removeObjectFromFile( %particleId ); + + // Remove from dropdown. + + PEP_ParticleSelector.clearEntry( %particleId ); + PEP_ParticleSelector.setFirstSelected(); + + // Remove from particle selectors in emitter. + + for( %i = 1; %i < 5; %i ++ ) + { + %emitterParticle = "PEE_EmitterParticle" @ %i; + %popup = %emitterParticle-->PopUpMenu; + + if( %popup.getSelected() == %particleId ) + { + %this.particleIndex = %i - 1; + %popup.setSelected( 0 ); // Select "None". + } + + %popup.clearEntry( %particleId ); + } + + // Sync up. + + PE_ParticleEditor.loadNewParticle(); + Parent::redo( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ActionDeleteParticle::undo( %this ) +{ + %particle = %this.particle.getName(); + %particleId = %this.particle.getId(); + %particleIndex = %this.particleIndex; + %emitter = %this.emitter; + + // Remove from unlisted. + + PE_UnlistedParticles.remove( %particleId ); + + // Resave to file. + + if( %particle.getFilename() !$= "" + && %particle.getFilename() !$= "tools/particleEditor/particleParticleEditor.ed.gui" ) + { + PE_ParticleSaver.setDirty( %particle ); + PE_ParticleSaver.saveDirty(); + } + + // Add to dropdown. + + PEP_ParticleSelector.add( %particle, %particleId ); + PEP_ParticleSelector.sort(); + PEP_ParticleSelector.setSelected( %particleId ); + + // Add particle to dropdowns in the emitter editor. + + for( %i = 1; %i < 5; %i ++ ) + { + %emitterParticle = "PEE_EmitterParticle" @ %i; + %popup = %emitterParticle-->PopUpMenu; + + %popup.add( %particle, %particleId ); + %popup.sort(); + + if( %i == %particleIndex + 1 ) + %popup.setSelected( %particleId ); + } + + // Sync up. + + PE_ParticleEditor.loadNewParticle(); + Parent::undo( %This ); +} + +//============================================================================================= +// ActionUpdateActiveParticle. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveParticle::redo( %this ) +{ + %particle = %this.particle; + %particle.setFieldValue( %this.field, %this.newValue ); + + Parent::redo( %this ); +} + +function ActionUpdateActiveParticle::undo( %this ) +{ + %particle = %this.particle; + %particle.setFieldValue( %this.field, %this.oldValue ); + + Parent::undo( %this ); +} + +//============================================================================================= +// ActionUpdateActiveParticleLifeFields. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveParticleLifeFields::redo( %this ) +{ + %particle = %this.particle; + + %particle.lifetimeMS = %this.newValueLifetimeMS; + %particle.lifetimeVarianceMS = %this.newValueLifetimeVarianceMS; + + Parent::redo( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveParticleLifeFields::undo( %this ) +{ + %particle = %this.particle; + + %particle.lifetimeMS = %this.oldValueLifetimeMS; + %particle.lifetimeVarianceMS = %this.oldValueLifetimeVarianceMS; + + Parent::undo( %this ); +} + +//============================================================================================= +// ActionUpdateActiveParticleSpinFields. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveParticleSpinFields::redo( %this ) +{ + %particle = %this.particle; + + %particle.spinRandomMax = %this.newValueSpinRandomMax; + %particle.spinRandomMin = %this.newValueSpinRandomMin; + + Parent::redo( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveParticleSpinFields::undo( %this ) +{ + %particle = %this.particle; + + %particle.spinRandomMax = %this.oldValueSpinRandomMax; + %particle.spinRandomMin = %this.oldValueSpinRandomMin; + + Parent::undo( %this ); +} diff --git a/Templates/Empty/game/tools/particleEditor/particleEmitterEditor.ed.cs b/Templates/Empty/game/tools/particleEditor/particleEmitterEditor.ed.cs new file mode 100644 index 000000000..710549842 --- /dev/null +++ b/Templates/Empty/game/tools/particleEditor/particleEmitterEditor.ed.cs @@ -0,0 +1,654 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +$PE_EMITTEREDITOR_DEFAULT_FILENAME = "art/shapes/particles/managedParticleEmitterData.cs"; + + +//============================================================================================= +// PE_EmitterEditor. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::guiSync( %this ) +{ + %data = PE_EmitterEditor.currEmitter; + + // Sync up sliders and number boxes. + + if( PE_EmitterEditor-->PEE_infiniteLoop.isStateOn() ) + { + PE_EmitterEditor-->PEE_lifetimeMS_slider.setActive( false ); + PE_EmitterEditor-->PEE_lifetimeMS_textEdit.setActive( false ); + PE_EmitterEditor-->PEE_lifetimeVarianceMS_slider.setActive( false ); + PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.setActive( false ); + } + else + { + PE_EmitterEditor-->PEE_lifetimeMS_slider.setActive( true ); + PE_EmitterEditor-->PEE_lifetimeMS_textEdit.setActive( true ); + PE_EmitterEditor-->PEE_lifetimeVarianceMS_slider.setActive( true ); + PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.setActive( true ); + + PE_EmitterEditor-->PEE_lifetimeMS_slider.setValue( %data.lifetimeMS ); + PE_EmitterEditor-->PEE_lifetimeMS_textEdit.setText( %data.lifetimeMS ); + PE_EmitterEditor-->PEE_lifetimeVarianceMS_slider.setValue( %data.lifetimeVarianceMS ); + PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.setText( %data.lifetimeVarianceMS ); + } + + PE_EmitterEditor-->PEE_ejectionPeriodMS_slider.setValue( %data.ejectionPeriodMS ); + PE_EmitterEditor-->PEE_ejectionPeriodMS_textEdit.setText( %data.ejectionPeriodMS ); + + PE_EmitterEditor-->PEE_periodVarianceMS_slider.setValue( %data.periodVarianceMS ); + PE_EmitterEditor-->PEE_periodVarianceMS_textEdit.setText( %data.periodVarianceMS ); + + PE_EmitterEditor-->PEE_ejectionVelocity_slider.setValue( %data.ejectionVelocity ); + PE_EmitterEditor-->PEE_ejectionVelocity_textEdit.setText( %data.ejectionVelocity ); + + PE_EmitterEditor-->PEE_velocityVariance_slider.setValue( %data.velocityVariance ); + PE_EmitterEditor-->PEE_velocityVariance_textEdit.setText( %data.velocityVariance ); + + PE_EmitterEditor-->PEE_orientParticles.setValue( %data.orientParticles ); + PE_EmitterEditor-->PEE_alignParticles.setValue( %data.alignParticles ); + PE_EmitterEditor-->PEE_alignDirection.setText( %data.alignDirection ); + + PE_EmitterEditor-->PEE_thetaMin_slider.setValue( %data.thetaMin ); + PE_EmitterEditor-->PEE_thetaMin_textEdit.setText( %data.thetaMin ); + + PE_EmitterEditor-->PEE_thetaMax_slider.setValue( %data.thetaMax ); + PE_EmitterEditor-->PEE_thetaMax_textEdit.setText( %data.thetaMax ); + + PE_EmitterEditor-->PEE_phiVariance_slider.setValue( %data.phiVariance ); + PE_EmitterEditor-->PEE_phiVariance_textEdit.setText( %data.phiVariance ); + + PE_EmitterEditor-->PEE_ejectionOffset_slider.setValue( %data.ejectionOffset ); + PE_EmitterEditor-->PEE_ejectionOffset_textEdit.setText( %data.ejectionOffset ); + + %blendTypeId = PE_EmitterEditor-->PEE_blendType.findText( %data.blendStyle ); + PE_EmitterEditor-->PEE_blendType.setSelected( %blendTypeId, false ); + + PE_EmitterEditor-->PEE_softnessDistance_slider.setValue( %data.softnessDistance ); + PE_EmitterEditor-->PEE_softnessDistance_textEdit.setText( %data.softnessDistance ); + + PE_EmitterEditor-->PEE_ambientFactor_slider.setValue( %data.ambientFactor ); + PE_EmitterEditor-->PEE_ambientFactor_textEdit.setText( %data.ambientFactor ); + + PE_EmitterEditor-->PEE_softParticles.setValue( %data.softParticles ); + PE_EmitterEditor-->PEE_reverseOrder.setValue( %data.reverseOrder ); + PE_EmitterEditor-->PEE_useEmitterSizes.setValue( %data.useEmitterSizes ); + PE_EmitterEditor-->PEE_useEmitterColors.setValue( %data.useEmitterColors ); + + // Sync up particle selectors. + + for( %index = 0; %index < 4; %index ++ ) + { + %ctrl = "PEE_EmitterParticle" @ ( %index + 1 ); + %popup = %ctrl-->PopUpMenu; + + %particle = getWord( %data.particles, %index ); + if( isObject( %particle ) ) + %popup.setSelected( %particle.getId(), false ); + else + %popup.setSelected( 0, false ); // Select "None". + } +} + +//--------------------------------------------------------------------------------------------- + +// Generic updateEmitter method +function PE_EmitterEditor::updateEmitter( %this, %propertyField, %value, %isSlider, %onMouseUp ) +{ + PE_EmitterEditor.setEmitterDirty(); + + %emitter = PE_EmitterEditor.currEmitter; + + %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1); + if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) ) + { + %last.field = %propertyField; + %last.isSlider = %isSlider; + %last.onMouseUp = %onMouseUp; + %last.newValue = %value; + } + else + { + %action = ParticleEditor.createUndo(ActionUpdateActiveEmitter, "Update Active Emitter"); + %action.emitter = %emitter; + %action.field = %propertyField; + %action.isSlider = %isSlider; + %action.onMouseUp = %onMouseUp; + %action.newValue = %value; + %action.oldValue = %emitter.getFieldValue( %propertyField ); + + ParticleEditor.submitUndo( %action ); + } + + %emitter.setFieldValue( %propertyField, %value ); + %emitter.reload(); +} + +//--------------------------------------------------------------------------------------------- + +// Special case updateEmitter methods +function PE_EmitterEditor::updateLifeFields( %this, %isRandom, %value, %isSlider, %onMouseUp ) +{ + PE_EmitterEditor.setEmitterDirty(); + + %emitter = PE_EmitterEditor.currEmitter; + + // Transfer values over to gui controls. + + if( %isRandom ) + { + if( %value > 0 ) + %value++; + + if( %value > PE_EmitterEditor-->PEE_lifetimeMS_slider.getValue() ) + { + PE_EmitterEditor-->PEE_lifetimeMS_textEdit.setText( %value ); + PE_EmitterEditor-->PEE_lifetimeMS_slider.setValue( %value ); + } + } + else + { + if( %value > 0 ) + %value --; + + if( %value < PE_EmitterEditor-->PEE_lifetimeVarianceMS_slider.getValue() ) + { + PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.setText( %value ); + PE_EmitterEditor-->PEE_lifetimeVarianceMS_slider.setValue( %value ); + } + } + + // Submit undo. + + %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1); + if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) ) + { + %last.isSlider = %isSlider; + %last.onMouseUp = %onMouseUp; + %last.newValueLifetimeMS = PE_EmitterEditor-->PEE_lifetimeMS_textEdit.getText(); + %last.newValueLifetimeVarianceMS = PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.getText(); + } + else + { + %action = ParticleEditor.createUndo(ActionUpdateActiveEmitterLifeFields, "Update Active Emitter"); + %action.emitter = %emitter; + %action.isSlider = %isSlider; + %action.onMouseUp = %onMouseUp; + + %action.newValueLifetimeMS = PE_EmitterEditor-->PEE_lifetimeMS_textEdit.getText(); + %action.oldValueLifetimeMS = %emitter.lifetimeMS; + + %action.newValueLifetimeVarianceMS = PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.getText(); + %action.oldValueLifetimeVarianceMS = %emitter.lifetimeVarianceMS; + + ParticleEditor.submitUndo( %action ); + } + + // Set the values on the current emitter. + + %emitter.lifetimeMS = PE_EmitterEditor-->PEE_lifetimeMS_textEdit.getText(); + %emitter.lifetimeVarianceMS = PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.getText(); + %emitter.reload(); + + // Keep the infiniteLoop checkbox up to date. + + PE_EmitterEditor-->PEE_infiniteLoop.setStateOn( + %emitter.lifetimeMS == 0 + ); +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::updateLifeFieldsInfiniteLoop( %this ) +{ + %emitter = PE_EmitterEditor.currEmitter; + %isEnabled = PE_EmitterEditor-->PEE_infiniteLoop.isStateOn(); + + // Submit undo. + + %action = ParticleEditor.createUndo( ActionUpdateActiveEmitterLifeFields, "Update Active Emitter" ); + %action.emitter = %emitter; + + if( %isEnabled ) + { + %action.newValueLifetimeMS = 0; + %action.newvalueLifetimeVarianceMS = 0; + %action.oldValueLifetimeMS = PE_EmitterEditor-->PEE_lifetimeMS_textEdit.getText(); + %action.oldValueLifetimeVarianceMS = PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.getText(); + } + else + { + %action.newValueLifetimeMS = PE_EmitterEditor-->PEE_lifetimeMS_textEdit.getText(); + %action.newvalueLifetimeVarianceMS = PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.getText(); + %action.oldValueLifetimeMS = 0; + %action.oldValueLifetimeVarianceMS = 0; + } + + ParticleEditor.submitUndo( %action ); + + // Execute action. + + %action.redo(); +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::updateAmountFields( %this, %isRandom, %value, %isSlider, %onMouseUp ) +{ + PE_EmitterEditor.setEmitterDirty(); + %emitter = PE_EmitterEditor.currEmitter; + + // Transfer values over to gui controls. + + if( %isRandom ) + { + %value ++; + if( %value > PE_EmitterEditor-->PEE_ejectionPeriodMS_slider.getValue() ) + { + PE_EmitterEditor-->PEE_ejectionPeriodMS_textEdit.setText( %value ); + PE_EmitterEditor-->PEE_ejectionPeriodMS_slider.setValue( %value ); + } + } + else + { + %value --; + if( %value < PE_EmitterEditor-->PEE_periodVarianceMS_slider.getValue() ) + { + PE_EmitterEditor-->PEE_periodVarianceMS_textEdit.setText( %value ); + PE_EmitterEditor-->PEE_periodVarianceMS_slider.setValue( %value ); + } + } + + // Submit undo. + + %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1); + if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) ) + { + %last.isSlider = %isSlider; + %last.onMouseUp = %onMouseUp; + %last.newValueEjectionPeriodMS = PE_EmitterEditor-->PEE_ejectionPeriodMS_textEdit.getText(); + %last.newValuePeriodVarianceMS = PE_EmitterEditor-->PEE_periodVarianceMS_textEdit.getText(); + } + else + { + %action = ParticleEditor.createUndo(ActionUpdateActiveEmitterAmountFields, "Update Active Emitter"); + %action.emitter = %emitter; + %action.isSlider = %isSlider; + %action.onMouseUp = %onMouseUp; + + %action.newValueEjectionPeriodMS = PE_EmitterEditor-->PEE_ejectionPeriodMS_textEdit.getText(); + %action.oldValueEjectionPeriodMS = %emitter.ejectionPeriodMS; + + %action.newValuePeriodVarianceMS = PE_EmitterEditor-->PEE_periodVarianceMS_textEdit.getText(); + %action.oldValuePeriodVarianceMS = %emitter.periodVarianceMS; + + ParticleEditor.submitUndo( %action ); + } + + // Set the values on the current emitter. + + %emitter.ejectionPeriodMS = PE_EmitterEditor-->PEE_ejectionPeriodMS_textEdit.getText(); + %emitter.periodVarianceMS = PE_EmitterEditor-->PEE_periodVarianceMS_textEdit.getText(); + %emitter.reload(); +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::updateSpeedFields( %this, %isRandom, %value, %isSlider, %onMouseUp ) +{ + PE_EmitterEditor.setEmitterDirty(); + %emitter = PE_EmitterEditor.currEmitter; + + // Transfer values over to gui controls. + + if( %isRandom ) + { + if( %value > PE_EmitterEditor-->PEE_ejectionVelocity_slider.getValue() ) + { + PE_EmitterEditor-->PEE_ejectionVelocity_textEdit.setText( %value ); + PE_EmitterEditor-->PEE_ejectionVelocity_slider.setValue( %value ); + } + } + else + { + if( %value < PE_EmitterEditor-->PEE_velocityVariance_slider.getValue() ) + { + PE_EmitterEditor-->PEE_velocityVariance_textEdit.setText( %value ); + PE_EmitterEditor-->PEE_velocityVariance_slider.setValue( %value ); + } + } + + // Submit undo. + + %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1); + if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) ) + { + %last.isSlider = %isSlider; + %last.onMouseUp = %onMouseUp; + %last.newValueEjectionVelocity = PE_EmitterEditor-->PEE_ejectionVelocity_textEdit.getText(); + %last.newValueVelocityVariance = PE_EmitterEditor-->PEE_velocityVariance_textEdit.getText(); + } + else + { + %action = ParticleEditor.createUndo(ActionUpdateActiveEmitterSpeedFields, "Update Active Emitter"); + %action.emitter = %emitter; + %action.isSlider = %isSlider; + %action.onMouseUp = %onMouseUp; + + %action.newValueEjectionVelocity = PE_EmitterEditor-->PEE_ejectionVelocity_textEdit.getText(); + %action.oldValueEjectionVelocity = %emitter.ejectionVelocity; + + %action.newValueVelocityVariance = PE_EmitterEditor-->PEE_velocityVariance_textEdit.getText(); + %action.oldValueVelocityVariance = %emitter.velocityVariance; + + ParticleEditor.submitUndo( %action ); + } + + // Set the values on the current emitter. + + %emitter.ejectionVelocity = PE_EmitterEditor-->PEE_ejectionVelocity_textEdit.getText(); + %emitter.velocityVariance = PE_EmitterEditor-->PEE_velocityVariance_textEdit.getText(); + %emitter.reload(); +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::updateParticlesFields( %this ) +{ + %particles = ""; + for( %i = 1; %i < 5; %i ++ ) + { + %emitterParticle = "PEE_EmitterParticle" @ %i; + %popup = %emitterParticle-->PopUpMenu; + %text = %popup.getText(); + + if( %text $= "" || %text $= "None" ) + continue; + + if( %particles $= "" ) + %particles = %text; + else + %particles = %particles SPC %text; + } + + %changedEditParticle = 1; + %currParticle = PE_ParticleEditor.currParticle.getName(); + + foreach$( %particleName in %particles ) + { + if( %particleName $= %currParticle ) + { + %changedEditParticle = 0; + break; + } + } + + // True only if the currently edited particle has not been found and the + // ParticleEditor is dirty. + + if( %changedEditParticle && PE_ParticleEditor.dirty ) + { + MessageBoxYesNoCancel("Save Particle Changes?", + "Do you wish to save the changes made to the <br>current particle before changing the particle?", + "PE_ParticleEditor.saveParticle( " @ PE_ParticleEditor.currParticle.getName() @ " ); PE_EmitterEditor.updateEmitter( \"particles\"," @ %particles @ ");", + "PE_ParticleEditor.saveParticleDialogDontSave( " @ PE_ParticleEditor.currParticle.getName() @ " ); PE_EmitterEditor.updateEmitter( \"particles\"," @ %particles @ ");", + "PE_EmitterEditor.guiSync();" ); + } + else + { + PE_EmitterEditor.updateEmitter( "particles", %particles ); + } +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::onNewEmitter( %this ) +{ + if( isObject( PE_EmitterEditor.currEmitter ) + && PE_EmitterEditor.currEmitter $= PEE_EmitterSelector.getSelected() ) + return; + + //FIXME: disregards particle tab dirty state + + if( PE_EmitterEditor.dirty ) + { + + if( PE_ParticleEditor.dirty ) + { + MessageBoxYesNo("Save Existing Particle?", + "Do you want to save changes to <br><br>" @ PE_ParticleEditor.currParticle.getName(), + "PE_ParticleEditor.saveParticle(" @ PE_ParticleEditor.currParticle @ ");" + ); + } + + %savedEmitter = PE_EmitterEditor.currEmitter; + MessageBoxYesNoCancel("Save Existing Emitter?", + "Do you want to save changes to <br><br>" @ %savedEmitter.getName(), + "PE_EmitterEditor.saveEmitter(" @ %savedEmitter@ "); PE_EmitterEditor.loadNewEmitter();", + "PE_EmitterEditor.saveEmitterDialogDontSave(" @ %savedEmitter @ "); PE_EmitterEditor.loadNewEmitter();" + ); + + + } + else + { + PE_EmitterEditor.loadNewEmitter(); + } +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::loadNewEmitter( %this, %emitter ) +{ + if( isObject( %emitter ) ) + %current = %emitter.getId(); + else + %current = PEE_EmitterSelector.getSelected(); + + PE_EmitterEditor.currEmitter = %current; + PE_EmitterEditor_NotDirtyEmitter.assignFieldsFrom( %current ); + PE_EmitterEditor_NotDirtyEmitter.originalName = %current.name; + + PE_EmitterEditor.guiSync(); + PE_EmitterEditor.setEmitterNotDirty(); + + PE_ParticleEditor.loadNewParticle( getWord( %current.particles, 0 ) ); + + ParticleEditor.updateEmitterNode(); + + PE_EmitterEditor-->PEE_infiniteLoop.setStateOn( %current.lifetimeMS == 0 ); +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::setEmitterDirty( %this ) +{ + PE_EmitterEditor.text = "Emitter *"; + PE_EmitterEditor.dirty = true; + + %emitter = PE_EmitterEditor.currEmitter; + + if( %emitter.getFilename() $= "" || %emitter.getFilename() $= "tools/particleEditor/particleEmitterEditor.ed.cs" ) + PE_EmitterSaver.setDirty( %emitter, $PE_EMITTEREDITOR_DEFAULT_FILENAME ); + else + PE_EmitterSaver.setDirty( %emitter ); +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::setEmitterNotDirty( %this ) +{ + PE_EmitterEditor.text = "Emitter"; + PE_EmitterEditor.dirty = false; + + PE_EmitterSaver.clearAll(); +} + +//--------------------------------------------------------------------------------------------- + +// Create Functionality +function PE_EmitterEditor::showNewDialog( %this ) +{ + //FIXME: disregards particle tab dirty state + + // Open a dialog if the current emitter is dirty. + + if( PE_ParticleEditor.dirty ) + { + MessageBoxYesNo("Save Existing Particle?", + "Do you want to save changes to <br><br>" @ PE_ParticleEditor.currParticle.getName(), + "PE_ParticleEditor.saveParticle(" @ PE_ParticleEditor.currParticle @ ");" + ); + } + + if( PE_EmitterEditor.dirty ) + { + MessageBoxYesNoCancel("Save Emitter Changes?", + "Do you wish to save the changes made to the <br>current emitter before changing the emitter?", + "PE_EmitterEditor.saveEmitter( " @ PE_EmitterEditor.currEmitter.getName() @ " ); PE_EmitterEditor.createEmitter();", + "PE_EmitterEditor.saveEmitterDialogDontSave( " @ PE_EmitterEditor.currEmitter.getName() @ " ); PE_EmitterEditor.createEmitter();" + ); + } + else + { + PE_EmitterEditor.createEmitter(); + } +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::createEmitter( %this ) +{ + // Create a new emitter. + %emitter = getUniqueName( "newEmitter" ); + datablock ParticleEmitterData( %emitter : DefaultEmitter ) + { + }; + + // Submit undo. + + %action = ParticleEditor.createUndo( ActionCreateNewEmitter, "Create New Emitter" ); + %action.prevEmitter = PE_EmitterEditor.currEmitter; + %action.emitter = %emitter.getId(); + %action.emitterName = %emitter; + + ParticleEditor.submitUndo( %action ); + + // Execute action. + + %action.redo(); + + PE_ParticleEditor.createParticle(false); +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::showDeleteDialog( %this ) +{ + if( PE_EmitterEditor.currEmitter.getName() $= "DefaultEmitter" ) + { + MessageBoxOK( "Error", "Cannot delete DefaultEmitter"); + return; + } + + if( isObject( PE_EmitterEditor.currEmitter ) ) + { + MessageBoxYesNoCancel("Delete Emitter?", + "Are you sure you want to delete<br><br>" @ PE_EmitterEditor.currEmitter.getName() @ "<br><br> Emitter deletion won't take affect until the level is exited.", + "PE_EmitterEditor.saveEmitterDialogDontSave( " @ PE_EmitterEditor.currEmitter.getName() @ " ); PE_EmitterEditor.deleteEmitter();" + ); + } +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::deleteEmitter( %this ) +{ + %emitter = PE_EmitterEditor.currEmitter; + + // Create undo. + + %action = ParticleEditor.createUndo( ActionDeleteEmitter, "Delete Emitter" ); + %action.emitter = %emitter; + %action.emitterFname = %emitter.getFilename(); + + ParticleEditor.submitUndo( %action ); + + // Execute action. + + %action.redo(); +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::saveEmitter( %this, %emitter ) +{ + + + if ( %emitter $= "" ) + %newName = PEE_EmitterSelector_Control->TextEdit.getText(); + else + %newName = %emitter.getName(); + + PE_EmitterEditor.currEmitter.setName( %newName ); + PE_EmitterEditor_NotDirtyEmitter.assignFieldsFrom( %emitter ); + PE_EmitterEditor_NotDirtyEmitter.originalName = %newName; + + PE_EmitterSaver.saveDirty(); + + PE_EmitterEditor.currEmitter = %newName.getId(); + PE_EmitterEditor.setEmitterNotDirty(); + + ParticleEditor.createParticleList(); +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::saveEmitterDialogDontSave( %this, %emitter) +{ + %emitter.setName( PE_EmitterEditor_NotDirtyEmitter.originalName ); + %emitter.assignFieldsFrom( PE_EmitterEditor_NotDirtyEmitter ); + PE_EmitterEditor.setEmitterNotDirty(); +} + +//============================================================================================= +// PEE_EmitterSelector_Control. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function PEE_EmitterSelector_Control::onRenameItem( %this ) +{ + Parent::onRenameItem( %this ); + + //FIXME: need to check for validity of name and name clashes + + PE_EmitterEditor.setEmitterDirty(); + + // Resort menu. + + %this-->PopupMenu.sort(); +} diff --git a/Templates/Empty/game/tools/particleEditor/particleParticleEditor.ed.cs b/Templates/Empty/game/tools/particleEditor/particleParticleEditor.ed.cs new file mode 100644 index 000000000..cafd80bf6 --- /dev/null +++ b/Templates/Empty/game/tools/particleEditor/particleParticleEditor.ed.cs @@ -0,0 +1,589 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +$PE_PARTICLEEDITOR_DEFAULT_FILENAME = "art/shapes/particles/managedParticleData.cs"; + + +//============================================================================================= +// PE_ParticleEditor. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::guiSync( %this ) +{ + // Populate the selector with the particles assigned + // to the current emitter. + + %containsCurrParticle = false; + %popup = PEP_ParticleSelector; + %popup.clear(); + + foreach$( %particle in PE_EmitterEditor.currEmitter.particles ) + { + if( %particle.getId() == PE_ParticleEditor.currParticle ) + %containsCurrParticle = true; + + %popup.add( %particle, %particle.getId() ); + } + + // Just in case the particle doesn't exist, fallback gracefully + + if( !%containsCurrParticle ) + PE_ParticleEditor.currParticle = getWord( PE_EmitterEditor.currEmitter.particles, 0 ).getId(); + + %data = PE_ParticleEditor.currParticle; + + %popup.sort(); + %popup.setSelected( %data ); + + %bitmap = MaterialEditorGui.searchForTexture( %data.getName(), %data.textureName ); + if( %bitmap !$= "" ) + { + PE_ParticleEditor-->PEP_previewImage.setBitmap( %bitmap ); + PE_ParticleEditor-->PEP_previewImageName.setText( %bitmap ); + PE_ParticleEditor-->PEP_previewImageName.tooltip = %bitmap; + } + else + { + PE_ParticleEditor-->PEP_previewImage.setBitmap( "" ); + PE_ParticleEditor-->PEP_previewImageName.setText( "None" ); + PE_ParticleEditor-->PEP_previewImageName.tooltip = "None"; + } + + PE_ParticleEditor-->PEP_inverseAlpha.setValue( %data.useInvAlpha ); + + PE_ParticleEditor-->PEP_lifetimeMS_slider.setValue( %data.lifetimeMS ); + PE_ParticleEditor-->PEP_lifetimeMS_textEdit.setText( %data.lifetimeMS ); + + PE_ParticleEditor-->PEP_lifetimeVarianceMS_slider.setValue( %data.lifetimeVarianceMS ); + PE_ParticleEditor-->PEP_lifetimeVarianceMS_textEdit.setText( %data.lifetimeVarianceMS ); + + PE_ParticleEditor-->PEP_inheritedVelFactor_slider.setValue( %data.inheritedVelFactor ); + PE_ParticleEditor-->PEP_inheritedVelFactor_textEdit.setText( %data.inheritedVelFactor ); + + PE_ParticleEditor-->PEP_constantAcceleration_slider.setValue( %data.constantAcceleration ); + PE_ParticleEditor-->PEP_constantAcceleration_textEdit.setText( %data.constantAcceleration ); + + PE_ParticleEditor-->PEP_gravityCoefficient_slider.setValue( %data.gravityCoefficient ); + PE_ParticleEditor-->PEP_gravityCoefficient_textEdit.setText( %data.gravityCoefficient ); + + PE_ParticleEditor-->PEP_dragCoefficient_slider.setValue( %data.dragCoefficient ); + PE_ParticleEditor-->PEP_dragCoefficient_textEdit.setText( %data.dragCoefficient ); + + PE_ParticleEditor-->PEP_spinRandomMin_slider.setValue( %data.spinRandomMin ); + PE_ParticleEditor-->PEP_spinRandomMin_textEdit.setText( %data.spinRandomMin ); + + PE_ParticleEditor-->PEP_spinRandomMax_slider.setValue( %data.spinRandomMax ); + PE_ParticleEditor-->PEP_spinRandomMax_textEdit.setText( %data.spinRandomMax ); + + PE_ParticleEditor-->PEP_spinRandomMax_slider.setValue( %data.spinRandomMax ); + PE_ParticleEditor-->PEP_spinRandomMax_textEdit.setText( %data.spinRandomMax ); + + PE_ParticleEditor-->PEP_spinSpeed_slider.setValue( %data.spinSpeed ); + PE_ParticleEditor-->PEP_spinSpeed_textEdit.setText( %data.spinSpeed ); + + PE_ColorTintSwatch0.color = %data.colors[ 0 ]; + PE_ColorTintSwatch1.color = %data.colors[ 1 ]; + PE_ColorTintSwatch2.color = %data.colors[ 2 ]; + PE_ColorTintSwatch3.color = %data.colors[ 3 ]; + + PE_ParticleEditor-->PEP_pointSize_slider0.setValue( %data.sizes[ 0 ] ); + PE_ParticleEditor-->PEP_pointSize_textEdit0.setText( %data.sizes[ 0 ] ); + + PE_ParticleEditor-->PEP_pointSize_slider1.setValue( %data.sizes[ 1 ] ); + PE_ParticleEditor-->PEP_pointSize_textEdit1.setText( %data.sizes[ 1 ] ); + + PE_ParticleEditor-->PEP_pointSize_slider2.setValue( %data.sizes[ 2 ] ); + PE_ParticleEditor-->PEP_pointSize_textEdit2.setText( %data.sizes[ 2 ] ); + + PE_ParticleEditor-->PEP_pointSize_slider3.setValue( %data.sizes[ 3 ] ); + PE_ParticleEditor-->PEP_pointSize_textEdit3.setText( %data.sizes[ 3 ] ); + + PE_ParticleEditor-->PEP_pointTime_slider0.setValue( %data.times[ 0 ] ); + PE_ParticleEditor-->PEP_pointTime_textEdit0.setText( %data.times[ 0 ] ); + + PE_ParticleEditor-->PEP_pointTime_slider1.setValue( %data.times[ 1 ] ); + PE_ParticleEditor-->PEP_pointTime_textEdit1.setText( %data.times[ 1 ] ); + + PE_ParticleEditor-->PEP_pointTime_slider2.setValue( %data.times[ 2 ] ); + PE_ParticleEditor-->PEP_pointTime_textEdit2.setText( %data.times[ 2 ] ); + + PE_ParticleEditor-->PEP_pointTime_slider3.setValue( %data.times[ 3 ] ); + PE_ParticleEditor-->PEP_pointTime_textEdit3.setText( %data.times[ 3 ] ); +} + +//--------------------------------------------------------------------------------------------- + +// Generic updateParticle method +function PE_ParticleEditor::updateParticle(%this, %propertyField, %value, %isSlider, %onMouseUp) +{ + PE_ParticleEditor.setParticleDirty(); + %particle = PE_ParticleEditor.currParticle; + + %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1); + if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) ) + { + %last.field = %propertyField; + %last.isSlider = %isSlider; + %last.onMouseUp = %onMouseUp; + %last.newValue = %value; + } + else + { + %action = ParticleEditor.createUndo(ActionUpdateActiveParticle, "Update Active Particle"); + %action.particle = %particle; + %action.field = %propertyField; + %action.isSlider = %isSlider; + %action.onMouseUp = %onMouseUp; + %action.newValue = %value; + %action.oldValue = %particle.getFieldValue( %propertyField ); + + ParticleEditor.submitUndo( %action ); + } + + %particle.setFieldValue( %propertyField, %value ); + %particle.reload(); +} + +//--------------------------------------------------------------------------------------------- + +// Special case updateEmitter methods +function PE_ParticleEditor::updateParticleTexture( %this, %action ) +{ + if( %action ) + { + %texture = MaterialEditorGui.openFile("texture"); + if( %texture !$= "" ) + { + PE_ParticleEditor-->PEP_previewImage.setBitmap(%texture); + PE_ParticleEditor-->PEP_previewImageName.setText(%texture); + PE_ParticleEditor-->PEP_previewImageName.tooltip = %texture; + + PE_ParticleEditor.updateParticle( "textureName", %texture ); + } + } + else + { + PE_ParticleEditor-->PEP_previewImage.setBitmap(""); + PE_ParticleEditor-->PEP_previewImageName.setText(""); + PE_ParticleEditor-->PEP_previewImageName.tooltip = ""; + + PE_ParticleEditor.updateParticle( "textureName", "" ); + } +} + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::updateLifeFields( %this, %isRandom, %value, %isSlider, %onMouseUp ) +{ + PE_ParticleEditor.setParticleDirty(); + %particle = PE_ParticleEditor.currParticle; + + //Transfer values over to gui controls. + + if( %isRandom ) + { + %value ++; + if( %value > PE_ParticleEditor-->PEP_lifetimeMS_slider.getValue() ) + { + PE_ParticleEditor-->PEP_lifetimeMS_textEdit.setText( %value ); + PE_ParticleEditor-->PEP_lifetimeMS_slider.setValue( %value ); + } + } + else + { + %value --; + if( %value < PE_ParticleEditor-->PEP_lifetimeVarianceMS_slider.getValue() ) + { + PE_ParticleEditor-->PEP_lifetimeVarianceMS_textEdit.setText( %value ); + PE_ParticleEditor-->PEP_lifetimeVarianceMS_slider.setValue( %value ); + } + } + + // Submit undo. + + %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1); + if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) ) + { + %last.isSlider = %isSlider; + %last.onMouseUp = %onMouseUp; + %last.newValueLifetimeMS = PE_ParticleEditor-->PEP_lifetimeMS_textEdit.getText(); + %last.newValueLifetimeVarianceMS = PE_ParticleEditor-->PEP_lifetimeVarianceMS_textEdit.getText(); + } + else + { + %action = ParticleEditor.createUndo(ActionUpdateActiveParticleLifeFields, "Update Active Particle"); + %action.particle = %particle; + %action.isSlider = %isSlider; + %action.onMouseUp = %onMouseUp; + + %action.newValueLifetimeMS = PE_ParticleEditor-->PEP_lifetimeMS_textEdit.getText(); + %action.oldValueLifetimeMS = %particle.lifetimeMS; + + %action.newValueLifetimeVarianceMS = PE_ParticleEditor-->PEP_lifetimeVarianceMS_textEdit.getText(); + %action.oldValueLifetimeVarianceMS = %particle.lifetimeVarianceMS; + + ParticleEditor.submitUndo( %action ); + } + + %particle.lifetimeMS = PE_ParticleEditor-->PEP_lifetimeMS_textEdit.getText(); + %particle.lifetimeVarianceMS = PE_ParticleEditor-->PEP_lifetimeVarianceMS_textEdit.getText(); + %particle.reload(); +} + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::updateSpinFields( %this, %isMax, %value, %isSlider, %onMouseUp ) +{ + PE_ParticleEditor.setParticleDirty(); + %particle = PE_ParticleEditor.currParticle; + + // Transfer values over to gui controls. + if( %isMax ) + { + %value ++; + if( %value > PE_ParticleEditor-->PEP_spinRandomMax_slider.getValue() ) + { + PE_ParticleEditor-->PEP_spinRandomMax_textEdit.setText( %value ); + PE_ParticleEditor-->PEP_spinRandomMax_slider.setValue( %value ); + } + } + else + { + %value --; + if( %value < PE_ParticleEditor-->PEP_spinRandomMin_slider.getValue() ) + { + PE_ParticleEditor-->PEP_spinRandomMin_textEdit.setText( %value ); + PE_ParticleEditor-->PEP_spinRandomMin_slider.setValue( %value ); + } + } + + // Submit undo. + + %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1); + if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) ) + { + %last.isSlider = %isSlider; + %last.onMouseUp = %onMouseUp; + %last.newValueSpinRandomMax = PE_ParticleEditor-->PEP_spinRandomMax_textEdit.getText(); + %last.newValueSpinRandomMin = PE_ParticleEditor-->PEP_spinRandomMin_textEdit.getText(); + } + else + { + %action = ParticleEditor.createUndo(ActionUpdateActiveParticleSpinFields, "Update Active Particle"); + %action.particle = %particle; + %action.isSlider = %isSlider; + %action.onMouseUp = %onMouseUp; + + %action.newValueSpinRandomMax = PE_ParticleEditor-->PEP_spinRandomMax_textEdit.getText(); + %action.oldValueSpinRandomMax = %particle.spinRandomMax; + + %action.newValueSpinRandomMin = PE_ParticleEditor-->PEP_spinRandomMin_textEdit.getText(); + %action.oldValueSpinRandomMin = %particle.spinRandomMin; + + ParticleEditor.submitUndo( %action ); + } + + %particle.spinRandomMax = PE_ParticleEditor-->PEP_spinRandomMax_textEdit.getText(); + %particle.spinRandomMin = PE_ParticleEditor-->PEP_spinRandomMin_textEdit.getText(); + + %particle.reload(); +} + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::onNewParticle( %this ) +{ + // Bail if the user selected the same particle. + + %id = PEP_ParticleSelector.getSelected(); + if( %id == PE_ParticleEditor.currParticle ) + return; + + // Load new particle if we're not in a dirty state + if( PE_ParticleEditor.dirty ) + { + MessageBoxYesNoCancel("Save Existing Particle?", + "Do you want to save changes to <br><br>" @ PE_ParticleEditor.currParticle.getName(), + "PE_ParticleEditor.saveParticle(" @ PE_ParticleEditor.currParticle @ ");", + "PE_ParticleEditor.saveParticleDialogDontSave(" @ PE_ParticleEditor.currParticle @ "); PE_ParticleEditor.loadNewParticle();" + ); + } + else + { + PE_ParticleEditor.loadNewParticle(); + } +} + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::loadNewParticle( %this, %particle ) +{ + if( isObject( %particle ) ) + %particle = %particle.getId(); + else + %particle = PEP_ParticleSelector.getSelected(); + + PE_ParticleEditor.currParticle = %particle; + + %particle.reload(); + + PE_ParticleEditor_NotDirtyParticle.assignFieldsFrom( %particle ); + PE_ParticleEditor_NotDirtyParticle.originalName = %particle.getName(); + + PE_ParticleEditor.guiSync(); + PE_ParticleEditor.setParticleNotDirty(); +} + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::setParticleDirty( %this ) +{ + PE_ParticleEditor.text = "Particle *"; + PE_ParticleEditor.dirty = true; + + %particle = PE_ParticleEditor.currParticle; + + if( %particle.getFilename() $= "" || %particle.getFilename() $= "tools/particleEditor/particleParticleEditor.ed.cs" ) + PE_ParticleSaver.setDirty( %particle, $PE_PARTICLEEDITOR_DEFAULT_FILENAME ); + else + PE_ParticleSaver.setDirty( %particle ); +} + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::setParticleNotDirty( %this ) +{ + PE_ParticleEditor.text = "Particle"; + PE_ParticleEditor.dirty = false; + + PE_ParticleSaver.clearAll(); +} + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::showNewDialog( %this, %replaceSlot ) +{ + // Open a dialog if the current Particle is dirty + if( PE_ParticleEditor.dirty ) + { + MessageBoxYesNoCancel("Save Particle Changes?", + "Do you wish to save the changes made to the <br>current particle before changing the particle?", + "PE_ParticleEditor.saveParticle( " @ PE_ParticleEditor.currParticle.getName() @ " ); PE_ParticleEditor.createParticle( " @ %replaceSlot @ " );", + "PE_ParticleEditor.saveParticleDialogDontSave( " @ PE_ParticleEditor.currParticle.getName() @ " ); PE_ParticleEditor.createParticle( " @ %replaceSlot @ " );" + ); + } + else + { + PE_ParticleEditor.createParticle( %replaceSlot ); + } +} + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::createParticle( %this, %replaceSlot ) +{ + // Make sure we have a spare slot on the current emitter. + + if( !%replaceSlot ) + { + %numExistingParticles = getWordCount( PE_EmitterEditor.currEmitter.particles ); + if( %numExistingParticles > 3 ) + { + MessageBoxOK( "Error", "An emitter cannot have more than 4 particles assigned to it." ); + return; + } + + %particleIndex = %numExistingParticles; + } + else + %particleIndex = %replaceSlot - 1; + + // Create the particle datablock and add to the emitter. + + %newParticle = getUniqueName( "newParticle" ); + + datablock ParticleData( %newParticle : DefaultParticle ) + { + }; + + // Submit undo. + + %action = ParticleEditor.createUndo( ActionCreateNewParticle, "Create New Particle" ); + %action.particle = %newParticle.getId(); + %action.particleIndex = %particleIndex; + %action.prevParticle = ( "PEE_EmitterParticleSelector" @ ( %particleIndex + 1 ) ).getSelected(); + %action.emitter = PE_EmitterEditor.currEmitter; + + ParticleEditor.submitUndo( %action ); + + // Execute action. + + %action.redo(); +} + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::showDeleteDialog( %this ) +{ + // Don't allow deleting DefaultParticle. + + if( PE_ParticleEditor.currParticle.getName() $= "DefaultParticle" ) + { + MessageBoxOK( "Error", "Cannot delete DefaultParticle"); + return; + } + + // Check to see if the particle emitter has more than 1 particle on it. + + if( getWordCount( PE_EmitterEditor.currEmitter.particles ) == 1 ) + { + MessageBoxOK( "Error", "At least one particle must remain on the particle emitter."); + return; + } + + // Bring up requester for confirmation. + + if( isObject( PE_ParticleEditor.currParticle ) ) + { + MessageBoxYesNoCancel( "Delete Particle?", + "Are you sure you want to delete<br><br>" @ PE_ParticleEditor.currParticle.getName() @ "<br><br> Particle deletion won't take affect until the engine is quit.", + "PE_ParticleEditor.saveParticleDialogDontSave( " @ PE_ParticleEditor.currParticle.getName() @ " ); PE_ParticleEditor.deleteParticle();", + "", + "" + ); + } +} + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::deleteParticle( %this ) +{ + %particle = PE_ParticleEditor.currParticle; + + // Submit undo. + + %action = ParticleEditor.createUndo( ActionDeleteParticle, "Delete Particle" ); + %action.particle = %particle; + %action.emitter = PE_EmitterEditor.currEmitter; + + ParticleEditor.submitUndo( %action ); + + // Execute action. + + %action.redo(); +} + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::saveParticle( %this, %particle ) +{ + %particle.setName( PEP_ParticleSelector.getText() ); + + PE_ParticleEditor_NotDirtyParticle.assignFieldsFrom( %particle ); + PE_ParticleEditor_NotDirtyParticle.originalName = %particle.getName(); + + PE_ParticleSaver.saveDirty(); + PE_ParticleEditor.setParticleNotDirty(); + + ParticleEditor.createParticleList(); +} + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::saveParticleDialogDontSave( %this, %particle ) +{ + %particle.setName( PE_ParticleEditor_NotDirtyParticle.originalName ); + %particle.assignFieldsFrom( PE_ParticleEditor_NotDirtyParticle ); + + PE_ParticleEditor.setParticleNotDirty(); +} + +//============================================================================================= +// PE_ColorTintSwatch. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function PE_ColorTintSwatch::updateParticleColor( %this, %color ) +{ + %arrayNum = %this.arrayNum; + + %r = getWord( %color, 0 ); + %g = getWord( %color, 1 ); + %b = getWord( %color, 2 ); + %a = getWord( %color, 3 ); + + %color = %r SPC %g SPC %b SPC %a; + %this.color = %color; + + PE_ParticleEditor.updateParticle( "colors[" @ %arrayNum @ "]", %color ); +} + +//============================================================================================= +// PEP_ParticleSelector_Control. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function PEP_ParticleSelector_Control::onRenameItem( %this ) +{ + Parent::onRenameItem( %this ); + + //FIXME: need to check for validity of name and name clashes + + PE_ParticleEditor.setParticleDirty(); + + // Resort menu. + + %this-->PopupMenu.sort(); +} + +//============================================================================================= +// PEP_NewParticleButton. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function PEP_NewParticleButton::onDefaultClick( %this ) +{ + PE_ParticleEditor.showNewDialog(); +} + +//--------------------------------------------------------------------------------------------- + +function PEP_NewParticleButton::onCtrlClick( %this ) +{ + for( %i = 1; %i < 5; %i ++ ) + { + %popup = "PEE_EmitterParticleSelector" @ %i; + if( %popup.getSelected() == PEP_ParticleSelector.getSelected() ) + { + %replaceSlot = %i; + break; + } + } + + PE_ParticleEditor.showNewDialog( %replaceSlot ); +} diff --git a/Templates/Empty/game/tools/physicsTools/main.cs b/Templates/Empty/game/tools/physicsTools/main.cs new file mode 100644 index 000000000..8da40844e --- /dev/null +++ b/Templates/Empty/game/tools/physicsTools/main.cs @@ -0,0 +1,122 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +function physicsToggleSimulation() +{ + %isEnabled = physicsSimulationEnabled(); + if ( %isEnabled ) + { + physicsStateText.setText( "Simulation is paused." ); + physicsStopSimulation( "client" ); + physicsStopSimulation( "server" ); + } + else + { + physicsStateText.setText( "Simulation is unpaused." ); + physicsStartSimulation( "client" ); + physicsStartSimulation( "server" ); + } +} + +function initializePhysicsTools() +{ + echo( " % - Initializing Physics Tools" ); + + if ( !physicsPluginPresent() ) + { + echo( "No physics plugin exists." ); + return; + } + + globalactionmap.bindCmd( keyboard, "alt t", "physicsToggleSimulation();", "" ); + globalactionmap.bindCmd( keyboard, "alt r", "physicsRestoreState();", "" ); + + new ScriptObject( PhysicsEditorPlugin ) + { + superClass = "EditorPlugin"; + editorGui = EWorldEditor; + }; +} + +function destroyPhysicsTools() +{ +} + +function PhysicsEditorPlugin::onWorldEditorStartup( %this ) +{ + new PopupMenu( PhysicsToolsMenu ) + { + superClass = "MenuBuilder"; + //class = "PhysXToolsMenu"; + + barTitle = "Physics"; + + item[0] = "Start Simulation" TAB "Ctrl-Alt P" TAB "physicsStartSimulation( \"client\" );physicsStartSimulation( \"server\" );"; + //item[1] = "Stop Simulation" TAB "" TAB "physicsSetTimeScale( 0 );"; + item[1] = "-"; + item[2] = "Speed 25%" TAB "" TAB "physicsSetTimeScale( 0.25 );"; + item[3] = "Speed 50%" TAB "" TAB "physicsSetTimeScale( 0.5 );"; + item[4] = "Speed 100%" TAB "" TAB "physicsSetTimeScale( 1.0 );"; + item[5] = "-"; + item[6] = "Reload NXBs" TAB "" TAB ""; + }; + + // Add our menu. + EditorGui.menuBar.insert( PhysicsToolsMenu, EditorGui.menuBar.dynamicItemInsertPos ); + + // Add ourselves to the window menu. + //EditorGui.addToWindowMenu( "Road and Path Editor", "", "RoadEditor" ); +} + +function PhysicsToolsMenu::onMenuSelect(%this) +{ + %isEnabled = physicsSimulationEnabled(); + + %itemText = !%isEnabled ? "Start Simulation" : "Pause Simulation"; + %itemCommand = !%isEnabled ? "physicsStartSimulation( \"client\" );physicsStartSimulation( \"server\" );" : "physicsStopSimulation( \"client\" );physicsStopSimulation( \"server\" );"; + + %this.setItemName( 0, %itemText ); + %this.setItemCommand( 0, %itemCommand ); +} + +function PhysicsEditorPlugin::onEditorWake( %this ) +{ + // Disable physics when entering + // the editor. Will be re-enabled + // when the editor is closed. + physicsStopSimulation( "client" ); + physicsStopSimulation( "server" ); + physicsRestoreState(); +} + +function PhysicsEditorPlugin::onEditorSleep( %this ) +{ + physicsStoreState(); + + %currentTimeScale = physicsGetTimeScale(); + if ( %currentTimeScale == 0.0 ) + physicsSetTimeScale( 1.0 ); + + physicsStartSimulation( "client" ); + physicsStartSimulation( "server" ); +} diff --git a/Templates/Empty/game/tools/resources/.gitignore b/Templates/Empty/game/tools/resources/.gitignore new file mode 100644 index 000000000..1bc0e838a --- /dev/null +++ b/Templates/Empty/game/tools/resources/.gitignore @@ -0,0 +1 @@ +# Keep directory in git repo diff --git a/Templates/Empty/game/tools/riverEditor/RiverEditorGui.gui b/Templates/Empty/game/tools/riverEditor/RiverEditorGui.gui new file mode 100644 index 000000000..a0a501e7f --- /dev/null +++ b/Templates/Empty/game/tools/riverEditor/RiverEditorGui.gui @@ -0,0 +1,412 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiRiverEditorCtrl(RiverEditorGui, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "RiverEditorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "None"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + cameraZRot = "0"; + forceFOV = "0"; + renderMissionArea = "0"; + missionAreaFillColor = "255 0 0 20"; + missionAreaFrameColor = "255 0 0 128"; + allowBorderMove = "0"; + borderMovePixelSize = "20"; + borderMoveSpeed = "0.1"; + consoleFrameColor = "255 0 0 255"; + consoleFillColor = "0 0 0 0"; + consoleSphereLevel = "1"; + consoleCircleSegments = "32"; + consoleLineWidth = "1"; + GizmoProfile = "GlobalGizmoProfile"; + DefaultWidth = "10"; + HoverSplineColor = "0 255 0 255"; + SelectedSplineColor = "255 0 255 255"; + HoverNodeColor = "255 255 255 255"; + + new GuiWindowCollapseCtrl(RiverEditorTreeWindow) { + internalName = ""; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) - 1; + Extent = "210 167"; + MinExtent = "210 100"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Rivers"; + + /* + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "LockSelection"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "167 148"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "EWorldEditor.lockSelection(true); EditorTree.toggleLock();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "World Editor"; + hovertime = "1000"; + bitmap = "tools/gui/images/lock"; + buttonType = "ToggleButton"; + groupNum = "-1"; + text = ""; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "DeleteSelection"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "185 148"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "EditorMenuEditDelete();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "World Editor"; + hovertime = "1000"; + bitmap = "tools/gui/images/delete"; + buttonType = "PushButton"; + groupNum = "-1"; + text = ""; + useMouseEvents = "0"; + }; + + */ + new GuiContainer(){ + profile = GuiDefaultProfile; + Position = "5 25"; + Extent = "200 120"; + Docking = "Client"; + Margin = "3 1 3 3 "; + HorizSizing = "width"; + VertSizing = "height"; + isContainer = "1"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "200 118"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiTreeViewCtrl(RiverTreeView) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "193 21"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "0"; + showRoot = "0"; + internalNamesOnly = "0"; + }; + }; + }; + }; + new GuiWindowCollapseCtrl(RiverEditorOptionsWindow) { + internalName = "Window"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) + getWord(RiverEditorTreeWindow.extent, 1) - 2; + Extent = "210 530"; + MinExtent = "210 300"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Properties"; + + new GuiContainer(){ //Node Properties + isContainer = "1"; + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 24"; + Extent = "202 85"; + Docking = "Top"; + Margin = "3 3 3 3"; + + new GuiTextCtrl(){ + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 0"; + Extent = "86 18"; + text = "Node Properties"; + }; + + new GuiTextCtrl(){ + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 21"; + Extent = "46 18"; + text = "Position"; + }; + new GuiTextEditCtrl(){ + internalName = "position"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "57 21"; + Extent = "141 18"; + text = ""; + AltCommand = "RiverEditorGui.editNodeDetails();"; + }; + new GuiTextCtrl(){ + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 42"; + Extent = "46 18"; + text = "Rotation"; + }; + new GuiTextEditCtrl(){ + internalName = "rotation"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "57 42"; + Extent = "141 18"; + text = ""; + AltCommand = "RiverEditorGui.editNodeDetails();"; + }; + new GuiTextCtrl(){ + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 63"; + Extent = "46 18"; + text = "Width"; + }; + new GuiTextEditCtrl(){ + internalName = "width"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "57 63"; + Extent = "52 18"; + text = ""; + AltCommand = "RiverEditorGui.editNodeDetails();"; + }; + new GuiTextCtrl(){ + Profile = "GuiTextRightProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "110 63"; + Extent = "32 18"; + text = "Depth"; + }; + new GuiTextEditCtrl(){ + internalName = "depth"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "146 63"; + Extent = "52 18"; + text = ""; + AltCommand = "RiverEditorGui.editNodeDetails();"; + }; + }; + new GuiContainer(){ //River Properties + isContainer = "1"; + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 112"; + Extent = "202 31"; + Docking = "Top"; + Margin = "0 0 3 3"; + + new GuiTextCtrl(){ + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 0"; + Extent = "121 18"; + text = "River Properties"; + }; + }; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "4 129"; + Extent = "202 357"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "-14 41 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiInspector(RiverInspector) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + name = "RiverInspector"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "1 1"; + Extent = "178 16"; + MinExtent = "16 16"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + dividerMargin = "5"; + }; + }; + new GuiMLTextCtrl(RiverFieldInfoControl) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorFieldInfoMLTextProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "1 485"; + Extent = "202 42"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + }; + }; + +}; + +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/riverEditor/RiverEditorSettingsTab.gui b/Templates/Empty/game/tools/riverEditor/RiverEditorSettingsTab.gui new file mode 100644 index 000000000..767733ec1 --- /dev/null +++ b/Templates/Empty/game/tools/riverEditor/RiverEditorSettingsTab.gui @@ -0,0 +1,517 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(RiverEditorSettingsTab,EditorGuiGroup) { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiTabPageCtrl(ERiverEditorSettingsPage) { + fitBook = "1"; + text = "River Editor"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiSolidDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "208 400"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "208 400"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + extent = "208 210"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Defaults"; + Margin = "0 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Width:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditNumericProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "RiverEditorPlugin.readSettings();"; + editorSettingsValue = "RiverEditor/DefaultWidth"; + editorSettingsWrite = "RiverEditorPlugin.writeSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Depth:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditNumericProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "RiverEditorPlugin.readSettings();"; + editorSettingsValue = "RiverEditor/DefaultDepth"; + editorSettingsWrite = "RiverEditorPlugin.writeSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Normal:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "RiverEditorPlugin.readSettings();"; + editorSettingsValue = "RiverEditor/DefaultNormal"; + editorSettingsWrite = "RiverEditorPlugin.writeSettings();"; + }; + }; + }; + }; + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Colors"; + Margin = "0 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiControl() { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 10"; + Extent = "208 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + className = "ESettingsWindowColor"; + editorSettingsRead = "RiverEditorPlugin.readSettings();"; + editorSettingsValue = "RiverEditor/HoverSplineColor"; + editorSettingsWrite = "RiverEditorPlugin.writeSettings();"; + + new GuiTextCtrl() { + text = "Hover Spline:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "80 0"; + Extent = "104 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + className = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + className = "ESettingsWindowColorButton"; + }; + }; + new GuiControl() { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 30"; + Extent = "208 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + className = "ESettingsWindowColor"; + editorSettingsRead = "RiverEditorPlugin.readSettings();"; + editorSettingsValue = "RiverEditor/SelectedSplineColor"; + editorSettingsWrite = "RiverEditorPlugin.writeSettings();"; + + new GuiTextCtrl() { + text = "Sel. Spline:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "80 0"; + Extent = "104 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + className = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + className = "ESettingsWindowColorButton"; + }; + }; + }; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/riverEditor/RiverEditorToolbar.gui b/Templates/Empty/game/tools/riverEditor/RiverEditorToolbar.gui new file mode 100644 index 000000000..aaaaa09d3 --- /dev/null +++ b/Templates/Empty/game/tools/riverEditor/RiverEditorToolbar.gui @@ -0,0 +1,323 @@ +%guiContent = new GuiControl(RiverEditorToolbar, EditorGuiGroup) { + canSaveDynamicFields = "0"; + internalName = "MeshRoadEditorToolbar"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "306 0"; + Extent = "800 32"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "6 6"; + extent = "100 20"; + minExtent = "8 8"; + visible = "1"; + text = "River Settings"; + maxLength = "255"; + helpTag = "0"; + }; + new GuiDynamicCtrlArrayControl(){ + Position = "83 3"; + extent = "111 32"; + colCount = "31"; + colSize = "29"; + rowCount = "1"; + RowSize = "27"; + rowSpacing = "2"; + colspacing = "4"; + + new GuiBitmapButtonCtrl(RiverEditorShowSplineBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "167 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Variable = "$River::showSpline"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + toolTip = "Show Spline"; + bitmap = "tools/worldEditor/images/road-river/menubar/show-spline"; + groupNum = "7"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiBitmapButtonCtrl(RiverEditorWireframeBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "253 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Variable = "$River::showWireframe"; + Command = "$River::showWireframe = $ThisControl.getValue();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + toolTip = "Show Wireframe"; + bitmap = "tools/worldEditor/images/road-river/menubar/show-wireframe"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiBitmapButtonCtrl(RiverEditorShowRoadBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefalutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "89 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Variable = "$River::showRiver"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + toolTip = "Show River Texture"; + bitmap = "tools/worldEditor/images/road-river/menubar/show-texture"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + }; + new GuiControl(RiverDefaultWidthTextEditContainer) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "197 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 6"; + Extent = "68 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Default Width"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + isContainer = "0"; + profile="GuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "67 2"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "RiverEditorGui.DefaultWidth = $ThisControl.getValue();"; + hovertime = "1000"; + text = "10"; + maxLength = "3"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "101 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(RiverDefaultWidthSliderCtrlContainer);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Changes Default River Width"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "core/art/gui/images/dropslider"; + }; + }; + new GuiControl(RiverDefaultDepthTextEditContainer) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "327 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 6"; + Extent = "68 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Default Depth"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + isContainer = "0"; + profile="GuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "67 2"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "RiverEditorGui.DefaultDepth = $ThisControl.getValue();"; + hovertime = "1000"; + text = "10"; + maxLength = "3"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "101 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(RiverDefaultDepthSliderCtrlContainer);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Changes Default River Depth"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "core/art/gui/images/dropslider"; + }; + }; +}; +new GuiMouseEventCtrl(RiverDefaultWidthSliderCtrlContainer, EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "GuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(RiverDefaultWidthTextEditContainer.position) + firstWord(RiverEditorToolbar.position) + 10 SPC + (getWord(RiverDefaultWidthTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "RiverDefaultWidthTextEditContainer-->textEdit.setText( mFloatLength($ThisControl.getValue(), 2)); RiverEditorGui.DefaultWidth = $ThisControl.getValue();"; + range = "0 100"; + ticks = "0"; + value = "10"; + }; +}; +new GuiMouseEventCtrl(RiverDefaultDepthSliderCtrlContainer, EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "GuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(RiverDefaultDepthTextEditContainer.position) + firstWord(RiverEditorToolbar.position) + 10 SPC + (getWord(RiverDefaultDepthTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "RiverDefaultDepthTextEditContainer-->textEdit.setValue( mFloatLength($ThisControl.getValue(), 2)); RiverEditorGui.DefaultWidth = $ThisControl.getValue();"; + range = "0 100"; + ticks = "0"; + value = "10"; + }; +}; \ No newline at end of file diff --git a/Templates/Empty/game/tools/riverEditor/main.cs b/Templates/Empty/game/tools/riverEditor/main.cs new file mode 100644 index 000000000..b51bd5273 --- /dev/null +++ b/Templates/Empty/game/tools/riverEditor/main.cs @@ -0,0 +1,230 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function initializeRiverEditor() +{ + echo(" % - Initializing River Editor"); + + exec( "./riverEditor.cs" ); + exec( "./riverEditorGui.gui" ); + exec( "./riverEditorToolbar.gui" ); + exec( "./riverEditorGui.cs" ); + + // Add ourselves to EditorGui, where all the other tools reside + RiverEditorGui.setVisible( false ); + RiverEditorToolbar.setVisible(false); + RiverEditorOptionsWindow.setVisible( false ); + RiverEditorTreeWindow.setVisible( false ); + + EditorGui.add( RiverEditorGui ); + EditorGui.add( RiverEditorToolbar ); + EditorGui.add( RiverEditorOptionsWindow ); + EditorGui.add( RiverEditorTreeWindow ); + + new ScriptObject( RiverEditorPlugin ) + { + superClass = "EditorPlugin"; + editorGui = RiverEditorGui; + }; + + %map = new ActionMap(); + %map.bindCmd( keyboard, "backspace", "RiverEditorGui.deleteNode();", "" ); + %map.bindCmd( keyboard, "1", "RiverEditorGui.prepSelectionMode();", "" ); + %map.bindCmd( keyboard, "2", "ToolsPaletteArray->RiverEditorMoveMode.performClick();", "" ); + %map.bindCmd( keyboard, "3", "ToolsPaletteArray->RiverEditorRotateMode.performClick();", "" ); + %map.bindCmd( keyboard, "4", "ToolsPaletteArray->RiverEditorScaleMode.performClick();", "" ); + %map.bindCmd( keyboard, "5", "ToolsPaletteArray->RiverEditorAddRiverMode.performClick();", "" ); + %map.bindCmd( keyboard, "=", "ToolsPaletteArray->RiverEditorInsertPointMode.performClick();", "" ); + %map.bindCmd( keyboard, "numpadadd", "ToolsPaletteArray->RiverEditorInsertPointMode.performClick();", "" ); + %map.bindCmd( keyboard, "-", "ToolsPaletteArray->RiverEditorRemovePointMode.performClick();", "" ); + %map.bindCmd( keyboard, "numpadminus", "ToolsPaletteArray->RiverEditorRemovePointMode.performClick();", "" ); + %map.bindCmd( keyboard, "z", "RiverEditorShowSplineBtn.performClick();", "" ); + %map.bindCmd( keyboard, "x", "RiverEditorWireframeBtn.performClick();", "" ); + %map.bindCmd( keyboard, "v", "RiverEditorShowRoadBtn.performClick();", "" ); + RiverEditorPlugin.map = %map; + + RiverEditorPlugin.initSettings(); +} + +function destroyRiverEditor() +{ +} + +function RiverEditorPlugin::onWorldEditorStartup( %this ) +{ + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "River Editor", "", RiverEditorPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "River Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "RiverEditorPlugin", "RiverEditorPalette", expandFilename("tools/worldEditor/images/toolbar/river-editor"), %tooltip ); + + //connect editor windows + GuiWindowCtrl::attach( RiverEditorOptionsWindow, RiverEditorTreeWindow); + + // Add ourselves to the Editor Settings window + exec( "./RiverEditorSettingsTab.gui" ); + ESettingsWindow.addTabPage( ERiverEditorSettingsPage ); +} + +function RiverEditorPlugin::onActivated( %this ) +{ + %this.readSettings(); + + $River::EditorOpen = true; + + ToolsPaletteArray->RiverEditorAddRiverMode.performClick(); + EditorGui.bringToFront( RiverEditorGui ); + + RiverEditorGui.setVisible(true); + RiverEditorGui.makeFirstResponder( true ); + RiverEditorToolbar.setVisible(true); + + RiverEditorOptionsWindow.setVisible( true ); + RiverEditorTreeWindow.setVisible( true ); + + RiverTreeView.open(ServerRiverSet,true); + %this.map.push(); + + // Store this on a dynamic field + // in order to restore whatever setting + // the user had before. + %this.prevGizmoAlignment = GlobalGizmoProfile.alignment; + + // The DecalEditor always uses Object alignment. + GlobalGizmoProfile.alignment = "Object"; + + // Set the status bar here until all tool have been hooked up + EditorGuiStatusBar.setInfo("River editor."); + EditorGuiStatusBar.setSelection(""); + + // Allow the Gui to setup. + RiverEditorGui.onEditorActivated(); + + Parent::onActivated(%this); +} + +function RiverEditorPlugin::onDeactivated( %this ) +{ + %this.writeSettings(); + + $River::EditorOpen = false; + + RiverEditorGui.setVisible(false); + RiverEditorToolbar.setVisible(false); + RiverEditorOptionsWindow.setVisible( false ); + RiverEditorTreeWindow.setVisible( false ); + %this.map.pop(); + + // Restore the previous Gizmo + // alignment settings. + GlobalGizmoProfile.alignment = %this.prevGizmoAlignment; + + // Allow the Gui to cleanup. + RiverEditorGui.onEditorDeactivated(); + + Parent::onDeactivated(%this); +} + +function RiverEditorPlugin::onEditMenuSelect( %this, %editMenu ) +{ + %hasSelection = false; + + if( isObject( RiverEditorGui.river ) ) + %hasSelection = true; + + %editMenu.enableItem( 3, false ); // Cut + %editMenu.enableItem( 4, false ); // Copy + %editMenu.enableItem( 5, false ); // Paste + %editMenu.enableItem( 6, %hasSelection ); // Delete + %editMenu.enableItem( 8, false ); // Deselect +} + +function RiverEditorPlugin::handleDelete( %this ) +{ + RiverEditorGui.deleteNode(); +} + +function RiverEditorPlugin::handleEscape( %this ) +{ + return RiverEditorGui.onEscapePressed(); +} + +function RiverEditorPlugin::isDirty( %this ) +{ + return RiverEditorGui.isDirty; +} + +function RiverEditorPlugin::onSaveMission( %this, %missionFile ) +{ + if( RiverEditorGui.isDirty ) + { + MissionGroup.save( %missionFile ); + RiverEditorGui.isDirty = false; + } +} + +//----------------------------------------------------------------------------- +// Settings +//----------------------------------------------------------------------------- + +function RiverEditorPlugin::initSettings( %this ) +{ + EditorSettings.beginGroup( "RiverEditor", true ); + + EditorSettings.setDefaultValue( "DefaultWidth", "10" ); + EditorSettings.setDefaultValue( "DefaultDepth", "5" ); + EditorSettings.setDefaultValue( "DefaultNormal", "0 0 1" ); + EditorSettings.setDefaultValue( "HoverSplineColor", "255 0 0 255" ); + EditorSettings.setDefaultValue( "SelectedSplineColor", "0 255 0 255" ); + EditorSettings.setDefaultValue( "HoverNodeColor", "255 255 255 255" ); //<-- Not currently used + + EditorSettings.endGroup(); +} + +function RiverEditorPlugin::readSettings( %this ) +{ + EditorSettings.beginGroup( "RiverEditor", true ); + + RiverEditorGui.DefaultWidth = EditorSettings.value("DefaultWidth"); + RiverEditorGui.DefaultDepth = EditorSettings.value("DefaultDepth"); + RiverEditorGui.DefaultNormal = EditorSettings.value("DefaultNormal"); + RiverEditorGui.HoverSplineColor = EditorSettings.value("HoverSplineColor"); + RiverEditorGui.SelectedSplineColor = EditorSettings.value("SelectedSplineColor"); + RiverEditorGui.HoverNodeColor = EditorSettings.value("HoverNodeColor"); + + EditorSettings.endGroup(); +} + +function RiverEditorPlugin::writeSettings( %this ) +{ + EditorSettings.beginGroup( "RiverEditor", true ); + + EditorSettings.setValue( "DefaultWidth", RiverEditorGui.DefaultWidth ); + EditorSettings.setValue( "DefaultDepth", RiverEditorGui.DefaultDepth ); + EditorSettings.setValue( "DefaultNormal", RiverEditorGui.DefaultNormal ); + EditorSettings.setValue( "HoverSplineColor", RiverEditorGui.HoverSplineColor ); + EditorSettings.setValue( "SelectedSplineColor", RiverEditorGui.SelectedSplineColor ); + EditorSettings.setValue( "HoverNodeColor", RiverEditorGui.HoverNodeColor ); + + EditorSettings.endGroup(); +} diff --git a/Templates/Empty/game/tools/riverEditor/riverEditor.cs b/Templates/Empty/game/tools/riverEditor/riverEditor.cs new file mode 100644 index 000000000..83da8b85c --- /dev/null +++ b/Templates/Empty/game/tools/riverEditor/riverEditor.cs @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +singleton GuiControlProfile( RiverEditorProfile ) +{ + canKeyFocus = true; + opaque = true; + fillColor = "192 192 192 192"; + category = "Editor"; +}; + +singleton GuiControlProfile (GuiSimpleBorderProfile) +{ + opaque = false; + border = 1; + category = "Editor"; +}; + \ No newline at end of file diff --git a/Templates/Empty/game/tools/riverEditor/riverEditorGui.cs b/Templates/Empty/game/tools/riverEditor/riverEditorGui.cs new file mode 100644 index 000000000..162ad46ee --- /dev/null +++ b/Templates/Empty/game/tools/riverEditor/riverEditorGui.cs @@ -0,0 +1,262 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +$River::EditorOpen = false; +$River::wireframe = true; +$River::showSpline = true; +$River::showRiver = true; +$River::showWalls = true; + +function RiverEditorGui::onEditorActivated( %this ) +{ + %count = EWorldEditor.getSelectionSize(); + for ( %i = 0; %i < %count; %i++ ) + { + %obj = EWorldEditor.getSelectedObject(%i); + if ( %obj.getClassName() !$= "River" ) + EWorldEditor.unselectObject( %obj ); + else + %this.setSelectedRiver( %obj ); + } + + %this.onRiverSelected( %this.getSelectedRiver() ); + %this.onNodeSelected(-1); +} + +function RiverEditorGui::onEditorDeactivated( %this ) +{ +} + +function RiverEditorGui::createRiver( %this ) +{ + %river = new River() + { + rippleDir[0] = "0.000000 1.000000"; + rippleDir[1] = "0.707000 0.707000"; + rippleDir[2] = "0.500000 0.860000"; + + rippleSpeed[0] = "-0.065"; + rippleSpeed[1] = "0.09"; + rippleSpeed[2] = "0.04"; + + rippleTexScale[0] = "7.140000 7.140000"; + rippleTexScale[1] = "6.250000 12.500000"; + rippleTexScale[2] = "50.000000 50.000000"; + + waveDir[0] = "0.000000 1.000000"; + waveDir[1] = "0.707000 0.707000"; + waveDir[2] = "0.500000 0.860000"; + + waveSpeed[0] = "1"; + waveSpeed[1] = "1"; + waveSpeed[2] = "1"; + + waveMagnitude[0] = "0.2"; + waveMagnitude[1] = "0.2"; + waveMagnitude[2] = "0.2"; + + baseColor = "45 108 171 255"; + + rippleTex = "core/art/water/ripple.dds"; + foamTex = "core/art/water/foam"; + cubemap = "DefaultSkyCubemap"; + depthGradientTex = "core/art/water/depthcolor_ramp"; + }; + + return %river; +} + +function RiverEditorGui::paletteSync( %this, %mode ) +{ + %evalShortcut = "ToolsPaletteArray-->" @ %mode @ ".setStateOn(1);"; + eval(%evalShortcut); +} + +function RiverEditorGui::onEscapePressed( %this ) +{ + if( %this.getMode() $= "RiverEditorAddNodeMode" ) + { + %this.prepSelectionMode(); + return true; + } + return false; +} + +function RiverEditorGui::onRiverSelected( %this, %river ) +{ + %this.river = %river; + RiverInspector.inspect( %river ); + RiverTreeView.buildVisibleTree(true); + if( RiverTreeView.getSelectedObject() != %river ) + { + RiverTreeView.clearSelection(); + %treeId = RiverTreeView.findItemByObjectId( %river ); + RiverTreeView.selectItem( %treeId ); + } +} + +function RiverEditorGui::onNodeSelected( %this, %nodeIdx ) +{ + if ( %nodeIdx == -1 ) + { + RiverEditorOptionsWindow-->position.setActive( false ); + RiverEditorOptionsWindow-->position.setValue( "" ); + + RiverEditorOptionsWindow-->rotation.setActive( false ); + RiverEditorOptionsWindow-->rotation.setValue( "" ); + + RiverEditorOptionsWindow-->width.setActive( false ); + RiverEditorOptionsWindow-->width.setValue( "" ); + + RiverEditorOptionsWindow-->depth.setActive( false ); + RiverEditorOptionsWindow-->depth.setValue( "" ); + } + else + { + RiverEditorOptionsWindow-->position.setActive( true ); + RiverEditorOptionsWindow-->position.setValue( %this.getNodePosition() ); + + RiverEditorOptionsWindow-->rotation.setActive( true ); + RiverEditorOptionsWindow-->rotation.setValue( %this.getNodeNormal() ); + + RiverEditorOptionsWindow-->width.setActive( true ); + RiverEditorOptionsWindow-->width.setValue( %this.getNodeWidth() ); + + RiverEditorOptionsWindow-->depth.setActive( true ); + RiverEditorOptionsWindow-->depth.setValue( %this.getNodeDepth() ); + } +} + +function RiverEditorGui::onNodeModified( %this, %nodeIdx ) +{ + RiverEditorOptionsWindow-->position.setValue( %this.getNodePosition() ); + RiverEditorOptionsWindow-->rotation.setValue( %this.getNodeNormal() ); + RiverEditorOptionsWindow-->width.setValue( %this.getNodeWidth() ); + RiverEditorOptionsWindow-->depth.setValue( %this.getNodeDepth() ); +} + +function RiverEditorGui::editNodeDetails( %this ) +{ + + %this.setNodePosition( RiverEditorOptionsWindow-->position.getText() ); + %this.setNodeNormal( RiverEditorOptionsWindow-->rotation.getText() ); + %this.setNodeWidth( RiverEditorOptionsWindow-->width.getText() ); + %this.setNodeDepth( RiverEditorOptionsWindow-->depth.getText() ); +} + +function RiverInspector::inspect( %this, %obj ) +{ + %name = ""; + if ( isObject( %obj ) ) + %name = %obj.getName(); + else + RiverFieldInfoControl.setText( "" ); + + //RiverInspectorNameEdit.setValue( %name ); + Parent::inspect( %this, %obj ); +} + +function RiverInspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ) +{ + // Same work to do as for the regular WorldEditor Inspector. + Inspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ); +} + +function RiverInspector::onFieldSelected( %this, %fieldName, %fieldTypeStr, %fieldDoc ) +{ + RiverFieldInfoControl.setText( "<font:ArialBold:14>" @ %fieldName @ "<font:ArialItalic:14> (" @ %fieldTypeStr @ ") " NL "<font:Arial:14>" @ %fieldDoc ); +} + +function RiverTreeView::onInspect(%this, %obj) +{ + RiverInspector.inspect(%obj); +} + +function RiverTreeView::onSelect(%this, %obj) +{ + RiverEditorGui.road = %obj; + RiverInspector.inspect( %obj ); + if(%obj != RiverEditorGui.getSelectedRiver()) + { + RiverEditorGui.setSelectedRiver( %obj ); + } +} + +function RiverEditorGui::prepSelectionMode( %this ) +{ + %mode = %this.getMode(); + + if ( %mode $= "RiverEditorAddNodeMode" ) + { + if ( isObject( %this.getSelectedRiver() ) ) + %this.deleteNode(); + } + + %this.setMode( "RiverEditorSelectMode" ); + ToolsPaletteArray-->RiverEditorSelectMode.setStateOn(1); +} + +//------------------------------------------------------------------------------ +function ERiverEditorSelectModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function ERiverEditorAddModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function ERiverEditorMoveModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function ERiverEditorRotateModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function ERiverEditorScaleModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function ERiverEditorInsertModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function ERiverEditorRemoveModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function RiverDefaultWidthSliderCtrlContainer::onWake(%this) +{ + RiverDefaultWidthSliderCtrlContainer-->slider.setValue(RiverDefaultWidthTextEditContainer-->textEdit.getText()); +} + +function RiverDefaultDepthSliderCtrlContainer::onWake(%this) +{ + RiverDefaultDepthSliderCtrlContainer-->slider.setValue(RiverDefaultDepthTextEditContainer-->textEdit.getText()); +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/roadEditor/RoadEditorGui.gui b/Templates/Empty/game/tools/roadEditor/RoadEditorGui.gui new file mode 100644 index 000000000..e97bb7132 --- /dev/null +++ b/Templates/Empty/game/tools/roadEditor/RoadEditorGui.gui @@ -0,0 +1,386 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiRoadEditorCtrl(RoadEditorGui) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "RoadEditorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "None"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + cameraZRot = "0"; + forceFOV = "0"; + renderMissionArea = "0"; + missionAreaFillColor = "255 0 0 20"; + missionAreaFrameColor = "255 0 0 128"; + allowBorderMove = "0"; + borderMovePixelSize = "20"; + borderMoveSpeed = "0.1"; + consoleFrameColor = "255 0 0 255"; + consoleFillColor = "0 0 0 0"; + consoleSphereLevel = "1"; + consoleCircleSegments = "32"; + consoleLineWidth = "1"; + GizmoProfile = "GlobalGizmoProfile"; + DefaultWidth = "10"; + HoverSplineColor = "0 255 0 255"; + SelectedSplineColor = "255 0 255 255"; + HoverNodeColor = "255 255 255 255"; + + new GuiWindowCollapseCtrl(RoadEditorTreeWindow) { + internalName = ""; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) - 1; + Extent = "210 167"; + MinExtent = "210 100"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Roads & Paths"; + + /* + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "LockSelection"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "167 148"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "EWorldEditor.lockSelection(true); EditorTree.toggleLock();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "World Editor"; + hovertime = "1000"; + bitmap = "tools/gui/images/lock"; + buttonType = "ToggleButton"; + groupNum = "-1"; + text = ""; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "DeleteSelection"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "185 148"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "EditorMenuEditDelete();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "World Editor"; + hovertime = "1000"; + bitmap = "tools/gui/images/delete"; + buttonType = "PushButton"; + groupNum = "-1"; + text = ""; + useMouseEvents = "0"; + }; + */ + new GuiContainer(){ + profile = GuiDefaultProfile; + Position = "5 25"; + Extent = "200 120"; + Docking = "Client"; + Margin = "3 1 3 3 "; + HorizSizing = "width"; + VertSizing = "height"; + isContainer = "1"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "200 118"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiTreeViewCtrl(RoadTreeView) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "193 21"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "0"; + showRoot = "0"; + internalNamesOnly = "0"; + }; + }; + }; + }; + new GuiWindowCollapseCtrl(RoadEditorOptionsWindow) { + internalName = "Window"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 SPC + getWord(EditorGuiToolbar.extent, 1) + getWord(RoadEditorTreeWindow.extent, 1) - 2; + Extent = "210 530"; + MinExtent = "210 298"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Properties"; + + new GuiContainer(RoadEditorProperties){ //Node Properties + isContainer = "1"; + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 24"; + Extent = "202 64"; + Docking = "Top"; + Margin = "3 3 3 3"; + + new GuiTextCtrl(){ + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 0"; + Extent = "86 18"; + text = "Node Properties"; + }; + + new GuiTextCtrl(){ + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 21"; + Extent = "46 18"; + text = "Position"; + }; + new GuiTextEditCtrl(){ + internalName = "position"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "57 21"; + Extent = "141 18"; + text = ""; + AltCommand = "RoadEditorGui.editNodeDetails();"; + }; + new GuiTextCtrl(){ + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 42"; + Extent = "46 18"; + text = "Width"; + }; + new GuiTextEditCtrl(){ + internalName = "width"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "57 42"; + Extent = "141 18"; + text = ""; + AltCommand = "RoadEditorGui.editNodeDetails();"; + }; + }; + new GuiContainer(){ //Decal Road Properties + isContainer = "1"; + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 91"; + Extent = "202 31"; + Docking = "Top"; + Margin = "0 0 3 3"; + + new GuiTextCtrl(){ + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 0"; + Extent = "121 18"; + text = "Decal Road Properties"; + }; + }; + + new GuiContainer(){ + profile = GuiDefaultProfile; + Position = "4 108"; + Extent = "202 377"; + HorizSizing = "width"; + VertSizing = "height"; + isContainer = "1"; + Docking = "Client"; + Margin = "-14 41 3 3"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 377"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiInspector(RoadInspector) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "200 196"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + dividerMargin = "5"; + groupFilters = "+SimBase,+DecalRoad"; + }; + }; + }; + new GuiMLTextCtrl(RoadFieldInfoControl) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorFieldInfoMLTextProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "1 485"; + Extent = "202 42"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + }; + }; + +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/roadEditor/RoadEditorSettingsTab.gui b/Templates/Empty/game/tools/roadEditor/RoadEditorSettingsTab.gui new file mode 100644 index 000000000..a31d49aac --- /dev/null +++ b/Templates/Empty/game/tools/roadEditor/RoadEditorSettingsTab.gui @@ -0,0 +1,457 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(RoadEditorSettingsTab,EditorGuiGroup) { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiTabPageCtrl(ERoadEditorSettingsPage) { + fitBook = "1"; + text = "Road Editor"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiSolidDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "208 400"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "208 400"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + extent = "208 210"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Defaults"; + Margin = "0 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Width:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditNumericProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "RoadEditorPlugin.readSettings();"; + editorSettingsValue = "RoadEditor/DefaultWidth"; + editorSettingsWrite = "RoadEditorPlugin.writeSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Material:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "RoadEditorPlugin.readSettings();"; + editorSettingsValue = "RoadEditor/MaterialName"; + editorSettingsWrite = "RoadEditorPlugin.writeSettings();"; + }; + }; + }; + }; + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Colors"; + Margin = "0 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiControl() { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 10"; + Extent = "208 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + className = "ESettingsWindowColor"; + editorSettingsRead = "RoadEditorPlugin.readSettings();"; + editorSettingsValue = "RoadEditor/HoverSplineColor"; + editorSettingsWrite = "RoadEditorPlugin.writeSettings();"; + + new GuiTextCtrl() { + text = "Hover Spline:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "80 0"; + Extent = "104 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + className = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + className = "ESettingsWindowColorButton"; + }; + }; + new GuiControl() { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 30"; + Extent = "208 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + className = "ESettingsWindowColor"; + editorSettingsRead = "RoadEditorPlugin.readSettings();"; + editorSettingsValue = "RoadEditor/SelectedSplineColor"; + editorSettingsWrite = "RoadEditorPlugin.writeSettings();"; + + new GuiTextCtrl() { + text = "Sel. Spline:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "80 0"; + Extent = "104 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + className = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + className = "ESettingsWindowColorButton"; + }; + }; + }; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/roadEditor/RoadEditorToolbar.gui b/Templates/Empty/game/tools/roadEditor/RoadEditorToolbar.gui new file mode 100644 index 000000000..bf00f626d --- /dev/null +++ b/Templates/Empty/game/tools/roadEditor/RoadEditorToolbar.gui @@ -0,0 +1,273 @@ +%guiContent = new GuiControl(RoadEditorToolbar) { + canSaveDynamicFields = "0"; + internalName = "RoadEditorToolbar"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "306 0"; + Extent = "800 32"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "6 6"; + extent = "70 20"; + minExtent = "8 8"; + visible = "1"; + text = "Road Settings"; + maxLength = "255"; + helpTag = "0"; + }; + new GuiDynamicCtrlArrayControl(){ + Position = "83 3"; + extent = "111 32"; + colCount = "31"; + colSize = "29"; + rowCount = "1"; + RowSize = "27"; + rowSpacing = "2"; + colspacing = "4"; + + new GuiBitmapButtonCtrl(RoadEditorShowSplineBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "167 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Variable = "$DecalRoad::showSpline"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + toolTip = "Show Spline"; + bitmap = "tools/worldEditor/images/road-river/menubar/show-spline"; + groupNum = "7"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiBitmapButtonCtrl(RoadEditorWireframeBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "253 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Variable = "$DecalRoad::wireframe"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + toolTip = "Show Wireframe"; + bitmap = "tools/worldEditor/images/road-river/menubar/show-wireframe"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiBitmapButtonCtrl(RoadEditorShowRoadBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefalutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "89 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Variable = "$DecalRoad::showRoad"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + toolTip = "Show Road Texture"; + bitmap = "tools/worldEditor/images/road-river/menubar/show-texture"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + }; + new GuiControl(RoadDefaultWidthTextEditContainer) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "197 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 6"; + Extent = "68 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Default Width"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + isContainer = "0"; + profile="GuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "67 2"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "RoadEditorGui.DefaultWidth = $ThisControl.getValue();"; + hovertime = "1000"; + text = "10"; + maxLength = "3"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "101 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(RoadDefaultWidthSliderCtrlContainer);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Changes Default Road Width"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "core/art/gui/images/dropslider"; + }; + }; + /*new GuiTextEditSliderCtrl(RoadEditorDefaultWidthSlider) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "429 6"; + Extent = "46 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "RoadEditorGui.DefaultWidth = $ThisControl.getValue();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "10.0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + format = "%2.1f"; + range = "0 100"; + increment = "0.5"; + focusOnMouseWheel = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "347 7"; + Extent = "66 16"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + text = "Default Width"; + maxLength = "1024"; + };*/ +}; +new GuiMouseEventCtrl(RoadDefaultWidthSliderCtrlContainer, EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "GuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(RoadDefaultWidthTextEditContainer.position) + firstWord(RoadEditorToolbar.position) + 10 SPC + (getWord(RoadDefaultWidthTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "RoadDefaultWidthTextEditContainer-->textEdit.setText( mFloatLength($ThisControl.getValue(), 2)); RoadEditorGui.DefaultWidth = $ThisControl.getValue();"; + range = "0 100"; + ticks = "0"; + value = "10"; + }; +}; \ No newline at end of file diff --git a/Templates/Empty/game/tools/roadEditor/main.cs b/Templates/Empty/game/tools/roadEditor/main.cs new file mode 100644 index 000000000..cb7ea052c --- /dev/null +++ b/Templates/Empty/game/tools/roadEditor/main.cs @@ -0,0 +1,215 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function initializeRoadEditor() +{ + echo( " - Initializing Road and Path Editor" ); + + exec( "./roadEditor.cs" ); + exec( "./roadEditorGui.gui" ); + exec( "./roadEditorToolbar.gui"); + exec( "./roadEditorGui.cs" ); + + // Add ourselves to EditorGui, where all the other tools reside + RoadEditorGui.setVisible( false ); + RoadEditorToolbar.setVisible( false ); + RoadEditorOptionsWindow.setVisible( false ); + RoadEditorTreeWindow.setVisible( false ); + + EditorGui.add( RoadEditorGui ); + EditorGui.add( RoadEditorToolbar ); + EditorGui.add( RoadEditorOptionsWindow ); + EditorGui.add( RoadEditorTreeWindow ); + + new ScriptObject( RoadEditorPlugin ) + { + superClass = "EditorPlugin"; + editorGui = RoadEditorGui; + }; + + %map = new ActionMap(); + %map.bindCmd( keyboard, "backspace", "RoadEditorGui.onDeleteKey();", "" ); + %map.bindCmd( keyboard, "1", "RoadEditorGui.prepSelectionMode();", "" ); + %map.bindCmd( keyboard, "2", "ToolsPaletteArray->RoadEditorMoveMode.performClick();", "" ); + %map.bindCmd( keyboard, "4", "ToolsPaletteArray->RoadEditorScaleMode.performClick();", "" ); + %map.bindCmd( keyboard, "5", "ToolsPaletteArray->RoadEditorAddRoadMode.performClick();", "" ); + %map.bindCmd( keyboard, "=", "ToolsPaletteArray->RoadEditorInsertPointMode.performClick();", "" ); + %map.bindCmd( keyboard, "numpadadd", "ToolsPaletteArray->RoadEditorInsertPointMode.performClick();", "" ); + %map.bindCmd( keyboard, "-", "ToolsPaletteArray->RoadEditorRemovePointMode.performClick();", "" ); + %map.bindCmd( keyboard, "numpadminus", "ToolsPaletteArray->RoadEditorRemovePointMode.performClick();", "" ); + %map.bindCmd( keyboard, "z", "RoadEditorShowSplineBtn.performClick();", "" ); + %map.bindCmd( keyboard, "x", "RoadEditorWireframeBtn.performClick();", "" ); + %map.bindCmd( keyboard, "v", "RoadEditorShowRoadBtn.performClick();", "" ); + RoadEditorPlugin.map = %map; + + RoadEditorPlugin.initSettings(); +} + +function destroyRoadEditor() +{ +} + +function RoadEditorPlugin::onWorldEditorStartup( %this ) +{ + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Road and Path Editor", "", RoadEditorPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "Road Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "RoadEditorPlugin", "RoadEditorPalette", expandFilename("tools/worldEditor/images/toolbar/road-path-editor"), %tooltip ); + + //connect editor windows + GuiWindowCtrl::attach( RoadEditorOptionsWindow, RoadEditorTreeWindow); + + // Add ourselves to the Editor Settings window + exec( "./RoadEditorSettingsTab.gui" ); + ESettingsWindow.addTabPage( ERoadEditorSettingsPage ); +} + +function RoadEditorPlugin::onActivated( %this ) +{ + %this.readSettings(); + + ToolsPaletteArray->RoadEditorAddRoadMode.performClick(); + EditorGui.bringToFront( RoadEditorGui ); + + RoadEditorGui.setVisible( true ); + RoadEditorGui.makeFirstResponder( true ); + RoadEditorToolbar.setVisible( true ); + + RoadEditorOptionsWindow.setVisible( true ); + RoadEditorTreeWindow.setVisible( true ); + + RoadTreeView.open(ServerDecalRoadSet,true); + + %this.map.push(); + + // Set the status bar here until all tool have been hooked up + EditorGuiStatusBar.setInfo("Road editor."); + EditorGuiStatusBar.setSelection(""); + + Parent::onActivated(%this); +} + +function RoadEditorPlugin::onDeactivated( %this ) +{ + %this.writeSettings(); + + RoadEditorGui.setVisible( false ); + RoadEditorToolbar.setVisible( false ); + RoadEditorOptionsWindow.setVisible( false ); + RoadEditorTreeWindow.setVisible( false ); + %this.map.pop(); + + Parent::onDeactivated(%this); +} + +function RoadEditorPlugin::onEditMenuSelect( %this, %editMenu ) +{ + %hasSelection = false; + + if( isObject( RoadEditorGui.road ) ) + %hasSelection = true; + + %editMenu.enableItem( 3, false ); // Cut + %editMenu.enableItem( 4, false ); // Copy + %editMenu.enableItem( 5, false ); // Paste + %editMenu.enableItem( 6, %hasSelection ); // Delete + %editMenu.enableItem( 8, false ); // Deselect +} + +function RoadEditorPlugin::handleDelete( %this ) +{ + RoadEditorGui.onDeleteKey(); +} + +function RoadEditorPlugin::handleEscape( %this ) +{ + return RoadEditorGui.onEscapePressed(); +} + +function RoadEditorPlugin::isDirty( %this ) +{ + return RoadEditorGui.isDirty; +} + +function RoadEditorPlugin::onSaveMission( %this, %missionFile ) +{ + if( RoadEditorGui.isDirty ) + { + MissionGroup.save( %missionFile ); + RoadEditorGui.isDirty = false; + } +} + +function RoadEditorPlugin::setEditorFunction( %this ) +{ + %terrainExists = parseMissionGroup( "TerrainBlock" ); + + if( %terrainExists == false ) + MessageBoxYesNoCancel("No Terrain","Would you like to create a New Terrain?", "Canvas.pushDialog(CreateNewTerrainGui);"); + + return %terrainExists; +} + +//----------------------------------------------------------------------------- +// Settings +//----------------------------------------------------------------------------- + +function RoadEditorPlugin::initSettings( %this ) +{ + EditorSettings.beginGroup( "RoadEditor", true ); + + EditorSettings.setDefaultValue( "DefaultWidth", "10" ); + EditorSettings.setDefaultValue( "HoverSplineColor", "255 0 0 255" ); + EditorSettings.setDefaultValue( "SelectedSplineColor", "0 255 0 255" ); + EditorSettings.setDefaultValue( "HoverNodeColor", "255 255 255 255" ); //<-- Not currently used + EditorSettings.setDefaultValue( "MaterialName", "DefaultDecalRoadMaterial" ); + + EditorSettings.endGroup(); +} + +function RoadEditorPlugin::readSettings( %this ) +{ + EditorSettings.beginGroup( "RoadEditor", true ); + + RoadEditorGui.DefaultWidth = EditorSettings.value("DefaultWidth"); + RoadEditorGui.HoverSplineColor = EditorSettings.value("HoverSplineColor"); + RoadEditorGui.SelectedSplineColor = EditorSettings.value("SelectedSplineColor"); + RoadEditorGui.HoverNodeColor = EditorSettings.value("HoverNodeColor"); + RoadEditorGui.materialName = EditorSettings.value("MaterialName"); + + EditorSettings.endGroup(); +} + +function RoadEditorPlugin::writeSettings( %this ) +{ + EditorSettings.beginGroup( "RoadEditor", true ); + + EditorSettings.setValue( "DefaultWidth", RoadEditorGui.DefaultWidth ); + EditorSettings.setValue( "HoverSplineColor", RoadEditorGui.HoverSplineColor ); + EditorSettings.setValue( "SelectedSplineColor", RoadEditorGui.SelectedSplineColor ); + EditorSettings.setValue( "HoverNodeColor", RoadEditorGui.HoverNodeColor ); + EditorSettings.setValue( "MaterialName", RoadEditorGui.materialName ); + + EditorSettings.endGroup(); +} diff --git a/Templates/Empty/game/tools/roadEditor/roadEditor.cs b/Templates/Empty/game/tools/roadEditor/roadEditor.cs new file mode 100644 index 000000000..0822050b0 --- /dev/null +++ b/Templates/Empty/game/tools/roadEditor/roadEditor.cs @@ -0,0 +1,76 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +singleton GuiControlProfile( RoadEditorProfile ) +{ + canKeyFocus = true; + opaque = true; + fillColor = "192 192 192 192"; + category = "Editor"; +}; + +singleton GuiControlProfile (GuiSimpleBorderProfile) +{ + opaque = false; + border = 1; + category = "Editor"; +}; + +singleton GuiCursor(RoadEditorMoveCursor) +{ + hotSpot = "4 4"; + renderOffset = "0 0"; + bitmapName = "~/gui/images/macCursor"; + category = "Editor"; +}; + +singleton GuiCursor( RoadEditorMoveNodeCursor ) +{ + hotSpot = "1 1"; + renderOffset = "0 0"; + bitmapName = "./Cursors/outline/drag_node_outline"; + category = "Editor"; +}; + +singleton GuiCursor( RoadEditorAddNodeCursor ) +{ + hotSpot = "1 1"; + renderOffset = "0 0"; + bitmapName = "./Cursors/outline/add_to_end_outline"; + category = "Editor"; +}; + +singleton GuiCursor( RoadEditorInsertNodeCursor ) +{ + hotSpot = "1 1"; + renderOffset = "0 0"; + bitmapName = "./Cursors/outline/insert_in_middle_outline"; + category = "Editor"; +}; + +singleton GuiCursor( RoadEditorResizeNodeCursor ) +{ + hotSpot = "1 1"; + renderOffset = "0 0"; + bitmapName = "./Cursors/outline/widen_path_outline"; + category = "Editor"; +}; diff --git a/Templates/Empty/game/tools/roadEditor/roadEditorGui.cs b/Templates/Empty/game/tools/roadEditor/roadEditorGui.cs new file mode 100644 index 000000000..5c6a29b40 --- /dev/null +++ b/Templates/Empty/game/tools/roadEditor/roadEditorGui.cs @@ -0,0 +1,249 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function RoadEditorGui::onWake( %this ) +{ + $DecalRoad::EditorOpen = true; + + %count = EWorldEditor.getSelectionSize(); + for ( %i = 0; %i < %count; %i++ ) + { + %obj = EWorldEditor.getSelectedObject(%i); + if ( %obj.getClassName() !$= "DecalRoad" ) + EWorldEditor.unselectObject(); + else + %this.setSelectedRoad( %obj ); + } + + %this.onNodeSelected(-1); +} + +function RoadEditorGui::onSleep( %this ) +{ + $DecalRoad::EditorOpen = false; +} + +function RoadEditorGui::paletteSync( %this, %mode ) +{ + %evalShortcut = "ToolsPaletteArray-->" @ %mode @ ".setStateOn(1);"; + eval(%evalShortcut); +} + +function RoadEditorGui::onDeleteKey( %this ) +{ + %road = %this.getSelectedRoad(); + %node = %this.getSelectedNode(); + + if ( !isObject( %road ) ) + return; + + if ( %node != -1 ) + { + %this.deleteNode(); + } + else + { + MessageBoxOKCancel( "Notice", "Delete selected DecalRoad?", "RoadEditorGui.deleteRoad();", "" ); + } +} + +function RoadEditorGui::onEscapePressed( %this ) +{ + if( %this.getMode() $= "RoadEditorAddNodeMode" ) + { + %this.prepSelectionMode(); + return true; + } + return false; +} + +//just in case we need it later +function RoadEditorGui::onRoadCreation( %this ) +{ +} + +function RoadEditorGui::onRoadSelected( %this, %road ) +{ + %this.road = %road; + + // Update the materialEditorList + if(isObject( %road )) + $Tools::materialEditorList = %road.getId(); + + RoadInspector.inspect( %road ); + RoadTreeView.buildVisibleTree(true); + if( RoadTreeView.getSelectedObject() != %road ) + { + RoadTreeView.clearSelection(); + %treeId = RoadTreeView.findItemByObjectId( %road ); + RoadTreeView.selectItem( %treeId ); + } +} + +function RoadEditorGui::onNodeSelected( %this, %nodeIdx ) +{ + + if ( %nodeIdx == -1 ) + { + RoadEditorProperties-->position.setActive( false ); + RoadEditorProperties-->position.setValue( "" ); + + RoadEditorProperties-->width.setActive( false ); + RoadEditorProperties-->width.setValue( "" ); + } + else + { + RoadEditorProperties-->position.setActive( true ); + RoadEditorProperties-->position.setValue( %this.getNodePosition() ); + + RoadEditorProperties-->width.setActive( true ); + RoadEditorProperties-->width.setValue( %this.getNodeWidth() ); + } + +} + +function RoadEditorGui::onNodeModified( %this, %nodeIdx ) +{ + + RoadEditorProperties-->position.setValue( %this.getNodePosition() ); + RoadEditorProperties-->width.setValue( %this.getNodeWidth() ); + +} + +function RoadEditorGui::editNodeDetails( %this ) +{ + + %this.setNodePosition( RoadEditorProperties-->position.getText() ); + %this.setNodeWidth( RoadEditorProperties-->width.getText() ); +} + +function RoadEditorGui::onBrowseClicked( %this ) +{ + //%filename = RETextureFileCtrl.getText(); + + %dlg = new OpenFileDialog() + { + Filters = "All Files (*.*)|*.*|"; + DefaultPath = RoadEditorGui.lastPath; + DefaultFile = %filename; + ChangePath = false; + MustExist = true; + }; + + %ret = %dlg.Execute(); + if(%ret) + { + RoadEditorGui.lastPath = filePath( %dlg.FileName ); + %filename = %dlg.FileName; + RoadEditorGui.setTextureFile( %filename ); + RETextureFileCtrl.setText( %filename ); + } + + %dlg.delete(); +} + +function RoadInspector::inspect( %this, %obj ) +{ + %name = ""; + if ( isObject( %obj ) ) + %name = %obj.getName(); + else + RoadFieldInfoControl.setText( "" ); + + //RoadInspectorNameEdit.setValue( %name ); + Parent::inspect( %this, %obj ); +} + +function RoadInspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ) +{ + // Same work to do as for the regular WorldEditor Inspector. + Inspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ); +} + +function RoadInspector::onFieldSelected( %this, %fieldName, %fieldTypeStr, %fieldDoc ) +{ + RoadFieldInfoControl.setText( "<font:ArialBold:14>" @ %fieldName @ "<font:ArialItalic:14> (" @ %fieldTypeStr @ ") " NL "<font:Arial:14>" @ %fieldDoc ); +} + +function RoadTreeView::onInspect(%this, %obj) +{ + RoadInspector.inspect(%obj); +} + +function RoadTreeView::onSelect(%this, %obj) +{ + RoadEditorGui.road = %obj; + RoadInspector.inspect( %obj ); + if(%obj != RoadEditorGui.getSelectedRoad()) + { + RoadEditorGui.setSelectedRoad( %obj ); + } +} + +function RoadEditorGui::prepSelectionMode( %this ) +{ + %mode = %this.getMode(); + + if ( %mode $= "RoadEditorAddNodeMode" ) + { + if ( isObject( %this.getSelectedRoad() ) ) + %this.deleteNode(); + } + + %this.setMode( "RoadEditorSelectMode" ); + ToolsPaletteArray-->RoadEditorSelectMode.setStateOn(1); +} +//------------------------------------------------------------------------------ +function ERoadEditorSelectModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function ERoadEditorAddModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function ERoadEditorMoveModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function ERoadEditorScaleModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function ERoadEditorInsertModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function ERoadEditorRemoveModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function RoadDefaultWidthSliderCtrlContainer::onWake(%this) +{ + RoadDefaultWidthSliderCtrlContainer-->slider.setValue(RoadDefaultWidthTextEditContainer-->textEdit.getText()); +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/shapeEditor/gui/Profiles.ed.cs b/Templates/Empty/game/tools/shapeEditor/gui/Profiles.ed.cs new file mode 100644 index 000000000..c4de16378 --- /dev/null +++ b/Templates/Empty/game/tools/shapeEditor/gui/Profiles.ed.cs @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Shape Editor Profiles +//----------------------------------------------------------------------------- + +singleton GuiControlProfile(GuiShapeEdScrollProfile : GuiEditorScrollProfile) +{ + // Don't clear the scroll area (since we need to be able to see the GuiContainer + // underneath that provides the fill color for the header row) + opaque = false; + category = "Editor"; +}; + +singleton GuiControlProfile(GuiShapeEdTextListProfile : GuiTextListProfile) +{ + // Customise the not-active font used for the header row + fontColorNA = "75 75 75"; + category = "Editor"; +}; + +singleton GuiControlProfile(GuiShapeEdRolloutProfile : GuiInspectorRolloutProfile0) +{ + bitmap = "tools/editorclasses/gui/images/rollout"; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiShapeEdTransitionSliderProfile ) +{ + bitmap = "tools/shapeEditor/images/transition_slider"; + category = "Core"; +}; diff --git a/Templates/Empty/game/tools/shapeEditor/gui/ShapeEditorSettingsTab.gui b/Templates/Empty/game/tools/shapeEditor/gui/ShapeEditorSettingsTab.gui new file mode 100644 index 000000000..7e5b0651a --- /dev/null +++ b/Templates/Empty/game/tools/shapeEditor/gui/ShapeEditorSettingsTab.gui @@ -0,0 +1,549 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ShapeEditorSettingsTab,EditorGuiGroup) { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiTabPageCtrl(EShapeEditorSettingsPage) { + fitBook = "1"; + text = "Shape Editor"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiSolidDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "208 400"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "208 400"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + extent = "208 210"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Colors"; + Margin = "0 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiControl() { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 10"; + Extent = "208 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + className = "ESettingsWindowColor"; + editorSettingsRead = "ShapeEdShapeView.sunDiffuse = EditorSettings.value(%this.editorSettingsValue);"; + editorSettingsValue = "ShapeEditor/SunDiffuseColor"; + editorSettingsWrite = "ShapeEditorPlugin.writeSettings();"; + + new GuiTextCtrl() { + text = "Sun Diffuse:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "80 0"; + Extent = "104 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + className = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + className = "ESettingsWindowColorButton"; + }; + }; + new GuiControl() { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 30"; + Extent = "208 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + className = "ESettingsWindowColor"; + editorSettingsRead = "ShapeEdShapeView.sunAmbient = EditorSettings.value(%this.editorSettingsValue);"; + editorSettingsValue = "ShapeEditor/SunAmbientColor"; + editorSettingsWrite = "ShapeEditorPlugin.writeSettings();"; + + new GuiTextCtrl() { + text = "Sun Ambient:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "80 0"; + Extent = "104 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + className = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + className = "ESettingsWindowColorButton"; + }; + }; + new GuiControl() { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 50"; + Extent = "208 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + className = "ESettingsWindowColor"; + editorSettingsRead = "ShapeEdPreviewGui-->previewBackground.color = ColorIntToFloat(EditorSettings.value(%this.editorSettingsValue));"; + editorSettingsValue = "ShapeEditor/BackgroundColor"; + editorSettingsWrite = "ShapeEditorPlugin.writeSettings();"; + + new GuiTextCtrl() { + text = "Background:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 2"; + Extent = "70 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "80 0"; + Extent = "104 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + className = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + className = "ESettingsWindowColorButton"; + }; + }; + }; + }; + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Grid"; + Margin = "0 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Grid Size:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditNumericProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "ShapeEdShapeView.gridSize = EditorSettings.value(%this.editorSettingsValue);"; + editorSettingsValue = "ShapeEditor/GridSize"; + editorSettingsWrite = "ShapeEditorPlugin.writeSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Grid Dimension:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "ShapeEdShapeView.gridDimension = EditorSettings.value(%this.editorSettingsValue);"; + editorSettingsValue = "ShapeEditor/GridDimension"; + editorSettingsWrite = "ShapeEditorPlugin.writeSettings();"; + }; + }; + }; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/shapeEditor/gui/ShapeEditorToolbar.ed.gui b/Templates/Empty/game/tools/shapeEditor/gui/ShapeEditorToolbar.ed.gui new file mode 100644 index 000000000..def18785c --- /dev/null +++ b/Templates/Empty/game/tools/shapeEditor/gui/ShapeEditorToolbar.ed.gui @@ -0,0 +1,295 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ShapeEditorToolbar, EditorGuiGroup) { + canSaveDynamicFields = "0"; + internalName = ""; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "102 0"; + Extent = "550" SPC getWord(EditorGuiToolbar.extent, 1); + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + canMove = "0"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + EdgeSnap = "0"; + text =""; + + new GuiContainer() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "menubarProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 32"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 7"; + extent = "86 16"; + minExtent = "8 8"; + visible = "1"; + text = "Preview Settings"; + maxLength = "255"; + helpTag = "0"; + }; + new GuiBitmapCtrl() { + Profile = "GuiDefaultProfile"; + position = "94 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-h.png"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "showGridBtn"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "100 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdShapeView.renderGrid = $ThisControl.getValue();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Show grid"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/show-grid"; + text = ""; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "fitToShapeBtn"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "134 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdShapeView.fitToShape();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Fit Camera to Shape (F)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/fit-selection"; + text = ""; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "orbitNodeBtn"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "168 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdShapeView.orbitNode = $ThisControl.getValue();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Orbit the selected node"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/orbit-cam"; + text = ""; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + }; + new GuiBitmapCtrl() { + Profile = "GuiDefaultProfile"; + position = "202 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-h.png"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "showNodes"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "210 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdShapeView.renderNodes = $ThisControl.getValue();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Show Nodes (N)"; + hovertime = "1000"; + bitmap = "tools/shapeEditor/images/shownodes_btn"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + internalName = "ghostMode"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "243 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdShapeView.renderGhost = $ThisControl.getValue();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Toggle shape transparency in the preview window (T)"; + hovertime = "1000"; + bitmap = "tools/shapeEditor/images/ghost_btn"; + buttonType = "ToggleButton"; + groupNum = "0"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + internalName = "wireframeMode"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "276 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "shapeEditorWireframeMode();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Toggle shape wireframe in the preview window (R)"; + hovertime = "1000"; + bitmap = "tools/shapeEditor/images/show-wireframe"; + buttonType = "ToggleButton"; + groupNum = "0"; + useMouseEvents = "0"; + }; + new GuiBitmapCtrl() { + Profile = "GuiDefaultProfile"; + position = "309 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-h.png"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "showBounds"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "315 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdShapeView.renderbounds = $ThisControl.getValue();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Toggle shape bounding box in the preview window"; + hovertime = "1000"; + bitmap = "tools/shapeEditor/images/object-bounds"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "showObjBox"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "348 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdShapeView.renderObjBox = $ThisControl.getValue();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Toggle selected object bounding box in the preview window"; + hovertime = "1000"; + bitmap = "tools/shapeEditor/images/object-fit-bounds"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "renderColMeshes"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "381 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "shapeEdShapeView.renderColMeshes = $ThisControl.getValue();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Toggle rendering of collision meshes in the preview window"; + hovertime = "1000"; + bitmap = "tools/shapeEditor/images/collision-shape"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + }; + new GuiBitmapCtrl() { + Profile = "GuiDefaultProfile"; + position = "415 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-h.png"; + }; + new GuiBitmapButtonCtrl() { + internalName = "showAdvanced"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "423 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdAdvancedWindow.setVisible( $ThisControl.getValue() );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Toggle Advanced Properties Window"; + hovertime = "1000"; + bitmap = "tools/shapeEditor/images/detail-levels_btn"; + buttonType = "ToggleButton"; + groupNum = "0"; + useMouseEvents = "0"; + }; + }; +}; diff --git a/Templates/Empty/game/tools/shapeEditor/gui/shapeEdAdvancedWindow.ed.gui b/Templates/Empty/game/tools/shapeEditor/gui/shapeEdAdvancedWindow.ed.gui new file mode 100644 index 000000000..b8221e4da --- /dev/null +++ b/Templates/Empty/game/tools/shapeEditor/gui/shapeEdAdvancedWindow.ed.gui @@ -0,0 +1,1845 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiWindowCollapseCtrl(ShapeEdAdvancedWindow, EditorGuiGroup) { + text = "Advanced Properties"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + closeCommand = "ShapeEditorToolbar-->showAdvanced.performClick();"; + EdgeSnap = "1"; + Margin = "4 4 4 4"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + position = getWord($pref::Video::mode, 0) - 209 - 209 SPC getWord(EditorGuiToolbar.extent, 1) - 1; + extent = "210 272"; + MinExtent = "210 253"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Profile = "GuiWindowProfile"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + minSize = "50 50"; + + new GuiTabBookCtrl() { + TabPosition = "Top"; + TabMargin = "6"; + MinTabWidth = "32"; + docking = "client"; + Margin = "3 1 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + position = "4 24"; + extent = "202 243"; + MinExtent = "8 -500"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "GuiTabBookProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "tabBook"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTabPageCtrl() { + text = "Details"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + Position = "0 19"; + extent = "202 224"; + MinExtent = "0 -500"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "GuiTabPageProfile"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiContainer() { + docking = "client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + position = "0 0"; + extent = "202 224"; + MinExtent = "8 8"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "GuiDefaultProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiContainer() { + position = "0 0"; + extent = "202 157"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "inspectorStyleRolloutDarkProfile"; + + new GuiTextCtrl() { + text = "Levels"; + position = "4 1"; + Extent = "192 16"; + MinExtent = "8 2"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "GuiTextProfile"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Levels"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "5 22"; + Extent = "49 13"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiCheckBoxProfile"; + Visible = "1"; + Variable = "ShapeEdShapeView.fixedDetail"; + Command = "ShapeEdAdvancedWindow-->detailSlider.setActive($ThisControl.getValue()); ShapeEdAdvancedWindow-->levelsInactive.setVisible( !$ThisControl.getValue() );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Allow the slider to select the current detail level"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "0 0"; + ticks = "1"; + snap = "1"; + value = "0"; + position = "57 22"; + Extent = "118 14"; + MinExtent = "8 2"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "GuiSliderProfile"; + Visible = "1"; + Variable = "ShapeEdShapeView.currentDL"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Drag the slider to change the current detail level"; + hovertime = "1000"; + isContainer = "0"; + internalName = "detailSlider"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapCtrl(){ + bitmap = "core/art/gui/images/inactive-overlay"; + position = "57 19"; + Extent = "122 20"; + tooltip = "Levels needs to be selected to enable the detail level slider"; + hovertime = "500"; + isContainer = true; + internalName = "levelsInactive"; + }; + new GuiTextCtrl() { + text = "0"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + position = "182 20"; + Extent = "15 16"; + MinExtent = "8 2"; + HorizSizing = "left"; + VertSizing = "bottom"; + Profile = "GuiTextProfile"; + Visible = "1"; + Variable = "ShapeEdShapeView.currentDL"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Index of the current detail level"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Polys"; + position = "37 40"; + extent = "26 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "0"; + position = "67 40"; + Extent = "40 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextProfile"; + Visible = "1"; + Variable = "ShapeEdShapeView.detailPolys"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Number of polygons in the current detail level"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Size"; + position = "127 40"; + extent = "24 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + position = "160 39"; + extent = "35 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextEditProfile"; + Visible = "1"; + Variable = "ShapeEdShapeView.detailSize"; + AltCommand = "ShapeEdAdvancedWindow.onEditDetailSize();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Edit this value to change the size of the current detail"; + hovertime = "1000"; + internalName = "detailSize"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Pixels"; + position = "35 60"; + extent = "28 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "0"; + position = "67 60"; + Extent = "40 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextProfile"; + Visible = "1"; + Variable = "ShapeEdShapeView.pixelSize"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Current size (in pixels) of the shape"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Distance"; + position = "109 60"; + Extent = "42 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = ""; + position = "160 60"; + extent = "38 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextProfile"; + Visible = "1"; + Variable = "ShapeEdShapeView.orbitDist"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Current distance from the shape to the camera"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Materials"; + position = "20 80"; + extent = "43 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = ""; + position = "67 80"; + extent = "40 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextProfile"; + Visible = "1"; + Variable = "ShapeEdShapeView.numMaterials"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Number of materials used by all meshes at this detail level"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Bones"; + position = "120 80"; + extent = "31 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "5"; + position = "160 80"; + extent = "38 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextProfile"; + Visible = "1"; + Variable = "ShapeEdShapeView.numBones"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Number of bones at this detail level (skins only)"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Primitives"; + position = "19 100"; + extent = "44 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = ""; + position = "67 100"; + extent = "40 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextProfile"; + Visible = "1"; + Variable = "ShapeEdShapeView.numDrawCalls"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Total number of mesh primitives (triangle lists) at this detail level"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Weights"; + position = "109 100"; + Extent = "42 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "5"; + position = "160 100"; + extent = "38 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextProfile"; + Visible = "1"; + Variable = "ShapeEdShapeView.numWeights"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Number of vertex weights at this detail level (skins only)"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Col Meshes"; + position = "7 120"; + extent = "56 16"; + horizSizing = "right"; + vertSizing = "bottom"; + }; + new GuiTextCtrl() { + text = ""; + position = "67 120"; + extent = "40 16"; + horizSizing = "right"; + vertSizing = "bottom"; + Variable = "ShapeEdShapeView.colMeshes"; + }; + new GuiTextCtrl() { + text = "Col Polys"; + position = "108 120"; + extent = "43 16"; + horizSizing = "right"; + vertSizing = "bottom"; + }; + new GuiTextCtrl() { + text = ""; + position = "160 120"; + extent = "38 16"; + horizSizing = "right"; + vertSizing = "bottom"; + Variable = "ShapeEdShapeView.colPolys"; + }; + }; + new GuiContainer() { + position = "0 138"; + Extent = "202 87"; + MinExtent = "8 8"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "inspectorStyleRolloutDarkProfile"; + isContainer = "1"; + + new GuiTextCtrl() { // Header + text = "Imposters"; + position = "4 1"; + Extent = "192 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextProfile"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Use Imposters"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "113 2"; + Extent = "83 13"; + MinExtent = "8 2"; + HorizSizing = "left"; + VertSizing = "bottom"; + Profile = "GuiCheckBoxProfile"; + Visible = "1"; + Command = "ShapeEdDetails.onToggleImposter( $ThisControl.getValue() );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Controls whether this shape uses an imposter detail level"; + hovertime = "1000"; + isContainer = "0"; + internalName = "bbUseImposters"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Detail Level"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + position = "6 23"; + Extent = "57 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + position = "68 22"; + Extent = "36 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextEditProfile"; + Visible = "1"; + AltCommand = "ShapeEdDetails.onEditImposter();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Specifies the detail level used to generate the imposters"; + hovertime = "1000"; + internalName = "bbDetailLevel"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Dimension"; + position = "6 43"; + Extent = "57 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + position = "68 43"; + Extent = "36 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextEditProfile"; + Visible = "1"; + AltCommand = "ShapeEdDetails.onEditImposter();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Specifies the dimension (width/height) of the imposters in pixels"; + hovertime = "1000"; + internalName = "bbDimension"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "X Steps"; + position = "6 65"; + Extent = "57 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + position = "68 64"; + Extent = "36 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextEditProfile"; + Visible = "1"; + AltCommand = "ShapeEdDetails.onEditImposter();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Number of steps in the horizontal axis"; + hovertime = "1000"; + internalName = "bbEquatorSteps"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Include Poles"; + groupNum = "-1"; + buttonType = "ToggleButton"; + position = "113 24"; + Extent = "83 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiCheckBoxProfile"; + Visible = "1"; + Command = "ShapeEdDetails.onEditImposter();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Specifies whether to include the poles (top and bottom) of the shape"; + hovertime = "1000"; + internalName = "bbIncludePoles"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Y Steps"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + position = "116 44"; + Extent = "41 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + Tooltip = "Number of steps in the vertical axis"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + position = "161 43"; + Extent = "36 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextEditProfile"; + Visible = "1"; + AltCommand = "ShapeEdDetails.onEditImposter();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "bbPolarSteps"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Y Angle"; + position = "116 65"; + Extent = "41 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Polar Angle - Y axis"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + position = "161 64"; + Extent = "36 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextEditProfile"; + Visible = "1"; + AltCommand = "ShapeEdDetails.onEditImposter();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "bbPolarAngle"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapCtrl(){ + bitmap = "core/art/gui/images/inactive-overlay"; + position = "4 18"; + Extent = "193 64"; + tooltip = "Imposters must be enabled, and an imposter detail level selected to edit these properties"; + hovertime = "500"; + isContainer = "1"; + internalName = "imposterInactive"; + }; + }; + }; + }; + new GuiTabPageCtrl() { + text = "Mounting"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + Position = "0 19"; + extent = "202 224"; + MinExtent = "0 -500"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "GuiTabPageProfile"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + isContainer = "1"; + + new GuiControl(){ + docking = "client"; + Margin = "0 0 0 0"; + Profile = "GuiScrollProfile"; + position = "0 0"; + extent = "202 224"; + + }; + new GuiContainer(ShapeEdMountWindow) { + docking = "none"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + position = "0 0"; + extent = "202 224"; + MinExtent = "8 8"; + HorizSizing = "width"; + vertSizing = "height"; + Profile = "GuiDefaultProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = " Render mounted shapes"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "2 2"; + extent = "139 13"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiCheckBoxProfile"; + Visible = "1"; + Variable = "ShapeEdShapeView.renderMounts"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Controls whether mounted shapes will be rendered in the 3D view"; + hovertime = "1000"; + isContainer = "0"; + internalName = "renderMounts"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + position = "0 17"; + extent = "202 124"; + MinExtent = "8 8"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "GuiShapeEdScrollProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + canSave = "1"; + isContainer = "1"; + + new GuiContainer() { + position = "0 0"; + extent = "200 121"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "inspectorStyleRolloutListProfile"; + }; + new GuiTextListCtrl() { + columns = "-1 0 110 152"; + fitParentWidth = "1"; + clipColumnText = "1"; + Position = "1 1"; + Extent = "200 11"; + MinExtent = "8 11"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiShapeEdTextListProfile"; + Visible = "1"; + Command = "ShapeEdMountWindow.update_onMountSelectionChanged();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "mountList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiContainer() { + position = "0 140"; + extent = "202 85"; + HorizSizing = "width"; + VertSizing = "top"; + Profile = "inspectorStyleRolloutDarkProfile"; + + new GuiTextCtrl() { + text = "Mount Item"; + position = "5 1"; + extent = "134 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "182 1"; + Extent = "16 16"; + MinExtent = "8 2"; + HorizSizing = "left"; + VertSizing = "bottom"; + Profile = "GuiDefaultProfile"; + Visible = "1"; + Command = "ShapeEdMountWindow.unmountShape();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Delete the selected mount item"; + canSaveDynamicFields = "0"; + canSave = "1"; + isContainer = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "core/art/gui/images/new"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "168 1"; + Extent = "16 16"; + MinExtent = "8 2"; + HorizSizing = "left"; + VertSizing = "bottom"; + Profile = "GuiDefaultProfile"; + Visible = "1"; + Command = "ShapeEdMountWindow.mountShape(-1);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Mounts a new shape to the current model"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + /*new GuiButtonCtrl() { + text = "Unmount All"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "109 97"; + extent = "78 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + vertSizing = "top"; + Profile = "GuiButtonProfile"; + Visible = "1"; + Command = "ShapeEdMountWindow.unmountAll();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Unmount all shapes"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + };*/ + new GuiTextCtrl() { + text = "Shape"; + position = "5 21"; + extent = "33 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextRightProfile"; + }; + new GuiPopUpMenuCtrl(ShapeEdMountShapeMenu) { + position = "42 20"; + extent = "156 18"; + HorizSizing = "width"; + vertSizing = "bottom"; + Profile = "GuiPopUpMenuProfile"; + ToolTip = "Select the model to mount"; + }; + new GuiTextCtrl() { + text = "Node"; + position = "5 42"; + extent = "33 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextRightProfile"; + }; + new GuiPopUpMenuCtrl() { + position = "42 41"; + extent = "62 18"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + Profile = "GuiPopUpMenuProfile"; + Command = "ShapeEdMountWindow.updateSelectedMount();"; + ToolTip = "Select the node on which to mount the model"; + internalName = "mountNode"; + }; + new GuiTextCtrl() { + text = "Type"; + position = "110 42"; + extent = "24 16"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + }; + new GuiPopUpMenuCtrl() { + position = "138 41"; + extent = "60 18"; + horizSizing = "left"; + vertSizing = "bottom"; + Profile = "GuiPopUpMenuProfile"; + Command = "ShapeEdMountWindow.updateSelectedMount();"; + ToolTip = "Select the type of mounting to use"; + internalName = "mountType"; + }; + new GuiPopUpMenuCtrl() { + position = "5 62"; + extent = "99 18"; + HorizSizing = "width"; + vertSizing = "bottom"; + Profile = "GuiPopUpMenuProfile"; + Command = "ShapeEdMountWindow.setMountThreadSequence();"; + ToolTip = "Select the sequence to play on the mounted model"; + internalName = "mountSeq"; + }; + new GuiSliderCtrl(ShapeEdMountSeqSlider) { + range = "0 1"; + ticks = "0"; + snap = "0"; + value = "0"; + position = "109 64"; + extent = "68 14"; + MinExtent = "8 2"; + HorizSizing = "width"; + VertSizing = "top"; + Profile = "GuiSliderProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Drag the slider to scrub through the sequence keyframes"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/shapeEditor/images/playfwd_btn"; + groupNum = "0"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "180 62"; + Extent = "18 18"; + MinExtent = "8 2"; + HorizSizing = "left"; + vertSizing = "top"; + Profile = "GuiButtonProfile"; + Visible = "1"; + Command = "ShapeEdMountWindow.toggleMountThreadPlayback();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Play forwards"; + hovertime = "1000"; + isContainer = "0"; + internalName = "mountPlayBtn"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; + new GuiTabPageCtrl() { + text = "Threads"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + Position = "0 19"; + extent = "202 224"; + MinExtent = "0 -500"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "GuiTabPageProfile"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiContainer(ShapeEdThreadWindow) { + docking = "client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + position = "0 0"; + extent = "202 224"; + MinExtent = "8 8"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "GuiDefaultProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiContainer() { + position = "0 0"; + extent = "203 141"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "inspectorStyleRolloutDarkProfile"; + + new GuiTextCtrl() { + text = "Thread"; + position = "4 1"; + extent = "41 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + }; + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + position = "0 17"; + extent = "47 124"; + MinExtent = "8 8"; + HorizSizing = "right"; + VertSizing = "height"; + Profile = "GuiShapeEdScrollProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextListCtrl(ShapeEdThreadList) { + fitParentWidth = "1"; + clipColumnText = "1"; + position = "1 1"; + extent = "45 11"; + MinExtent = "8 11"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiShapeEdTextListProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTextCtrl() { + text = "Sequence"; + position = "52 1"; + extent = "53 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + }; + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + position = "46 17"; + extent = "157 124"; + MinExtent = "8 8"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "GuiShapeEdScrollProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextListCtrl() { + fitParentWidth = "1"; + clipColumnText = "1"; + Position = "1 1"; + extent = "155 11"; + MinExtent = "8 11"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiShapeEdTextListProfile"; + Visible = "1"; + Command = "ShapeEdSequenceList.setSelectedById( $ThisControl.getSelectedId() );"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "seqList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "184 1"; + Extent = "16 16"; + MinExtent = "8 2"; + HorizSizing = "left"; + VertSizing = "bottom"; + Profile = "GuiDefaultProfile"; + Visible = "1"; + Command = "ShapeEdThreadWindow.onRemoveThread();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Delete the selected thread"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "core/art/gui/images/new"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "171 1"; + Extent = "16 16"; + MinExtent = "8 2"; + HorizSizing = "left"; + VertSizing = "bottom"; + Profile = "GuiDefaultProfile"; + Visible = "1"; + Command = "ShapeEdThreadWindow.onAddThread();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Add a new thread"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiSliderCtrl(ShapeEdThreadSlider) { + range = "0 0"; + ticks = "0"; + snap = "0"; + value = "0"; + position = "29 146"; + extent = "133 14"; + MinExtent = "8 2"; + HorizSizing = "width"; + VertSizing = "top"; + Profile = "GuiSliderProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Drag the slider to scrub through the sequence keyframes"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/shapeEditor/images/playbkwd_btn"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + position = "6 144"; + extent = "18 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + vertSizing = "top"; + Profile = "GuiButtonProfile"; + Visible = "1"; + Command = "ShapeEdAnimWindow-->playBkwdBtn.performClick();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Play backwards"; + hovertime = "1000"; + isContainer = "0"; + internalName = "playBkwdBtn"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/shapeEditor/images/pause_btn"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + position = "166 144"; + Extent = "18 18"; + MinExtent = "8 2"; + HorizSizing = "left"; + vertSizing = "top"; + Profile = "GuiButtonProfile"; + Visible = "1"; + Command = "ShapeEdAnimWindow-->pauseBtn.performClick();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Toggle Pause (SPACE)"; + hovertime = "1000"; + isContainer = "0"; + internalName = "pauseBtn"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/shapeEditor/images/playfwd_btn"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + position = "184 144"; + Extent = "18 18"; + MinExtent = "8 2"; + HorizSizing = "left"; + vertSizing = "top"; + Profile = "GuiButtonProfile"; + Visible = "1"; + Command = "ShapeEdAnimWindow-->playFwdBtn.performClick();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Play forwards"; + hovertime = "1000"; + isContainer = "0"; + internalName = "playFwdBtn"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = " Transition lasts"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "3 167"; + extent = "88 13"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "top"; + Profile = "GuiCheckBoxProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Controls whether the thread will smoothly transition when a new sequence is selected"; + hovertime = "1000"; + isContainer = "0"; + internalName = "useTransitions"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + position = "98 164"; + extent = "49 18"; + MinExtent = "8 2"; + HorizSizing = "width"; + VertSizing = "top"; + Profile = "GuiTextEditProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Number of seconds over which to transition to the new sequence"; + hovertime = "1000"; + internalName = "transitionTime"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "seconds"; + position = "153 165"; + extent = "44 16"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "top"; + profile = "GuiTextProfile"; + }; + new GuiTextCtrl() { + text = "Transition to"; + position = "4 186"; + extent = "62 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "top"; + profile = "GuiTextProfile"; + }; + new GuiPopUpMenuCtrl() { + position = "68 185"; + extent = "133 18"; + HorizSizing = "width"; + vertSizing = "top"; + Profile = "GuiPopUpMenuProfile"; + ToolTip = "Select the start position of the new sequence"; + internalName = "transitionTo"; + }; + new GuiTextCtrl() { + text = "Target anim"; + position = "4 207"; + extent = "58 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "top"; + profile = "GuiTextProfile"; + }; + new GuiPopUpMenuCtrl() { + position = "68 206"; + extent = "133 18"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "top"; + Profile = "GuiPopUpMenuProfile"; + ToolTip = "Select the initial play state of the new sequence"; + internalName = "transitionTarget"; + }; + }; + }; + new GuiTabPageCtrl() { + text = "Collision"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + Position = "0 19"; + extent = "202 224"; + MinExtent = "0 -500"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "GuiTabPageProfile"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiContainer(ShapeEdColWindow) { + docking = "client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + position = "0 0"; + extent = "202 225"; + MinExtent = "8 8"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "GuiDefaultProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Fit Type"; + position = "5 5"; + extent = "41 16"; + horizSizing = "right"; + vertSizing = "bottom"; + }; + new GuiPopUpMenuCtrl() { + position = "70 4"; + extent = "108 18"; + horizSizing = "right"; + vertSizing = "bottom"; + Profile = "GuiPopUpMenuProfile"; + Command = "ShapeEdColWindow.editCollision();"; + ToolTip = "Select the method used to auto-generate the collision geometry"; + internalName = "colType"; + }; + new GuiTextCtrl() { + text = "Fit Target"; + position = "5 25"; + extent = "45 16"; + horizSizing = "right"; + vertSizing = "bottom"; + }; + new GuiPopUpMenuCtrl() { + position = "70 24"; + extent = "108 18"; + horizSizing = "right"; + vertSizing = "bottom"; + Profile = "GuiPopUpMenuProfile"; + Command = "ShapeEdColWindow.editCollision();"; + ToolTip = "Select the object to fit collision geometry to"; + internalName = "colTarget"; + }; + new GuiTextCtrl() { + text = "Max Depth"; + position = "5 47"; + extent = "53 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + }; + new GuiSliderCtrl() { + range = "0 8"; + ticks = "4"; + snap = "0"; + value = "4"; + position = "70 48"; + extent = "104 14"; + MinExtent = "8 2"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "GuiSliderProfile"; + Visible = "1"; + AltCommand = "ShapeEdColWindow-->hullDepthText.setText( mFloor($ThisControl.getValue()) );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Maximum hull split depth"; + hovertime = "1000"; + isContainer = "0"; + internalName = "hullDepth"; + }; + new GuiTextCtrl() { + text = "4"; + position = "181 47"; + extent = "18 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + internalName = "hullDepthText"; + }; + new GuiTextCtrl() { + text = "Merge %"; + position = "5 68"; + extent = "53 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + }; + new GuiSliderCtrl() { + range = "0 60"; + ticks = "4"; + snap = "0"; + value = "30"; + position = "70 69"; + extent = "104 14"; + MinExtent = "8 2"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "GuiSliderProfile"; + Visible = "1"; + AltCommand = "ShapeEdColWindow-->hullMergeText.setText( mFloor($ThisControl.getValue()) );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Hull volume merge threshold"; + hovertime = "1000"; + isContainer = "0"; + internalName = "hullMergeThreshold"; + }; + new GuiTextCtrl() { + text = "30"; + position = "179 68"; + extent = "18 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + internalName = "hullMergeText"; + }; + new GuiTextCtrl() { + text = "Concavity %"; + position = "5 89"; + extent = "59 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + }; + new GuiSliderCtrl() { + range = "0 60"; + ticks = "4"; + snap = "0"; + value = "30"; + position = "70 90"; + extent = "104 14"; + MinExtent = "8 2"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "GuiSliderProfile"; + Visible = "1"; + AltCommand = "ShapeEdColWindow-->hullConcaveText.setText( mFloor($ThisControl.getValue()) );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Hull concavity threshold"; + hovertime = "1000"; + isContainer = "0"; + internalName = "hullConcaveThreshold"; + }; + new GuiTextCtrl() { + text = "30"; + position = "179 89"; + extent = "18 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + internalName = "hullConcaveText"; + }; + new GuiTextCtrl() { + text = "Max Verts"; + position = "5 110"; + extent = "53 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + }; + new GuiSliderCtrl() { + range = "8 64"; + ticks = "4"; + snap = "0"; + value = "32"; + position = "70 111"; + extent = "104 14"; + MinExtent = "8 2"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "GuiSliderProfile"; + Visible = "1"; + AltCommand = "ShapeEdColWindow-->hullMaxVertsText.setText( mFloor($ThisControl.getValue()) );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Maximum number of verts in a convex hull"; + hovertime = "1000"; + isContainer = "0"; + internalName = "hullMaxVerts"; + }; + new GuiTextCtrl() { + text = "32"; + position = "179 110"; + extent = "18 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + internalName = "hullMaxVertsText"; + }; + new GuiTextCtrl() { + text = "Box %"; + position = "5 131"; + extent = "53 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + }; + new GuiSliderCtrl() { + range = "0 100"; + ticks = "4"; + snap = "0"; + value = "30"; + position = "70 132"; + extent = "104 14"; + MinExtent = "8 2"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "GuiSliderProfile"; + Visible = "1"; + AltCommand = "ShapeEdColWindow-->hullMaxBoxErrorText.setText( mFloor($ThisControl.getValue()) );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Maximum box volume error %"; + hovertime = "1000"; + isContainer = "0"; + internalName = "hullMaxBoxError"; + }; + new GuiTextCtrl() { + text = "30"; + position = "179 131"; + extent = "18 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + internalName = "hullMaxBoxErrorText"; + }; + new GuiTextCtrl() { + text = "Sphere %"; + position = "5 152"; + extent = "53 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + }; + new GuiSliderCtrl() { + range = "0 100"; + ticks = "4"; + snap = "0"; + value = "30"; + position = "70 153"; + extent = "104 14"; + MinExtent = "8 2"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "GuiSliderProfile"; + Visible = "1"; + AltCommand = "ShapeEdColWindow-->hullMaxSphereErrorText.setText( mFloor($ThisControl.getValue()) );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Maximum sphere volume error %"; + hovertime = "1000"; + isContainer = "0"; + internalName = "hullMaxSphereError"; + }; + new GuiTextCtrl() { + text = "30"; + position = "179 152"; + extent = "18 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + internalName = "hullMaxSphereErrorText"; + }; + new GuiTextCtrl() { + text = "Capsule %"; + position = "5 173"; + extent = "53 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + }; + new GuiSliderCtrl() { + range = "0 100"; + ticks = "4"; + snap = "0"; + value = "30"; + position = "70 174"; + extent = "104 14"; + MinExtent = "8 2"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "GuiSliderProfile"; + Visible = "1"; + AltCommand = "ShapeEdColWindow-->hullMaxCapsuleErrorText.setText( mFloor($ThisControl.getValue()) );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Maximum capsule volume error %"; + hovertime = "1000"; + isContainer = "0"; + internalName = "hullMaxCapsuleError"; + }; + new GuiTextCtrl() { + text = "30"; + position = "179 173"; + extent = "18 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + internalName = "hullMaxCapsuleErrorText"; + }; + new GuiButtonCtrl() { + text = "Update Hulls"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "7 200"; + extent = "88 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + vertSizing = "bottom"; + Profile = "GuiButtonProfile"; + Visible = "1"; + Command = "ShapeEdColWindow.editCollision();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Update the convex hull(s)"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Revert Changes"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "105 200"; + extent = "88 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + vertSizing = "bottom"; + Profile = "GuiButtonProfile"; + Visible = "1"; + Command = "ShapeEdColWindow.update_onCollisionChanged();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Revert changes to settings"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapCtrl() { + bitmap = "core/art/gui/images/inactive-overlay"; + position = "0 47"; + extent = "199 175"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + internalName = "hullInactive"; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- + +new GuiControl(ShapeEdWaitGui,EditorGuiGroup) { + isContainer = "1"; + Profile = "GuiOverlayProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiControl() { + isContainer = "1"; + Profile = "editorMenu_wBorderProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "277 271"; + Extent = "245 57"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "Dialog"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = ""; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextBoldCenterProfile"; + HorizSizing = "width"; + VertSizing = "center"; + position = "5 19"; + Extent = "236 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + internalName = "message"; + }; + }; +}; + +function ShapeEdWaitGui::show(%this, %text) +{ + %this-->message.setText( %text ); + Canvas.pushDialog( %this ); + Canvas.repaint(); +} + +function ShapeEdWaitGui::hide(%this) +{ + Canvas.popDialog( %this ); +} + +function ShapeEdWaitGui::onWake(%this) +{ + %res = %this.getExtent(); + %resX = getWord( %res, 0 ); + %resY = getWord( %res, 1 ); + + %dialog = %this-->Dialog; + %dialogExtent = %dialog.getExtent(); + %dialogWidth = getWord( %dialogExtent, 0 ); + %dialogHeight = getWord( %dialogExtent, 1 ); + %dialogPostion = %dialog.getPosition(); + + %posX = ( %resX / 2 ) - ( %dialogWidth / 2 ); + %posY = ( %resY / 2 ) - ( %dialogHeight / 2 ); + %dialog.setPosition( %posX, %posY ); +} diff --git a/Templates/Empty/game/tools/shapeEditor/gui/shapeEdAnimWindow.ed.gui b/Templates/Empty/game/tools/shapeEditor/gui/shapeEdAnimWindow.ed.gui new file mode 100644 index 000000000..731e877de --- /dev/null +++ b/Templates/Empty/game/tools/shapeEditor/gui/shapeEdAnimWindow.ed.gui @@ -0,0 +1,438 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiWindowCtrl(ShapeEdAnimWindow) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiToolbarWindowProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = -1 SPC getWord(ShapeEdPreviewGui.extent,0)-94; + Extent = "817 53"; + MinExtent = "475 53"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "4 4 4 4"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "0"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "0"; + canCollapse = "0"; + text = ""; + + new GuiContainer() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "5 10"; + Extent = "809 "; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + // Sequence playback controls + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "0 3"; + Extent = "809 38"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiTextCtrl() { + HorizSizing = "left"; + VertSizing = "top"; + position = "740 19"; + Extent = "35 16"; + text = "Frame:"; + }; + new GuiTextCtrl() { + HorizSizing = "left"; + VertSizing = "top"; + Profile = "GuiTextProfile"; + position = "778 19"; + Extent = "26 18"; + Variable = "$ShapeEdCurrentFrame"; + }; + + new GuiTextEditCtrl() { + internalName = "seqIn"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "28 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ShapeEdSequences.onEditSeqInOut(\"in\", $ThisControl.getText());"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Set the In Point to the Current Frame"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "5"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + + new GuiSliderCtrl(ShapeEdSeqSlider) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "35 4"; + Extent = "736 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + range = "0 255"; + ticks = "0"; + value = "0"; + Variable = "$ShapeEdCurrentFrame"; + }; + + new GuiTextEditCtrl() { + internalName = "seqOut"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "778 0"; + Extent = "28 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ShapeEdSequences.onEditSeqInOut(\"out\", $ThisControl.getText());"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Set the Out Point to the Current Frame"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "5"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + + // VCR style buttons: back step_back play step_fwd fwd + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "center"; + VertSizing = "top"; + position = "194 17"; + extent = "420 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "28 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdSequences.onEditSeqInOut(\"in\", ShapeEdSeqSlider.getValue());"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Set the in position to the current frame (I)"; + hovertime = "1000"; + text = "in"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "48 0"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdAnimWindow.setKeyframe( ShapeEdAnimWindow-->seqIn.getText() );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Skip to in frame (SHIFT -)"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/shapeEditor/images/back_btn"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "76 0"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdAnimWindow.setKeyframe( mCeil(ShapeEdSeqSlider.getValue() - 1) );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Previous frame (-)"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/shapeEditor/images/stepback_btn"; + internalName = "stepBkwdBtn"; + }; + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "114 0"; + Extent = "94 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl() { + internalName = "playBkwdBtn"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdAnimWindow.setNoProxySequence(); ShapeEdAnimWindow.setThreadDirection( -1 );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Play sequence in reverse"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/shapeEditor/images/playbkwd_btn"; + }; + new GuiBitmapButtonCtrl() { + internalName = "pauseBtn"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "38 0"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdAnimWindow.setThreadDirection( 0 );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Toggle pause (SPACE)"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/shapeEditor/images/pause_btn"; + }; + new GuiBitmapButtonCtrl() { + internalName = "playFwdBtn"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "76 0"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdAnimWindow.setNoProxySequence(); ShapeEdAnimWindow.setThreadDirection( 1 );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Play sequence"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/shapeEditor/images/playfwd_btn"; + }; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "228 0"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdAnimWindow.setKeyframe( mFloor(ShapeEdSeqSlider.getValue() + 1) );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Next frame (+)"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/shapeEditor/images/stepfwd_btn"; + internalName = "stepFwdBtn"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "266 0"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdAnimWindow.setKeyframe( ShapeEdAnimWindow-->seqOut.getText() );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Skip to out frame (SHIFT +)"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/shapeEditor/images/fwd_btn"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + horizSizing = "right"; + VertSizing = "bottom"; + position = "306 0"; + Extent = "28 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdSequences.onEditSeqInOut(\"out\", ShapeEdSeqSlider.getValue());"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Set the out position to the current frame (O)"; + hovertime = "1000"; + text = "out"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + internalName = "pingpong"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + horizSizing = "left"; + VertSizing = "bottom"; + position = "365 0"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdAnimWindow.togglePingPong();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Toggle 'pingpong' mode on the current thread"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + bitmap = "tools/shapeEditor/images/pingpong_btn"; + }; + new GuiTextEditCtrl() { + internalName = "timeScale"; + Profile = "GuiTextEditProfile"; + horizSizing = "left"; + VertSizing = "bottom"; + position = "390 0"; + extent = "30 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Text = "1.0"; + AltCommand = "ShapeEdShapeView.setTimeScale( $ThisControl.getText() );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Edit this value to change the playback speed for all threads"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiBitmapButtonCtrl() { + internalName = "seqInBar"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "39 0"; + Extent = "8 13"; + MinExtent = "1 1"; + bitmap = "tools/shapeEditor/images/seq_bar-in"; + ToolTip = "Set the In Point to the Current Frame"; + Command = "ShapeEdSequences.onEditSeqInOut(\"in\", ShapeEdSeqSlider.getValue());"; + }; + new GuiBitmapButtonCtrl() { + internalName = "seqOutBar"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "765 0"; + Extent = "8 13"; + MinExtent = "1 1"; + bitmap = "tools/shapeEditor/images/seq_bar-out"; + ToolTip = "Set the Out Point to the Current Frame"; + Command = "ShapeEdSequences.onEditSeqInOut(\"out\", ShapeEdSeqSlider.getValue());"; + }; + }; +}; + +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/shapeEditor/gui/shapeEdPreviewWindow.ed.gui b/Templates/Empty/game/tools/shapeEditor/gui/shapeEdPreviewWindow.ed.gui new file mode 100644 index 000000000..c81f82952 --- /dev/null +++ b/Templates/Empty/game/tools/shapeEditor/gui/shapeEdPreviewWindow.ed.gui @@ -0,0 +1,85 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(ShapeEdPreviewGui) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0" SPC (getWord(EditorGuiToolbar.extent, 1)-1); + Docking = "Client"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiSwatchButtonCtrl() { + internalName = "previewBackground"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiInspectorSwatchButtonProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "-210 -40"; + Extent = getWord(ShapeEdPreviewGui.extent,0)+212 + SPC getWord(ShapeEdPreviewGui.extent,0)+42; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + color = "0 0 0 .39"; + }; + new GuiShapeEdPreview(ShapeEdShapeView) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "-209 -90"; + Extent = getWord(ShapeEdPreviewGui.extent,0)+209 + SPC getWord(ShapeEdPreviewGui.extent, 1)+90; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + renderMissionArea = "0"; + GizmoProfile = "GlobalGizmoProfile"; + cameraZRot = "0"; + forceFOV = "0"; + gridColor = "0 0 0 140"; + renderNodes = "0"; + renderObjBox = "0"; + renderMounts = "0"; + renderColMeshes = "0"; + selectedNode = "-1"; + sunDiffuse = "255 255 255 255"; + sunAmbient = "180 180 180 255"; + timeScale = "1.0"; + fixedDetail = "0"; + orbitNode = "0"; + }; + }; +}; + +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/shapeEditor/gui/shapeEdPropWindow.ed.gui b/Templates/Empty/game/tools/shapeEditor/gui/shapeEdPropWindow.ed.gui new file mode 100644 index 000000000..e2a3f1b28 --- /dev/null +++ b/Templates/Empty/game/tools/shapeEditor/gui/shapeEdPropWindow.ed.gui @@ -0,0 +1,1474 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiWindowCollapseCtrl(ShapeEdPropWindow) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) + getWord(ShapeEdSelectWindow.extent, 1) - 2; + Extent = "210 484"; + MinExtent = "210 352"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "4 4 4 4"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Properties"; + + //--------------------------------------------------------------------- + // Sequence and Node editors + new GuiTabBookCtrl(ShapeEdSeqNodeTabBook) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "4 42"; + Extent = "202 437"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "client"; + Margin = "3 1 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + TabPosition = "Top"; + TabMargin = "6"; + MinTabWidth = "32"; + + //--------------------------------------------------------------- + // Sequence editor + new GuiTabPageCtrl(ShapeEdSequences) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 19"; + Extent = "202 418"; + MinExtent = "0 -500"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Seq"; + maxLength = "1024"; + + new GuiContainer() { + isContainer = "1"; + Profile = "GuiInspectorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 418"; + MinExtent = "0 8"; + }; + new GuiBitmapBorderCtrl() { + isContainer = "1"; + Profile = "GuiTabBorderProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 418"; + MinExtent = "0 8"; + }; + + // Sequence list + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 211"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiShapeEdScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 211"; + MinExtent = "8 25"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = false; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiContainer() { + internalName = "sequenceListHeader"; + Profile = "inspectorStyleRolloutListProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "200 19"; + MinExtent = "8 2"; + }; + new GuiTextListCtrl(ShapeEdSequenceList) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiShapeEdTextListProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "202 20"; + MinExtent = "8 11"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdPropWindow.update_onSeqSelectionChanged();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + enumerate = "0"; + resizeCell = "1"; + columns = "0 100 145 190 235"; + fitParentWidth = "0"; + clipColumnText = "1"; + }; + }; + }; + + // Sequence properties + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "0 210"; + Extent = "202 209"; + MinExtent = "8 11"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ // Sequence Properties Container + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "202 103"; + isContainer = true; + + new GuiTextCtrl() { // Header + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "104 16"; + text = "Sequence Properties"; + }; + new GuiTextCtrl() { // Name + HorizSizing = "right"; + VertSizing = "bottom"; + position = "16 22"; + Extent = "27 16"; + text = "Name"; + }; + new GuiTextEditCtrl() { + internalName = "seqName"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "46 21"; + Extent = "152 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ShapeEdSequences.onEditName();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Name of the selected sequence (edit to rename)"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "256"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + // animation dropdown + new GuiTextCtrl() { + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "-5 42"; + Extent = "48 18"; + text = "Source"; + tooltip = "Animation source data"; + }; + new GuiPopUpMenuCtrl(ShapeEdSeqFromMenu) { + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "46 41"; + Extent = "91 18"; + }; + // Start Frame + new GuiTextCtrl() { + Profile = "GuiTextRightProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "32 62"; + Extent = "11 16"; + text = "in"; + }; + new GuiTextEditCtrl() { + internalName = "startFrame"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "46 61"; + Extent = "32 18"; + text = ""; + AltCommand = "ShapeEdSequences.onEditSeqInOut(\"in\", $ThisControl.getText());"; + }; + // End frame + new GuiTextCtrl() { + Profile = "GuiTextRightProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "85 62"; + Extent = "18 16"; + text = "out"; + }; + new GuiTextEditCtrl() { + internalName = "endFrame"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "105 61"; + Extent = "32 18"; + text = ""; + AltCommand = "ShapeEdSequences.onEditSeqInOut(\"out\", $ThisControl.getText());"; + }; + // Cyclic flag + new GuiCheckBoxCtrl() { + internalName = "cyclicFlag"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "143 43"; + Extent = "39 13"; + Command = "ShapeEdSequences.onToggleCyclic();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Loop Animation. Toggles the cyclic flag."; + hovertime = "1000"; + text = "Loop"; + }; + // Priority + new GuiTextCtrl() { + Profile = "GuiTextRightProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "136 62"; + Extent = "41 16"; + text = "Priority"; + }; + new GuiTextEditCtrl() { + internalName = "priority"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "179 61"; + Extent = "19 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ShapeEdSequences.onEditPriority();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Priority of the selected sequence"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "5"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + // Blend animation dropdown + new GuiCheckBoxCtrl() { + internalName = "blendFlag"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "2 82"; + Extent = "45 16"; + Command = "ShapeEdSequences.onEditBlend();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Toggle the blend flag for the selected sequence"; + hovertime = "1000"; + text = "Blend"; + }; + new GuiPopUpMenuCtrl() { + internalName = "blendSeq"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "46 81"; + Extent = "91 18"; + tooltip = "Blend reference sequence"; + Command = "ShapeEdSequences.onEditBlend();"; + }; + + // Blend frame + new GuiTextCtrl() { + Profile = "GuiTextRightProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "142 81"; + Extent = "29 18"; + text = "Frame"; + }; + new GuiTextEditCtrl() { + internalName = "blendFrame"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "173 81"; + Extent = "25 18"; + text = ""; + tooltip = "Blend reference frame"; + AltCommand = "ShapeEdSequences.onEditBlend();"; + }; + }; + new GuiContainer(){ // Triggers Container + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 102"; + Extent = "202 106"; + isContainer = true; + + // Triggers + new GuiTextCtrl() { + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 0"; + Extent = "50 18"; + text = "Triggers"; + }; + new GuiBitmapButtonCtrl() { + internalName = "addTriggerBtn"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "170 2"; + Extent = "15 15"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdSequences.onAddTrigger();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Add a new trigger"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "core/art/gui/images/new"; + }; + new GuiBitmapButtonCtrl() { + internalName = "deleteTriggerBtn"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "185 2"; + Extent = "15 15"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdTriggerList.onDeleteSelection();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Delete the selected trigger"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + // Trigger list + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 17"; + Extent = "202 66"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiShapeEdScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 66"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiContainer() { + Profile = "inspectorStyleRolloutListProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "200 19"; + }; + new GuiTextListCtrl(ShapeEdTriggerList) { + canSaveDynamicFields = "0"; + Profile = "GuiShapeEdTextListProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "177 16"; + MinExtent = "8 11"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdPropWindow.onTriggerSelectionChanged();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + enumerate = "0"; + resizeCell = "1"; + columns = "-1 0 60 118"; + fitParentWidth = "1"; + clipColumnText = "1"; + }; + }; + }; + new GuiTextCtrl() { + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 85"; + Extent = "35 18"; + text = "Frame"; + }; + new GuiTextEditCtrl() { + internalName = "triggerFrame"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "36 85"; + Extent = "32 18"; + text = ""; + AltCommand = "ShapeEdTriggerList.onEditSelection();"; + }; + new GuiTextCtrl() { + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "75 85"; + Extent = "35 18"; + text = "Trigger"; + }; + new GuiTextEditCtrl() { + internalName = "triggerNum"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "110 85"; + Extent = "32 18"; + text = ""; + AltCommand = "ShapeEdTriggerList.onEditSelection();"; + }; + new GuiCheckBoxCtrl() { + internalName = "triggerOnOff"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "152 87"; + Extent = "47 13"; + text = "On/off"; + Command = "ShapeEdTriggerList.onEditSelection();"; + }; + }; + }; + }; + + //--------------------------------------------------------------- + // Node Editor + new GuiTabPageCtrl(ShapeEdNodes) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 19"; + Extent = "202 418"; + MinExtent = "0 -500"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Node"; + maxLength = "1024"; + + new GuiBitmapBorderCtrl() { + isContainer = "1"; + Profile = "GuiTabBorderProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 418"; + MinExtent = "0 8"; + }; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 288"; + MinExtent = "8 0"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = false; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiTreeViewCtrl(ShapeEdNodeTreeView) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "height"; + Position = "1 1"; + Extent = "122 21"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "0"; + showRoot = "0"; + internalNamesOnly = "0"; + }; + }; + new GuiContainer(){ // Node Properties Container + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "top"; + position = "0 287"; + Extent = "202 131"; + isContainer = true; + + new GuiTextCtrl() { + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "104 16"; + text = "Node Properties"; + }; + // Node property labels + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "top"; + Position = "6 18"; + Extent = "50 108"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiTextCtrl() { + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "GuiTextRightProfile"; + position = "9 6"; + Extent = "40 16"; + text = "Name"; + }; + new GuiTextCtrl() { + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "GuiTextRightProfile"; + position = "10 26"; + Extent = "40 16"; + text = "Parent"; + }; + new GuiTextCtrl() { + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "GuiTextRightProfile"; + position = "-5 49"; + Extent = "54 16"; + text = "Transform"; + }; + new GuiTextCtrl() { + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "GuiTextRightProfile"; + position = "11 73"; + Extent = "39 16"; + text = "Position"; + }; + new GuiTextCtrl() { + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "GuiTextRightProfile"; + position = "8 93"; + Extent = "42 16"; + text = "Rotation"; + }; + }; + + // Node properties + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "49 16"; + Extent = "155 109"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiTextEditCtrl() { + internalName = "nodeName"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "12 5"; + Extent = "137 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ShapeEdNodes.onEditName();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Name of the selected node (edit to rename)"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiPopUpMenuCtrl(ShapeEdNodeParentMenu) { + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "12 25"; + Extent = "137 18"; + tooltip = "Selected node's parent"; + }; + new GuiIconButtonCtrl() { + internalName = "worldTransform"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiIconButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "12 45"; + Extent = "65 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdPropWindow.update_onNodeTransformChanged();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "View global node transform"; + hovertime = "1000"; + text = "World"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + buttonMargin = "0 4"; + iconBitmap = "tools/gui/images/menubar/world-transform_n"; + textMargin = "25"; + }; + new GuiIconButtonCtrl() { + internalName = "objectTransform"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiIconButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "84 45"; + Extent = "65 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdPropWindow.update_onNodeTransformChanged();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "View local node transform (relative to parent)"; + hovertime = "1000"; + text = "Object"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + buttonMargin = "0 4"; + iconBitmap = "tools/gui/images/menubar/object-transform_n"; + textMargin = "26"; + }; + new GuiTextEditCtrl() { + internalName = "nodePosition"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "12 72"; + Extent = "137 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ShapeEdNodes.onEditTransform();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Node position (x y z)"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiTextEditCtrl() { + internalName = "nodeRotation"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "12 92"; + Extent = "137 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ShapeEdNodes.onEditTransform();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Node rotation (axis.x axis.y axis.z angle)"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + }; + }; + }; + + //--------------------------------------------------------------- + // Details/Objects + new GuiTabPageCtrl(ShapeEdDetails) { + fitBook = "0"; + text = "Detail"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + position = "0 19"; + extent = "202 418"; + MinExtent = "0 -500"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "GuiTabPageProfile"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + + new GuiContainer() { + position = "0 0"; + extent = "202 418"; + minExtent = "0 8"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiInspectorProfile"; + isContainer = "1"; + }; + new GuiBitmapBorderCtrl() { + position = "0 0"; + extent = "202 418"; + minExtent = "0 8"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "GuiTabBorderProfile"; + isContainer = "1"; + }; + + // Detail/object tree + new GuiControl() { + Position = "0 0"; + extent = "202 276"; + MinExtent = "8 8"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "GuiDefaultProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = false; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + Position = "0 0"; + extent = "202 276"; + MinExtent = "8 25"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "GuiShapeEdScrollProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTreeViewCtrl(ShapeEdDetailTree) { + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "0"; + showRoot = "0"; + Position = "1 1"; + extent = "85 110"; + MinExtent = "8 8"; + HorizSizing = "right"; + VertSizing = "height"; + Profile = "GuiTreeViewProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + + // Detail/Object properties + new GuiControl() { + position = "0 275"; + extent = "202 143"; + MinExtent = "8 8"; + HorizSizing = "width"; + vertSizing = "top"; + Profile = "GuiDefaultProfile"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiContainer() { + position = "0 0"; + extent = "202 143"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "inspectorStyleRolloutDarkProfile"; + isContainer = "1"; + + new GuiTextCtrl() { // Header + text = "Detail/Object Properties"; + position = "4 1"; + extent = "112 16"; + HorizSizing = "right"; + VertSizing = "bottom"; + }; + new GuiTextEditCtrl() { + position = "5 23"; + extent = "130 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextEditProfile"; + Visible = "1"; + AltCommand = "ShapeEdDetails.onEditName();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Edit this value to rename the current object or detail"; + hovertime = "1000"; + internalName = "meshName"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + position = "157 23"; + extent = "40 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiTextEditProfile"; + Visible = "1"; + AltCommand = "ShapeEdDetails.onEditSize();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Edit this value to change the size of the current mesh or detail"; + hovertime = "1000"; + internalName = "meshSize"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Billboarding"; + position = "5 44"; + extent = "57 16"; + HorizSizing = "right"; + VertSizing = "bottom"; + }; + new GuiPopUpMenuCtrl() { + position = "88 45"; + extent = "109 18"; + HorizSizing = "right"; + vertSizing = "bottom"; + Profile = "GuiPopUpMenuProfile"; + Command = "ShapeEdDetails.onEditBBType();"; + ToolTip = "The type of billboarding used by the mesh"; + internalName = "bbType"; + }; + new GuiTextCtrl() { + text = "Object Node"; + position = "5 66"; + extent = "60 16"; + HorizSizing = "right"; + VertSizing = "bottom"; + }; + new GuiPopUpMenuCtrl() { + position = "88 67"; + extent = "109 18"; + HorizSizing = "right"; + vertSizing = "bottom"; + Profile = "GuiPopUpMenuProfile"; + Command = "ShapeEdDetails.onSetObjectNode();"; + ToolTip = "The node this object is attached to (all detail levels)"; + internalName = "objectNode"; + }; + new GuiBitmapCtrl(){ + bitmap = "core/art/gui/images/inactive-overlay"; + position = "4 45"; + extent = "193 42"; + tooltip = "A mesh must be selected to edit these properties"; + hovertime = "500"; + isContainer = "1"; + internalName = "editMeshInactive"; + }; + new GuiButtonCtrl() { + text = "Import Shape into..."; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "4 91"; + extent = "102 22"; + MinExtent = "8 2"; + HorizSizing = "right"; + vertSizing = "bottom"; + Profile = "GuiButtonProfile"; + Visible = "1"; + Command = "ShapeEdDetails.onAddMeshFromFile(\"\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Add geometry from a different model file into the current shape"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + position = "111 92"; + extent = "85 18"; + horizSizing = "right"; + vertSizing = "bottom"; + Profile = "GuiPopUpMenuProfile"; + tooltip = "Select which detail level new geometry will be added to"; + internalName = "addGeomTo"; + }; + new GuiButtonCtrl() { + text = "Re-compute bounds"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "40 117"; + extent = "122 22"; + MinExtent = "8 2"; + HorizSizing = "right"; + vertSizing = "bottom"; + Profile = "GuiButtonProfile"; + Visible = "1"; + Command = "ShapeEditor.doSetBounds();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Recompute the shape bounding box using the geometry in the current detail level"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; + + //--------------------------------------------------------------- + // Materials + new GuiTabPageCtrl(ShapeEdMaterials) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 19"; + Extent = "202 418"; + MinExtent = "0 -500"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Mat"; + maxLength = "1024"; + + new GuiContainer() { + isContainer = "1"; + Profile = "GuiInspectorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 418"; + MinExtent = "0 8"; + }; + new GuiBitmapBorderCtrl() { + isContainer = "1"; + Profile = "GuiTabBorderProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 418"; + MinExtent = "0 8"; + }; + + // Material list + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 345"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiShapeEdScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 345"; + MinExtent = "8 25"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = false; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiContainer() { + internalName = "materialListHeader"; + Profile = "inspectorStyleRolloutListProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "200 19"; + MinExtent = "8 2"; + }; + new GuiTextListCtrl(ShapeEdMaterialList) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiShapeEdTextListProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "202 20"; + MinExtent = "8 11"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdMaterials.updateSelectedMaterial(ShapeEdMaterials-->highlightMaterial.getValue());"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + enumerate = "0"; + resizeCell = "1"; + columns = "0 130"; + fitParentWidth = "0"; + clipColumnText = "1"; + }; + }; + }; + + // Material properties + new GuiContainer() { + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "0 344"; + Extent = "202 74"; + isContainer = true; + + new GuiTextCtrl() { // Header + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "104 16"; + text = "Material Options"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiIconButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 21"; + Extent = "150 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdMaterials.editSelectedMaterial();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Open the Material Editor to edit the selected material"; + hovertime = "1000"; + text = "Edit the selected Material"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + buttonMargin = "0 4"; + iconBitmap = "tools/worldEditor/images/toolbar/matterial-editor_n"; + textMargin = "25"; + }; + new GuiCheckBoxCtrl() { + internalName = "highlightMaterial"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 52"; + Extent = "150 13"; + Command = "ShapeEdMaterials.updateSelectedMaterial($ThisControl.getValue());"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Highlight the primitives that use the selected Material"; + hovertime = "1000"; + text = "Highlight selected Material"; + }; + }; + }; + }; + + // Save/New/Delete buttons (node or sequence, depending on which tab is active) + new GuiBitmapButtonCtrl() { + internalName = "saveBtn"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "154 25"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEditor.saveChanges();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Save the current shape"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/save-icon"; + }; + new GuiBitmapButtonCtrl() { + internalName = "newBtn"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "176 25"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = ""; + hovertime = "1000"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "core/art/gui/images/new"; + }; + new GuiBitmapButtonCtrl() { + internalName = "deleteBtn"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "190 25"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = ""; + hovertime = "1000"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; +}; +//--- OBJECT WRITE END --- + +new GuiControl(GenImposterGui,EditorGuiGroup) { + isContainer = "1"; + Profile = "GuiOverlayProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiControl() { + isContainer = "1"; + Profile = "editorMenu_wBorderProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "277 271"; + Extent = "245 57"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "Dialog"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Generating imposter bitmaps..."; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextBoldCenterProfile"; + HorizSizing = "width"; + VertSizing = "center"; + position = "5 19"; + Extent = "236 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; +}; + +function GenImposterGui::onWake(%this) +{ + %res = %this.getExtent(); + %resX = getWord(%res, 0); + %resY = getWord(%res, 1); + + %dialog = %this-->Dialog; + %dialogExtent = %dialog.getExtent(); + %dialogWidth = getWord(%dialogExtent, 0); + %dialogHeight = getWord(%dialogExtent, 1); + %dialogPostion = %dialog.getPosition(); + + %posX = (%resX / 2) - (%dialogWidth / 2); + %posY = (%resY / 2) - (%dialogHeight / 2); + %dialog.setPosition(%posX, %posY); +} diff --git a/Templates/Empty/game/tools/shapeEditor/gui/shapeEdSelectWindow.ed.gui b/Templates/Empty/game/tools/shapeEditor/gui/shapeEdSelectWindow.ed.gui new file mode 100644 index 000000000..a97734188 --- /dev/null +++ b/Templates/Empty/game/tools/shapeEditor/gui/shapeEdSelectWindow.ed.gui @@ -0,0 +1,504 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + //--------------------------------------------------------------------------- + // Shape selector window + new GuiWindowCollapseCtrl(ShapeEdSelectWindow) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) - 1; + Extent = "210 213"; + MinExtent = "210 114"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "4 4 4 4"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Shapes"; + + new GuiTabBookCtrl() { + internalName = "tabBook"; + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "4 24"; + Extent = "202 165"; + MinExtent = "8 -500"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + docking = "client"; + Margin = "3 1 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + TabPosition = "Top"; + TabMargin = "6"; + MinTabWidth = "32"; + + //--------------------------------------------------------------- + // Scene shapes (ie. the MissionGroup) + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 19"; + Extent = "202 146"; + MinExtent = "0 -500"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Scene"; + maxLength = "1024"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "202 146"; + MinExtent = "8 -500"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = false; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiTreeViewCtrl(ShapeEdShapeTreeView) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "190 144"; + MinExtent = "8 -500"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "1"; + MultipleSelections = "1"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "1"; + showRoot = "1"; + internalNamesOnly = "0"; + showObjectIds = "0"; + showClassNames = "0"; + showObjectNames = "1"; + showInternalNames = "1"; + showClassNameForUnnamedObjects = "1"; + }; + }; + }; + + //--------------------------------------------------------------- + // All shapes + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 19"; + Extent = "202 146"; + MinExtent = "0 -500"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Library"; + maxLength = "1024"; + + new GuiContainer() { + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "202 146"; + MinExtent = "0 -500"; + Profile = "GuiInspectorProfile"; + }; + new GuiBitmapBorderCtrl() { + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "202 146"; + MinExtent = "0 -500"; + Profile = "GuiTabBorderProfile"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "3 4"; + Extent = "20 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdSelectWindow.navigateUp();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/folderUp"; + }; + new GuiPopUpMenuCtrl(ShapeEdSelectMenu) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "26 4"; + Extent = "172 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "art"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 24"; + Extent = "202 122"; + MinExtent = "8 -500"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = false; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiDynamicCtrlArrayControl() { + internalName = "shapeLibrary"; + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "189 42"; + MinExtent = "8 11"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + colCount = "1"; + colSize = "64"; + rowCount = "0"; + RowSize = "64"; + rowSpacing = "4"; + colSpacing = "4"; + frozen = "0"; + autoCellSize = "1"; + fillRowFirst = "1"; + dynamicSize = "1"; + }; + }; + }; + + //--------------------------------------------------------------- + // Shape hints + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 19"; + Extent = "202 146"; + MinExtent = "0 -500"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Hints"; + maxLength = "1024"; + + new GuiContainer() { + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "202 146"; + MinExtent = "0 -500"; + Profile = "GuiInspectorProfile"; + }; + new GuiBitmapBorderCtrl() { + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "202 146"; + MinExtent = "0 -500"; + Profile = "GuiTabBorderProfile"; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 24"; + Extent = "202 123"; + MinExtent = "8 -500"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = true; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiStackControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 1"; + Extent = "185 50"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "2"; + + new GuiRolloutCtrl() { + Profile = "GuiShapeEdRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 0"; + Extent = "184 24"; + MinExtent = "8 -500"; + Caption = "Nodes"; + Margin = "2 2 2 2"; + Expanded = "0"; + + new GuiStackControl() { + internalName = "nodeHints"; + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 24"; + Extent = "184 0"; + MinExtent = "8 -500"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "2"; + }; + }; + + new GuiRolloutCtrl() { + Profile = "GuiShapeEdRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 26"; + Extent = "184 24"; + MinExtent = "8 -500"; + Caption = "Sequences"; + Margin = "2 2 2 2"; + Expanded = "0"; + + new GuiStackControl() { + internalName = "sequenceHints"; + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "184 24"; + MinExtent = "8 -500"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "2"; + }; + }; + }; + }; + new GuiTextCtrl(){ + Position = "5 5"; + Extent = "60 16"; + text = "Shape Type"; + }; + new GuiPopUpMenuCtrl(ShapeEdHintMenu) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "66 4"; + Extent = "132 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "art"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + }; + }; + + // Force load DAEs + new GuiCheckBoxCtrl() { + Profile = "GuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "135 27"; + Extent = "72 13"; + Variable = "EWorldEditor.forceLoadDAE"; + Command = "EWorldEditor.forceLoadDAE = $ThisControl.getValue(); EditorSettings.setValue(\"forceLoadDAE\", EWorldEditor.forceLoadDAE);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Forces loading of DAE files (ignores cached.dts if present)"; + hovertime = "1000"; + text = " Force DAE"; + }; + + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/shapeEditor/images/back_btn_d.png b/Templates/Empty/game/tools/shapeEditor/images/back_btn_d.png new file mode 100644 index 000000000..41a33f548 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/back_btn_d.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/back_btn_h.png b/Templates/Empty/game/tools/shapeEditor/images/back_btn_h.png new file mode 100644 index 000000000..ce9a266c5 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/back_btn_h.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/back_btn_n.png b/Templates/Empty/game/tools/shapeEditor/images/back_btn_n.png new file mode 100644 index 000000000..5daf81682 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/back_btn_n.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/collision-shape_d.png b/Templates/Empty/game/tools/shapeEditor/images/collision-shape_d.png new file mode 100644 index 000000000..83969b176 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/collision-shape_d.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/collision-shape_h.png b/Templates/Empty/game/tools/shapeEditor/images/collision-shape_h.png new file mode 100644 index 000000000..378c734e8 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/collision-shape_h.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/collision-shape_n.png b/Templates/Empty/game/tools/shapeEditor/images/collision-shape_n.png new file mode 100644 index 000000000..743bc4091 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/collision-shape_n.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/detail-levels_btn_d.png b/Templates/Empty/game/tools/shapeEditor/images/detail-levels_btn_d.png new file mode 100644 index 000000000..4bfa56aa3 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/detail-levels_btn_d.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/detail-levels_btn_h.png b/Templates/Empty/game/tools/shapeEditor/images/detail-levels_btn_h.png new file mode 100644 index 000000000..8ca5a0b1c Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/detail-levels_btn_h.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/detail-levels_btn_n.png b/Templates/Empty/game/tools/shapeEditor/images/detail-levels_btn_n.png new file mode 100644 index 000000000..f7788fb21 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/detail-levels_btn_n.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/fwd_btn_d.png b/Templates/Empty/game/tools/shapeEditor/images/fwd_btn_d.png new file mode 100644 index 000000000..0dd59b856 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/fwd_btn_d.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/fwd_btn_h.png b/Templates/Empty/game/tools/shapeEditor/images/fwd_btn_h.png new file mode 100644 index 000000000..65147daa6 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/fwd_btn_h.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/fwd_btn_n.png b/Templates/Empty/game/tools/shapeEditor/images/fwd_btn_n.png new file mode 100644 index 000000000..ba5f67aab Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/fwd_btn_n.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/ghost_btn_d.png b/Templates/Empty/game/tools/shapeEditor/images/ghost_btn_d.png new file mode 100644 index 000000000..ce7522ebf Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/ghost_btn_d.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/ghost_btn_h.png b/Templates/Empty/game/tools/shapeEditor/images/ghost_btn_h.png new file mode 100644 index 000000000..efc103ef8 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/ghost_btn_h.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/ghost_btn_n.png b/Templates/Empty/game/tools/shapeEditor/images/ghost_btn_n.png new file mode 100644 index 000000000..79d2cebf7 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/ghost_btn_n.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/highlight_material.png b/Templates/Empty/game/tools/shapeEditor/images/highlight_material.png new file mode 100644 index 000000000..78ac974a3 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/highlight_material.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/object-bounds_d.png b/Templates/Empty/game/tools/shapeEditor/images/object-bounds_d.png new file mode 100644 index 000000000..98253e586 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/object-bounds_d.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/object-bounds_h.png b/Templates/Empty/game/tools/shapeEditor/images/object-bounds_h.png new file mode 100644 index 000000000..aa41d5ac7 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/object-bounds_h.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/object-bounds_n.png b/Templates/Empty/game/tools/shapeEditor/images/object-bounds_n.png new file mode 100644 index 000000000..3bd3633e8 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/object-bounds_n.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/object-fit-bounds_d.png b/Templates/Empty/game/tools/shapeEditor/images/object-fit-bounds_d.png new file mode 100644 index 000000000..8071e25b5 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/object-fit-bounds_d.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/object-fit-bounds_h.png b/Templates/Empty/game/tools/shapeEditor/images/object-fit-bounds_h.png new file mode 100644 index 000000000..a0a4cd3bc Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/object-fit-bounds_h.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/object-fit-bounds_n.png b/Templates/Empty/game/tools/shapeEditor/images/object-fit-bounds_n.png new file mode 100644 index 000000000..aaaed8e10 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/object-fit-bounds_n.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/pause_btn_d.png b/Templates/Empty/game/tools/shapeEditor/images/pause_btn_d.png new file mode 100644 index 000000000..3caa5f8f8 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/pause_btn_d.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/pause_btn_h.png b/Templates/Empty/game/tools/shapeEditor/images/pause_btn_h.png new file mode 100644 index 000000000..361275542 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/pause_btn_h.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/pause_btn_n.png b/Templates/Empty/game/tools/shapeEditor/images/pause_btn_n.png new file mode 100644 index 000000000..d9a398521 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/pause_btn_n.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/pingpong_btn_d.png b/Templates/Empty/game/tools/shapeEditor/images/pingpong_btn_d.png new file mode 100644 index 000000000..3d26cabb7 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/pingpong_btn_d.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/pingpong_btn_h.png b/Templates/Empty/game/tools/shapeEditor/images/pingpong_btn_h.png new file mode 100644 index 000000000..ecdf5a3c0 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/pingpong_btn_h.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/pingpong_btn_n.png b/Templates/Empty/game/tools/shapeEditor/images/pingpong_btn_n.png new file mode 100644 index 000000000..60a9c1548 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/pingpong_btn_n.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/playbkwd_btn_d.png b/Templates/Empty/game/tools/shapeEditor/images/playbkwd_btn_d.png new file mode 100644 index 000000000..ef0e45000 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/playbkwd_btn_d.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/playbkwd_btn_h.png b/Templates/Empty/game/tools/shapeEditor/images/playbkwd_btn_h.png new file mode 100644 index 000000000..73837b5d5 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/playbkwd_btn_h.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/playbkwd_btn_n.png b/Templates/Empty/game/tools/shapeEditor/images/playbkwd_btn_n.png new file mode 100644 index 000000000..6e5f277bc Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/playbkwd_btn_n.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/playfwd_btn_d.png b/Templates/Empty/game/tools/shapeEditor/images/playfwd_btn_d.png new file mode 100644 index 000000000..835e3f6fa Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/playfwd_btn_d.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/playfwd_btn_h.png b/Templates/Empty/game/tools/shapeEditor/images/playfwd_btn_h.png new file mode 100644 index 000000000..87543b362 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/playfwd_btn_h.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/playfwd_btn_n.png b/Templates/Empty/game/tools/shapeEditor/images/playfwd_btn_n.png new file mode 100644 index 000000000..7fadf843d Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/playfwd_btn_n.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/seq_bar-in_d.png b/Templates/Empty/game/tools/shapeEditor/images/seq_bar-in_d.png new file mode 100644 index 000000000..dedef925e Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/seq_bar-in_d.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/seq_bar-in_h.png b/Templates/Empty/game/tools/shapeEditor/images/seq_bar-in_h.png new file mode 100644 index 000000000..c443af280 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/seq_bar-in_h.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/seq_bar-in_n.png b/Templates/Empty/game/tools/shapeEditor/images/seq_bar-in_n.png new file mode 100644 index 000000000..cf5091875 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/seq_bar-in_n.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/seq_bar-out_d.png b/Templates/Empty/game/tools/shapeEditor/images/seq_bar-out_d.png new file mode 100644 index 000000000..540f5a9b1 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/seq_bar-out_d.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/seq_bar-out_h.png b/Templates/Empty/game/tools/shapeEditor/images/seq_bar-out_h.png new file mode 100644 index 000000000..2feb3bfb6 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/seq_bar-out_h.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/seq_bar-out_n.png b/Templates/Empty/game/tools/shapeEditor/images/seq_bar-out_n.png new file mode 100644 index 000000000..cac5d5b54 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/seq_bar-out_n.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/show-wireframe_d.png b/Templates/Empty/game/tools/shapeEditor/images/show-wireframe_d.png new file mode 100644 index 000000000..6f94d00d4 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/show-wireframe_d.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/show-wireframe_h.png b/Templates/Empty/game/tools/shapeEditor/images/show-wireframe_h.png new file mode 100644 index 000000000..d88297ec2 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/show-wireframe_h.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/show-wireframe_n.png b/Templates/Empty/game/tools/shapeEditor/images/show-wireframe_n.png new file mode 100644 index 000000000..bab4eb253 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/show-wireframe_n.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/shownodes_btn_d.png b/Templates/Empty/game/tools/shapeEditor/images/shownodes_btn_d.png new file mode 100644 index 000000000..a9a358d46 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/shownodes_btn_d.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/shownodes_btn_h.png b/Templates/Empty/game/tools/shapeEditor/images/shownodes_btn_h.png new file mode 100644 index 000000000..6958e6ab8 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/shownodes_btn_h.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/shownodes_btn_n.png b/Templates/Empty/game/tools/shapeEditor/images/shownodes_btn_n.png new file mode 100644 index 000000000..599deaba4 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/shownodes_btn_n.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/stepback_btn_d.png b/Templates/Empty/game/tools/shapeEditor/images/stepback_btn_d.png new file mode 100644 index 000000000..e4c0fb52a Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/stepback_btn_d.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/stepback_btn_h.png b/Templates/Empty/game/tools/shapeEditor/images/stepback_btn_h.png new file mode 100644 index 000000000..46fbd79fa Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/stepback_btn_h.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/stepback_btn_n.png b/Templates/Empty/game/tools/shapeEditor/images/stepback_btn_n.png new file mode 100644 index 000000000..f0c114002 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/stepback_btn_n.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/stepfwd_btn_d.png b/Templates/Empty/game/tools/shapeEditor/images/stepfwd_btn_d.png new file mode 100644 index 000000000..f0160a16a Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/stepfwd_btn_d.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/stepfwd_btn_h.png b/Templates/Empty/game/tools/shapeEditor/images/stepfwd_btn_h.png new file mode 100644 index 000000000..4513970b5 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/stepfwd_btn_h.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/stepfwd_btn_n.png b/Templates/Empty/game/tools/shapeEditor/images/stepfwd_btn_n.png new file mode 100644 index 000000000..eb98eb498 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/stepfwd_btn_n.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/sun-btn_d.png b/Templates/Empty/game/tools/shapeEditor/images/sun-btn_d.png new file mode 100644 index 000000000..c357d6889 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/sun-btn_d.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/sun-btn_h.png b/Templates/Empty/game/tools/shapeEditor/images/sun-btn_h.png new file mode 100644 index 000000000..813b0a7b6 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/sun-btn_h.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/sun-btn_n.png b/Templates/Empty/game/tools/shapeEditor/images/sun-btn_n.png new file mode 100644 index 000000000..70152a8be Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/sun-btn_n.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/transition_slider.png b/Templates/Empty/game/tools/shapeEditor/images/transition_slider.png new file mode 100644 index 000000000..9aa51ab50 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/transition_slider.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/images/trigger_marker.png b/Templates/Empty/game/tools/shapeEditor/images/trigger_marker.png new file mode 100644 index 000000000..ea7dab994 Binary files /dev/null and b/Templates/Empty/game/tools/shapeEditor/images/trigger_marker.png differ diff --git a/Templates/Empty/game/tools/shapeEditor/main.cs b/Templates/Empty/game/tools/shapeEditor/main.cs new file mode 100644 index 000000000..f033bae86 --- /dev/null +++ b/Templates/Empty/game/tools/shapeEditor/main.cs @@ -0,0 +1,420 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +// Shape Editor +//------------------------------------------------------------------------------ + +function initializeShapeEditor() +{ + echo(" % - Initializing Shape Editor"); + + exec("./gui/Profiles.ed.cs"); + + exec("./gui/shapeEdPreviewWindow.ed.gui"); + exec("./gui/shapeEdAnimWindow.ed.gui"); + exec("./gui/shapeEdAdvancedWindow.ed.gui"); + exec("./gui/shapeEditorToolbar.ed.gui"); + exec("./gui/shapeEdSelectWindow.ed.gui"); + exec("./gui/shapeEdPropWindow.ed.gui"); + + exec("./scripts/shapeEditor.ed.cs"); + exec("./scripts/shapeEditorHints.ed.cs"); + exec("./scripts/shapeEditorActions.ed.cs"); + + // Add windows to editor gui + ShapeEdPreviewGui.setVisible(false); + ShapeEdAnimWindow.setVisible(false); + + ShapeEditorToolbar.setVisible(false); + ShapeEdSelectWindow.setVisible(false); + ShapeEdPropWindow.setVisible(false); + + EditorGui.add(ShapeEdPreviewGui); + EditorGui.add(ShapeEdAnimWindow); + EditorGui.add(ShapeEdAdvancedWindow); + + EditorGui.add(ShapeEditorToolbar); + EditorGui.add(ShapeEdSelectWindow); + EditorGui.add(ShapeEdPropWindow); + + new ScriptObject(ShapeEditorPlugin) + { + superClass = "EditorPlugin"; + editorGui = ShapeEdShapeView; + }; + + %map = new ActionMap(); + %map.bindCmd( keyboard, "escape", "ToolsToolbarArray->WorldEditorInspectorPalette.performClick();", "" ); + %map.bindCmd( keyboard, "1", "ShapeEditorNoneModeBtn.performClick();", "" ); + %map.bindCmd( keyboard, "2", "ShapeEditorMoveModeBtn.performClick();", "" ); + %map.bindCmd( keyboard, "3", "ShapeEditorRotateModeBtn.performClick();", "" ); + //%map.bindCmd( keyboard, "4", "ShapeEditorScaleModeBtn.performClick();", "" ); // not needed for the shape editor + %map.bindCmd( keyboard, "n", "ShapeEditorToolbar->showNodes.performClick();", "" ); + %map.bindCmd( keyboard, "t", "ShapeEditorToolbar->ghostMode.performClick();", "" ); + %map.bindCmd( keyboard, "r", "ShapeEditorToolbar->wireframeMode.performClick();", "" ); + %map.bindCmd( keyboard, "f", "ShapeEditorToolbar->fitToShapeBtn.performClick();", "" ); + %map.bindCmd( keyboard, "g", "ShapeEditorToolbar->showGridBtn.performClick();", "" ); + %map.bindCmd( keyboard, "h", "ShapeEdSelectWindow->tabBook.selectPage( 2 );", "" ); // Load help tab + %map.bindCmd( keyboard, "l", "ShapeEdSelectWindow->tabBook.selectPage( 1 );", "" ); // load Library Tab + %map.bindCmd( keyboard, "j", "ShapeEdSelectWindow->tabBook.selectPage( 0 );", "" ); // load scene object Tab + %map.bindCmd( keyboard, "SPACE", "ShapeEdAnimWindow.togglePause();", "" ); + %map.bindCmd( keyboard, "i", "ShapeEdSequences.onEditSeqInOut(\"in\", ShapeEdSeqSlider.getValue());", "" ); + %map.bindCmd( keyboard, "o", "ShapeEdSequences.onEditSeqInOut(\"out\", ShapeEdSeqSlider.getValue());", "" ); + %map.bindCmd( keyboard, "shift -", "ShapeEdSeqSlider.setValue(ShapeEdAnimWindow-->seqIn.getText());", "" ); + %map.bindCmd( keyboard, "shift =", "ShapeEdSeqSlider.setValue(ShapeEdAnimWindow-->seqOut.getText());", "" ); + %map.bindCmd( keyboard, "=", "ShapeEdAnimWindow-->stepFwdBtn.performClick();", "" ); + %map.bindCmd( keyboard, "-", "ShapeEdAnimWindow-->stepBkwdBtn.performClick();", "" ); + + ShapeEditorPlugin.map = %map; + + ShapeEditorPlugin.initSettings(); +} + +function destroyShapeEditor() +{ +} + +function SetToggleButtonValue(%ctrl, %value) +{ + if ( %ctrl.getValue() != %value ) + %ctrl.performClick(); +} + +// Replace the command field in an Editor PopupMenu item (returns the original value) +function ShapeEditorPlugin::replaceMenuCmd(%this, %menuTitle, %id, %newCmd) +{ + %menu = EditorGui.findMenu( %menuTitle ); + %cmd = getField( %menu.item[%id], 2 ); + %menu.setItemCommand( %id, %newCmd ); + + return %cmd; +} + +function ShapeEditorPlugin::onWorldEditorStartup(%this) +{ + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu("Shape Editor", "", ShapeEditorPlugin); + + // Add ourselves to the ToolsToolbar + %tooltip = "Shape Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "ShapeEditorPlugin", "ShapeEditorPalette", expandFilename("tools/worldEditor/images/toolbar/shape-editor"), %tooltip ); + + // Add ourselves to the Editor Settings window + exec( "./gui/ShapeEditorSettingsTab.gui" ); + ESettingsWindow.addTabPage( EShapeEditorSettingsPage ); + + GuiWindowCtrl::attach(ShapeEdPropWindow, ShapeEdSelectWindow); + ShapeEdAnimWindow.resize( -1, 526, 593, 53 ); + + // Initialise gui + ShapeEdSeqNodeTabBook.selectPage(0); + ShapeEdAdvancedWindow-->tabBook.selectPage(0); + ShapeEdSelectWindow-->tabBook.selectPage(0); + ShapeEdSelectWindow.navigate(""); + + SetToggleButtonValue( ShapeEditorToolbar-->orbitNodeBtn, 0 ); + SetToggleButtonValue( ShapeEditorToolbar-->ghostMode, 0 ); + + // Initialise hints menu + ShapeEdHintMenu.clear(); + %count = ShapeHintGroup.getCount(); + for (%i = 0; %i < %count; %i++) + { + %hint = ShapeHintGroup.getObject(%i); + ShapeEdHintMenu.add(%hint.objectType, %hint); + } +} + +function ShapeEditorPlugin::open(%this, %filename) +{ + if ( !%this.isActivated ) + { + // Activate the Shape Editor + EditorGui.setEditor( %this, true ); + + // Get editor settings (note the sun angle is not configured in the settings + // dialog, so apply the settings here instead of in readSettings) + %this.readSettings(); + ShapeEdShapeView.sunAngleX = EditorSettings.value("ShapeEditor/SunAngleX"); + ShapeEdShapeView.sunAngleZ = EditorSettings.value("ShapeEditor/SunAngleZ"); + EWorldEditor.forceLoadDAE = EditorSettings.value("forceLoadDAE"); + + $wasInWireFrameMode = $gfx::wireframe; + ShapeEditorToolbar-->wireframeMode.setStateOn($gfx::wireframe); + + if ( GlobalGizmoProfile.getFieldValue(alignment) $= "Object" ) + ShapeEdNodes-->objectTransform.setStateOn(1); + else + ShapeEdNodes-->worldTransform.setStateOn(1); + + // Initialise and show the shape editor + ShapeEdShapeTreeView.open(MissionGroup); + ShapeEdShapeTreeView.buildVisibleTree(true); + + ShapeEdPreviewGui.setVisible(true); + ShapeEdSelectWindow.setVisible(true); + ShapeEdPropWindow.setVisible(true); + ShapeEdAnimWindow.setVisible(true); + ShapeEdAdvancedWindow.setVisible(ShapeEditorToolbar-->showAdvanced.getValue()); + ShapeEditorToolbar.setVisible(true); + EditorGui.bringToFront(ShapeEdPreviewGui); + + ToolsPaletteArray->WorldEditorMove.performClick(); + %this.map.push(); + + // Switch to the ShapeEditor UndoManager + %this.oldUndoMgr = Editor.getUndoManager(); + Editor.setUndoManager( ShapeEdUndoManager ); + + ShapeEdShapeView.setDisplayType( EditorGui.currentDisplayType ); + %this.initStatusBar(); + + // Customise menu bar + %this.oldCamFitCmd = %this.replaceMenuCmd( "Camera", 8, "ShapeEdShapeView.fitToShape();" ); + %this.oldCamFitOrbitCmd = %this.replaceMenuCmd( "Camera", 9, "ShapeEdShapeView.fitToShape();" ); + + Parent::onActivated(%this); + } + + // Select the new shape + if (isObject(ShapeEditor.shape) && (ShapeEditor.shape.baseShape $= %filename)) + { + // Shape is already selected => re-highlight the selected material if necessary + ShapeEdMaterials.updateSelectedMaterial(ShapeEdMaterials-->highlightMaterial.getValue()); + } + else if (%filename !$= "") + { + ShapeEditor.selectShape(%filename, ShapeEditor.isDirty()); + + // 'fitToShape' only works after the GUI has been rendered, so force a repaint first + Canvas.repaint(); + ShapeEdShapeView.fitToShape(); + } +} + +function ShapeEditorPlugin::onActivated(%this) +{ + %this.open(""); + + // Try to start with the shape selected in the world editor + %count = EWorldEditor.getSelectionSize(); + for (%i = 0; %i < %count; %i++) + { + %obj = EWorldEditor.getSelectedObject(%i); + %shapeFile = ShapeEditor.getObjectShapeFile(%obj); + if (%shapeFile !$= "") + { + if (!isObject(ShapeEditor.shape) || (ShapeEditor.shape.baseShape !$= %shapeFile)) + { + // Call the 'onSelect' method directly if the object is not in the + // MissionGroup tree (such as a Player or Projectile object). + ShapeEdShapeTreeView.clearSelection(); + if (!ShapeEdShapeTreeView.selectItem(%obj)) + ShapeEdShapeTreeView.onSelect(%obj); + + // 'fitToShape' only works after the GUI has been rendered, so force a repaint first + Canvas.repaint(); + ShapeEdShapeView.fitToShape(); + } + break; + } + } +} + +function ShapeEditorPlugin::initStatusBar(%this) +{ + EditorGuiStatusBar.setInfo("Shape editor ( Shift Click ) to speed up camera."); + EditorGuiStatusBar.setSelection( ShapeEditor.shape.baseShape ); +} + +function ShapeEditorPlugin::onDeactivated(%this) +{ + %this.writeSettings(); + + // Notify game objects if shape has been modified + if ( ShapeEditor.isDirty() ) + ShapeEditor.shape.notifyShapeChanged(); + + $gfx::wireframe = $wasInWireFrameMode; + + ShapeEdMaterials.updateSelectedMaterial(false); + ShapeEditorToolbar.setVisible(false); + + ShapeEdPreviewGui.setVisible(false); + ShapeEdSelectWindow.setVisible(false); + ShapeEdPropWindow.setVisible(false); + ShapeEdAnimWindow.setVisible(false); + ShapeEdAdvancedWindow.setVisible(false); + + if( EditorGui-->MatEdPropertiesWindow.visible ) + { + ShapeEdMaterials.editSelectedMaterialEnd( true ); + } + + %this.map.pop(); + + // Restore the original undo manager + Editor.setUndoManager( %this.oldUndoMgr ); + + // Restore menu bar + %this.replaceMenuCmd( "Camera", 8, %this.oldCamFitCmd ); + %this.replaceMenuCmd( "Camera", 9, %this.oldCamFitOrbitCmd ); + + Parent::onDeactivated(%this); +} + +function ShapeEditorPlugin::onExitMission( %this ) +{ + // unselect the current shape + ShapeEdShapeView.setModel( "" ); + if (ShapeEditor.shape != -1) + ShapeEditor.shape.delete(); + ShapeEditor.shape = 0; + ShapeEdUndoManager.clearAll(); + ShapeEditor.setDirty( false ); + + ShapeEdSequenceList.clear(); + ShapeEdNodeTreeView.removeItem( 0 ); + ShapeEdPropWindow.update_onNodeSelectionChanged( -1 ); + ShapeEdDetailTree.removeItem( 0 ); + ShapeEdMaterialList.clear(); + + ShapeEdMountWindow-->mountList.clear(); + ShapeEdThreadWindow-->seqList.clear(); + ShapeEdThreadList.clear(); +} + +function ShapeEditorPlugin::openShape( %this, %path, %discardChangesToCurrent ) +{ + EditorGui.setEditor( ShapeEditorPlugin ); + + if( ShapeEditor.isDirty() && !%discardChangesToCurrent ) + { + MessageBoxYesNo( "Save Changes?", + "Save changes to current shape?", + "ShapeEditor.saveChanges(); ShapeEditorPlugin.openShape(\"" @ %path @ "\");", + "ShapeEditorPlugin.openShape(\"" @ %path @ "\");" ); + return; + } + + ShapeEditor.selectShape( %path ); + ShapeEdShapeView.fitToShape(); +} + +function shapeEditorWireframeMode() +{ + $gfx::wireframe = !$gfx::wireframe; + ShapeEditorToolbar-->wireframeMode.setStateOn($gfx::wireframe); +} + +//----------------------------------------------------------------------------- +// Settings +//----------------------------------------------------------------------------- + +function ShapeEditorPlugin::initSettings( %this ) +{ + EditorSettings.beginGroup( "ShapeEditor", true ); + + // Display options + EditorSettings.setDefaultValue( "BackgroundColor", "0 0 0 100" ); + EditorSettings.setDefaultValue( "HighlightMaterial", 1 ); + EditorSettings.setDefaultValue( "ShowNodes", 1 ); + EditorSettings.setDefaultValue( "ShowBounds", 0 ); + EditorSettings.setDefaultValue( "ShowObjBox", 1 ); + EditorSettings.setDefaultValue( "RenderMounts", 1 ); + EditorSettings.setDefaultValue( "RenderCollision", 0 ); + + // Grid + EditorSettings.setDefaultValue( "ShowGrid", 1 ); + EditorSettings.setDefaultValue( "GridSize", 0.1 ); + EditorSettings.setDefaultValue( "GridDimension", "40 40" ); + + // Sun + EditorSettings.setDefaultValue( "SunDiffuseColor", "255 255 255 255" ); + EditorSettings.setDefaultValue( "SunAmbientColor", "180 180 180 255" ); + EditorSettings.setDefaultValue( "SunAngleX", "45" ); + EditorSettings.setDefaultValue( "SunAngleZ", "135" ); + + // Sub-windows + EditorSettings.setDefaultValue( "AdvancedWndVisible", "1" ); + + EditorSettings.endGroup(); +} + +function ShapeEditorPlugin::readSettings( %this ) +{ + EditorSettings.beginGroup( "ShapeEditor", true ); + + // Display options + ShapeEdPreviewGui-->previewBackground.color = ColorIntToFloat( EditorSettings.value("BackgroundColor") ); + SetToggleButtonValue( ShapeEdMaterials-->highlightMaterial, EditorSettings.value( "HighlightMaterial" ) ); + SetToggleButtonValue( ShapeEditorToolbar-->showNodes, EditorSettings.value( "ShowNodes" ) ); + SetToggleButtonValue( ShapeEditorToolbar-->showBounds, EditorSettings.value( "ShowBounds" ) ); + SetToggleButtonValue( ShapeEditorToolbar-->showObjBox, EditorSettings.value( "ShowObjBox" ) ); + SetToggleButtonValue( ShapeEditorToolbar-->renderColMeshes, EditorSettings.value( "RenderCollision" ) ); + SetToggleButtonValue( ShapeEdMountWindow-->renderMounts, EditorSettings.value( "RenderMounts" ) ); + + // Grid + SetToggleButtonValue( ShapeEditorToolbar-->showGridBtn, EditorSettings.value( "ShowGrid" ) ); + ShapeEdShapeView.gridSize = EditorSettings.value( "GridSize" ); + ShapeEdShapeView.gridDimension = EditorSettings.value( "GridDimension" ); + + // Sun + ShapeEdShapeView.sunDiffuse = EditorSettings.value("SunDiffuseColor"); + ShapeEdShapeView.sunAmbient = EditorSettings.value("SunAmbientColor"); + + // Sub-windows + SetToggleButtonValue( ShapeEditorToolbar-->showAdvanced, EditorSettings.value( "AdvancedWndVisible" ) ); + + EditorSettings.endGroup(); +} + +function ShapeEditorPlugin::writeSettings( %this ) +{ + EditorSettings.beginGroup( "ShapeEditor", true ); + + // Display options + EditorSettings.setValue( "BackgroundColor", ColorFloatToInt( ShapeEdPreviewGui-->previewBackground.color ) ); + EditorSettings.setValue( "HighlightMaterial", ShapeEdMaterials-->highlightMaterial.getValue() ); + EditorSettings.setValue( "ShowNodes", ShapeEditorToolbar-->showNodes.getValue() ); + EditorSettings.setValue( "ShowBounds", ShapeEditorToolbar-->showBounds.getValue() ); + EditorSettings.setValue( "ShowObjBox", ShapeEditorToolbar-->showObjBox.getValue() ); + EditorSettings.setValue( "RenderCollision", ShapeEditorToolbar-->renderColMeshes.getValue() ); + EditorSettings.setValue( "RenderMounts", ShapeEdMountWindow-->renderMounts.getValue() ); + + // Grid + EditorSettings.setValue( "ShowGrid", ShapeEditorToolbar-->showGridBtn.getValue() ); + EditorSettings.setValue( "GridSize", ShapeEdShapeView.gridSize ); + EditorSettings.setValue( "GridDimension", ShapeEdShapeView.gridDimension ); + + // Sun + EditorSettings.setValue( "SunDiffuseColor", ShapeEdShapeView.sunDiffuse ); + EditorSettings.setValue( "SunAmbientColor", ShapeEdShapeView.sunAmbient ); + EditorSettings.setValue( "SunAngleX", ShapeEdShapeView.sunAngleX ); + EditorSettings.setValue( "SunAngleZ", ShapeEdShapeView.sunAngleZ ); + + // Sub-windows + EditorSettings.setValue( "AdvancedWndVisible", ShapeEditorToolbar-->showAdvanced.getValue() ); + + EditorSettings.endGroup(); +} diff --git a/Templates/Empty/game/tools/shapeEditor/scripts/shapeEditor.ed.cs b/Templates/Empty/game/tools/shapeEditor/scripts/shapeEditor.ed.cs new file mode 100644 index 000000000..72ece66b9 --- /dev/null +++ b/Templates/Empty/game/tools/shapeEditor/scripts/shapeEditor.ed.cs @@ -0,0 +1,3386 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// @todo: +// +// - split node transform editboxes into X Y Z and rot X Y Z with spin controls +// to allow easier manual editing +// - add groundspeed editing ( use same format as node transform editing ) +// +// Known bugs/limitations: +// +// - resizing the GuiTextListCtrl should resize the columns as well +// - modifying the from/in/out properties of a sequence will change the sequence +// order in the shape ( since it results in remove/add sequence commands ) +// - deleting a node should not delete its children as well? +// + +//------------------------------------------------------------------------------ +// Utility Methods +//------------------------------------------------------------------------------ + +if ( !isObject( ShapeEditor ) ) new ScriptObject( ShapeEditor ) +{ + shape = -1; + deletedCount = 0; +}; + + +// Capitalise the first letter of the input string +function strcapitalise( %str ) +{ + %len = strlen( %str ); + return strupr( getSubStr( %str,0,1 ) ) @ getSubStr( %str,1,%len-1 ); +} + +function ShapeEditor::getObjectShapeFile( %this, %obj ) +{ + // Get the path to the shape file used by the given object (not perfect, but + // works for the vast majority of object types) + %path = ""; + if ( %obj.isMemberOfClass( "TSStatic" ) ) + %path = %obj.shapeName; + else if ( %obj.isMemberOfClass( "PhysicsShape" ) ) + %path = %obj.getDataBlock().shapeName; + else if ( %obj.isMemberOfClass( "GameBase" ) ) + %path = %obj.getDataBlock().shapeFile; + + return %path; +} + +// Check if the given name already exists +function ShapeEditor::nameExists( %this, %type, %name ) +{ + if ( ShapeEditor.shape == -1 ) + return false; + + if ( %type $= "node" ) + return ( ShapeEditor.shape.getNodeIndex( %name ) >= 0 ); + else if ( %type $= "sequence" ) + return ( ShapeEditor.shape.getSequenceIndex( %name ) >= 0 ); + else if ( %type $= "object" ) + return ( ShapeEditor.shape.getObjectIndex( %name ) >= 0 ); +} + +// Check if the given 'hint' name exists (spaces could also be underscores) +function ShapeEditor::hintNameExists( %this, %type, %name ) +{ + if ( ShapeEditor.nameExists( %type, %name ) ) + return true; + + // If the name contains spaces, try replacing with underscores + %name = strreplace( %name, " ", "_" ); + if ( ShapeEditor.nameExists( %type, %name ) ) + return true; + + return false; +} + +// Generate a unique name from a given base by appending an integer +function ShapeEditor::getUniqueName( %this, %type, %name ) +{ + for ( %idx = 1; %idx < 100; %idx++ ) + { + %uniqueName = %name @ %idx; + if ( !%this.nameExists( %type, %uniqueName ) ) + break; + } + + return %uniqueName; +} + +function ShapeEditor::getProxyName( %this, %seqName ) +{ + return "__proxy__" @ %seqName; +} + +function ShapeEditor::getUnproxyName( %this, %proxyName ) +{ + return strreplace( %proxyName, "__proxy__", "" ); +} + +function ShapeEditor::getBackupName( %this, %seqName ) +{ + return "__backup__" @ %seqName; +} + +// Check if this mesh name is a collision hint +function ShapeEditor::isCollisionMesh( %this, %name ) +{ + return ( startswith( %name, "ColBox" ) || + startswith( %name, "ColSphere" ) || + startswith( %name, "ColCapsule" ) || + startswith( %name, "ColConvex" ) ); +} + +// +function ShapeEditor::getSequenceSource( %this, %seqName ) +{ + %source = %this.shape.getSequenceSource( %seqName ); + + // Use the sequence name as the source for DTS built-in sequences + %src0 = getField( %source, 0 ); + %src1 = getField( %source, 1 ); + if ( %src0 $= %src1 ) + %source = setField( %source, 1, "" ); + if ( %src0 $= "" ) + %source = setField( %source, 0, %seqName ); + + return %source; +} + +// Recursively get names for a node and its children +function ShapeEditor::getNodeNames( %this, %nodeName, %names, %exclude ) +{ + if ( %nodeName $= %exclude ) + return %names; + + %count = %this.shape.getNodeChildCount( %nodeName ); + for ( %i = 0; %i < %count; %i++ ) + { + %childName = %this.shape.getNodeChildName( %nodeName, %i ); + %names = %this.getNodeNames( %childName, %names, %exclude ); + } + + %names = %names TAB %nodeName; + + return trim( %names ); +} + +// Get the list of meshes for a particular object +function ShapeEditor::getObjectMeshList( %this, %name ) +{ + %list = ""; + %count = %this.shape.getMeshCount( %name ); + for ( %i = 0; %i < %count; %i++ ) + %list = %list TAB %this.shape.getMeshName( %name, %i ); + return trim( %list ); +} + +// Get the list of meshes for a particular detail level +function ShapeEditor::getDetailMeshList( %this, %detSize ) +{ + %list = ""; + %objCount = ShapeEditor.shape.getObjectCount(); + for ( %i = 0; %i < %objCount; %i++ ) + { + %objName = ShapeEditor.shape.getObjectName( %i ); + %meshCount = ShapeEditor.shape.getMeshCount( %objName ); + for ( %j = 0; %j < %meshCount; %j++ ) + { + %size = ShapeEditor.shape.getMeshSize( %objName, %j ); + if ( %size == %detSize ) + %list = %list TAB %this.shape.getMeshName( %objName, %j ); + } + } + return trim( %list ); +} + +function ShapeEditor::isDirty( %this ) +{ + return ( isObject( %this.shape ) && ShapeEdPropWindow-->saveBtn.isActive() ); +} + +function ShapeEditor::setDirty( %this, %dirty ) +{ + if ( %dirty ) + ShapeEdSelectWindow.text = "Shapes *"; + else + ShapeEdSelectWindow.text = "Shapes"; + + ShapeEdPropWindow-->saveBtn.setActive( %dirty ); +} + +function ShapeEditor::saveChanges( %this ) +{ + if ( isObject( ShapeEditor.shape ) ) + { + ShapeEditor.saveConstructor( ShapeEditor.shape ); + ShapeEditor.shape.writeChangeSet(); + ShapeEditor.shape.notifyShapeChanged(); // Force game objects to reload shape + ShapeEditor.setDirty( false ); + } +} + +//------------------------------------------------------------------------------ +// Shape Selection +//------------------------------------------------------------------------------ + +function ShapeEditor::findConstructor( %this, %path ) +{ + %count = TSShapeConstructorGroup.getCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %obj = TSShapeConstructorGroup.getObject( %i ); + if ( %obj.baseShape $= %path ) + return %obj; + } + return -1; +} + +function ShapeEditor::createConstructor( %this, %path ) +{ + %name = strcapitalise( fileBase( %path ) ) @ strcapitalise( getSubStr( fileExt( %path ), 1, 3 ) ); + %name = strreplace( %name, "-", "_" ); + %name = strreplace( %name, ".", "_" ); + %name = getUniqueName( %name ); + return new TSShapeConstructor( %name ) { baseShape = %path; }; +} + +function ShapeEditor::saveConstructor( %this, %constructor ) +{ + %savepath = filePath( %constructor.baseShape ) @ "/" @ fileBase( %constructor.baseShape ) @ ".cs"; + new PersistenceManager( shapeEd_perMan ); + shapeEd_perMan.setDirty( %constructor, %savepath ); + shapeEd_perMan.saveDirtyObject( %constructor ); + shapeEd_perMan.delete(); +} + +// Handle a selection in the shape selector list +function ShapeEdSelectWindow::onSelect( %this, %path ) +{ + // Prompt user to save the old shape if it is dirty + if ( ShapeEditor.isDirty() ) + { + %cmd = "ColladaImportDlg.showDialog( \"" @ %path @ "\", \"ShapeEditor.selectShape( \\\"" @ %path @ "\\\", "; + MessageBoxYesNoCancel( "Shape Modified", "Would you like to save your changes?", %cmd @ "true );\" );", %cmd @ "false );\" );" ); + } + else + { + %cmd = "ShapeEditor.selectShape( \"" @ %path @ "\", false );"; + ColladaImportDlg.showDialog( %path, %cmd ); + } +} + +function ShapeEditor::selectShape( %this, %path, %saveOld ) +{ + ShapeEdShapeView.setModel( "" ); + + if ( %saveOld ) + { + // Save changes to a TSShapeConstructor script + %this.saveChanges(); + } + else if ( ShapeEditor.isDirty() ) + { + // Purge all unsaved changes + %oldPath = ShapeEditor.shape.baseShape; + ShapeEditor.shape.delete(); + ShapeEditor.shape = 0; + + reloadResource( %oldPath ); // Force game objects to reload shape + } + + // Initialise the shape preview window + if ( !ShapeEdShapeView.setModel( %path ) ) + { + MessageBoxOK( "Error", "Failed to load '" @ %path @ "'. Check the console for error messages." ); + return; + } + ShapeEdShapeView.fitToShape(); + + ShapeEdUndoManager.clearAll(); + ShapeEditor.setDirty( false ); + + // Get ( or create ) the TSShapeConstructor object for this shape + ShapeEditor.shape = ShapeEditor.findConstructor( %path ); + if ( ShapeEditor.shape <= 0 ) + { + ShapeEditor.shape = %this.createConstructor( %path ); + if ( ShapeEditor.shape <= 0 ) + { + error( "ShapeEditor: Error - could not select " @ %path ); + return; + } + } + + // Initialise the editor windows + ShapeEdAdvancedWindow.update_onShapeSelectionChanged(); + ShapeEdMountWindow.update_onShapeSelectionChanged(); + ShapeEdThreadWindow.update_onShapeSelectionChanged(); + ShapeEdColWindow.update_onShapeSelectionChanged(); + ShapeEdPropWindow.update_onShapeSelectionChanged(); + ShapeEdShapeView.refreshShape(); + + // Update object type hints + ShapeEdSelectWindow.updateHints(); + + // Update editor status bar + EditorGuiStatusBar.setSelection( %path ); +} + +// Handle a selection in the MissionGroup shape selector +function ShapeEdShapeTreeView::onSelect( %this, %obj ) +{ + %path = ShapeEditor.getObjectShapeFile( %obj ); + if ( %path !$= "" ) + ShapeEdSelectWindow.onSelect( %path ); + + // Set the object type (for required nodes and sequences display) + %objClass = %obj.getClassName(); + %hintId = -1; + + %count = ShapeHintGroup.getCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %hint = ShapeHintGroup.getObject( %i ); + if ( %objClass $= %hint.objectType ) + { + %hintId = %hint; + break; + } + else if ( isMemberOfClass( %objClass, %hint.objectType ) ) + { + %hintId = %hint; + } + } + ShapeEdHintMenu.setSelected( %hintId ); +} + +// Find all DTS or COLLADA models. Note: most of this section was shamelessly +// stolen from creater.ed.cs => great work whoever did the original! +function ShapeEdSelectWindow::navigate( %this, %address ) +{ + // Freeze the icon array so it doesn't update until we've added all of the + // icons + %this-->shapeLibrary.frozen = true; + %this-->shapeLibrary.clear(); + ShapeEdSelectMenu.clear(); + + %filePatterns = "*.dts" TAB "*.dae" TAB "*.kmz"; + %fullPath = findFirstFileMultiExpr( %filePatterns ); + + while ( %fullPath !$= "" ) + { + // Ignore cached DTS files + if ( endswith( %fullPath, "cached.dts" ) ) + { + %fullPath = findNextFileMultiExpr( %filePatterns ); + continue; + } + + // Ignore assets in the tools folder + %fullPath = makeRelativePath( %fullPath, getMainDotCSDir() ); + %splitPath = strreplace( %fullPath, "/", " " ); + if ( getWord( %splitPath, 0 ) $= "tools" ) + { + %fullPath = findNextFileMultiExpr( %filePatterns ); + continue; + } + + %dirCount = getWordCount( %splitPath ) - 1; + %pathFolders = getWords( %splitPath, 0, %dirCount - 1 ); + + // Add this file's path ( parent folders ) to the + // popup menu if it isn't there yet. + %temp = strreplace( %pathFolders, " ", "/" ); + %r = ShapeEdSelectMenu.findText( %temp ); + if ( %r == -1 ) + ShapeEdSelectMenu.add( %temp ); + + // Is this file in the current folder? + if ( stricmp( %pathFolders, %address ) == 0 ) + { + %this.addShapeIcon( %fullPath ); + } + // Then is this file in a subfolder we need to add + // a folder icon for? + else + { + %wordIdx = 0; + %add = false; + + if ( %address $= "" ) + { + %add = true; + %wordIdx = 0; + } + else + { + for ( ; %wordIdx < %dirCount; %wordIdx++ ) + { + %temp = getWords( %splitPath, 0, %wordIdx ); + if ( stricmp( %temp, %address ) == 0 ) + { + %add = true; + %wordIdx++; + break; + } + } + } + + if ( %add == true ) + { + %folder = getWord( %splitPath, %wordIdx ); + + // Add folder icon if not already present + %ctrl = %this.findIconCtrl( %folder ); + if ( %ctrl == -1 ) + %this.addFolderIcon( %folder ); + } + } + + %fullPath = findNextFileMultiExpr( %filePatterns ); + } + + %this-->shapeLibrary.sort( "alphaIconCompare" ); + for ( %i = 0; %i < %this-->shapeLibrary.getCount(); %i++ ) + %this-->shapeLibrary.getObject( %i ).autoSize = false; + + %this-->shapeLibrary.frozen = false; + %this-->shapeLibrary.refresh(); + %this.address = %address; + + ShapeEdSelectMenu.sort(); + + %str = strreplace( %address, " ", "/" ); + %r = ShapeEdSelectMenu.findText( %str ); + if ( %r != -1 ) + ShapeEdSelectMenu.setSelected( %r, false ); + else + ShapeEdSelectMenu.setText( %str ); +} + +function ShapeEdSelectWindow::navigateDown( %this, %folder ) +{ + if ( %this.address $= "" ) + %address = %folder; + else + %address = %this.address SPC %folder; + + // Because this is called from an IconButton::onClick command + // we have to wait a tick before actually calling navigate, else + // we would delete the button out from under itself. + %this.schedule( 1, "navigate", %address ); +} + +function ShapeEdSelectWindow::navigateUp( %this ) +{ + %count = getWordCount( %this.address ); + + if ( %count == 0 ) + return; + + if ( %count == 1 ) + %address = ""; + else + %address = getWords( %this.address, 0, %count - 2 ); + + %this.navigate( %address ); +} + +function ShapeEdSelectWindow::findIconCtrl( %this, %name ) +{ + for ( %i = 0; %i < %this-->shapeLibrary.getCount(); %i++ ) + { + %ctrl = %this-->shapeLibrary.getObject( %i ); + if ( %ctrl.text $= %name ) + return %ctrl; + } + return -1; +} + +function ShapeEdSelectWindow::createIcon( %this ) +{ + %ctrl = new GuiIconButtonCtrl() + { + profile = "GuiCreatorIconButtonProfile"; + iconLocation = "Left"; + textLocation = "Right"; + extent = "348 19"; + textMargin = 8; + buttonMargin = "2 2"; + autoSize = false; + sizeIconToButton = true; + makeIconSquare = true; + buttonType = "radioButton"; + groupNum = "-1"; + }; + + return %ctrl; +} + +function ShapeEdSelectWindow::addFolderIcon( %this, %text ) +{ + %ctrl = %this.createIcon(); + + %ctrl.altCommand = "ShapeEdSelectWindow.navigateDown( \"" @ %text @ "\" );"; + %ctrl.iconBitmap = "core/art/gui/images/folder.png"; + %ctrl.text = %text; + %ctrl.tooltip = %text; + %ctrl.class = "CreatorFolderIconBtn"; + + %ctrl.buttonType = "radioButton"; + %ctrl.groupNum = "-1"; + + %this-->shapeLibrary.addGuiControl( %ctrl ); +} + +function ShapeEdSelectWindow::addShapeIcon( %this, %fullPath ) +{ + %ctrl = %this.createIcon(); + + %ext = fileExt( %fullPath ); + %file = fileBase( %fullPath ); + %fileLong = %file @ %ext; + %tip = %fileLong NL + "Size: " @ fileSize( %fullPath ) / 1000.0 SPC "KB" NL + "Date Created: " @ fileCreatedTime( %fullPath ) NL + "Last Modified: " @ fileModifiedTime( %fullPath ); + + %ctrl.altCommand = "ShapeEdSelectWindow.onSelect( \"" @ %fullPath @ "\" );"; + %ctrl.iconBitmap = ( ( %ext $= ".dts" ) ? EditorIconRegistry::findIconByClassName( "TSStatic" ) : "tools/gui/images/iconCollada" ); + %ctrl.text = %file; + %ctrl.class = "CreatorStaticIconBtn"; + %ctrl.tooltip = %tip; + + %ctrl.buttonType = "radioButton"; + %ctrl.groupNum = "-1"; + + // Check if a shape specific icon is available + %formats = ".png .jpg .dds .bmp .gif .jng .tga"; + %count = getWordCount( %formats ); + for ( %i = 0; %i < %count; %i++ ) + { + %ext = getWord( %formats, %i ); + if ( isFile( %fullPath @ %ext ) ) + { + %ctrl.iconBitmap = %fullPath @ %ext; + break; + } + } + + %this-->shapeLibrary.addGuiControl( %ctrl ); +} + +function ShapeEdSelectMenu::onSelect( %this, %id, %text ) +{ + %split = strreplace( %text, "/", " " ); + ShapeEdSelectWindow.navigate( %split ); +} + +// Update the GUI in response to the shape selection changing +function ShapeEdPropWindow::update_onShapeSelectionChanged( %this ) +{ + // --- NODES TAB --- + ShapeEdNodeTreeView.removeItem( 0 ); + %rootId = ShapeEdNodeTreeView.insertItem( 0, "<root>", 0, "" ); + %count = ShapeEditor.shape.getNodeCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %name = ShapeEditor.shape.getNodeName( %i ); + if ( ShapeEditor.shape.getNodeParentName( %name ) $= "" ) + ShapeEdNodeTreeView.addNodeTree( %name ); + } + %this.update_onNodeSelectionChanged( -1 ); // no node selected + + // --- SEQUENCES TAB --- + ShapeEdSequenceList.clear(); + ShapeEdSequenceList.addRow( -1, "Name" TAB "Cyclic" TAB "Blend" TAB "Frames" TAB "Priority" ); + ShapeEdSequenceList.setRowActive( -1, false ); + ShapeEdSequenceList.addRow( 0, "<rootpose>" TAB "" TAB "" TAB "" TAB "" ); + + %count = ShapeEditor.shape.getSequenceCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %name = ShapeEditor.shape.getSequenceName( %i ); + + // Ignore __backup__ sequences (only used by editor) + if ( !startswith( %name, "__backup__" ) ) + ShapeEdSequenceList.addItem( %name ); + } + ShapeEdThreadWindow.onAddThread(); // add thread 0 + + // --- DETAILS TAB --- + // Add detail levels and meshes to tree + ShapeEdDetailTree.clearSelection(); + ShapeEdDetailTree.removeItem( 0 ); + %root = ShapeEdDetailTree.insertItem( 0, "<root>", "", "" ); + %objCount = ShapeEditor.shape.getObjectCount(); + for ( %i = 0; %i < %objCount; %i++ ) + { + %objName = ShapeEditor.shape.getObjectName( %i ); + %meshCount = ShapeEditor.shape.getMeshCount( %objName ); + for ( %j = 0; %j < %meshCount; %j++ ) + { + %meshName = ShapeEditor.shape.getMeshName( %objName, %j ); + ShapeEdDetailTree.addMeshEntry( %meshName, 1 ); + } + } + + // Initialise object node list + ShapeEdDetails-->objectNode.clear(); + ShapeEdDetails-->objectNode.add( "<root>" ); + %nodeCount = ShapeEditor.shape.getNodeCount(); + for ( %i = 0; %i < %nodeCount; %i++ ) + ShapeEdDetails-->objectNode.add( ShapeEditor.shape.getNodeName( %i ) ); + + // --- MATERIALS TAB --- + ShapeEdMaterials.updateMaterialList(); +} + +//------------------------------------------------------------------------------ +// Shape Hints +//------------------------------------------------------------------------------ + +function ShapeEdHintMenu::onSelect( %this, %id, %text ) +{ + ShapeEdSelectWindow.updateHints(); +} + +function ShapeEdSelectWindow::updateHints( %this ) +{ + %objectType = ShapeEdHintMenu.getText(); + + ShapeEdSelectWindow-->nodeHints.freeze( true ); + ShapeEdSelectWindow-->sequenceHints.freeze( true ); + + // Move all current hint controls to a holder SimGroup + for ( %i = ShapeEdSelectWindow-->nodeHints.getCount()-1; %i >= 0; %i-- ) + ShapeHintControls.add( ShapeEdSelectWindow-->nodeHints.getObject( %i ) ); + for ( %i = ShapeEdSelectWindow-->sequenceHints.getCount()-1; %i >= 0; %i-- ) + ShapeHintControls.add( ShapeEdSelectWindow-->sequenceHints.getObject( %i ) ); + + // Update node and sequence hints, modifying and/or creating gui controls as needed + for ( %i = 0; %i < ShapeHintGroup.getCount(); %i++ ) + { + %hint = ShapeHintGroup.getObject( %i ); + if ( ( %objectType $= %hint.objectType ) || isMemberOfClass( %objectType, %hint.objectType ) ) + { + for ( %idx = 0; %hint.node[%idx] !$= ""; %idx++ ) + ShapeEdHintMenu.processHint( "node", %hint.node[%idx] ); + + for ( %idx = 0; %hint.sequence[%idx] !$= ""; %idx++ ) + ShapeEdHintMenu.processHint( "sequence", %hint.sequence[%idx] ); + } + } + + ShapeEdSelectWindow-->nodeHints.freeze( false ); + ShapeEdSelectWindow-->nodeHints.updateStack(); + ShapeEdSelectWindow-->sequenceHints.freeze( false ); + ShapeEdSelectWindow-->sequenceHints.updateStack(); + +} + +function ShapeEdHintMenu::processHint( %this, %type, %hint ) +{ + %name = getField( %hint, 0 ); + %desc = getField( %hint, 1 ); + + // check for arrayed names (ending in 0-N or 1-N) + %pos = strstr( %name, "0-" ); + if ( %pos == -1 ) + %pos = strstr( %name, "1-" ); + + if ( %pos > 0 ) + { + // arrayed name => add controls for each name in the array, but collapse + // consecutive indices where possible. eg. if the model only has nodes + // mount1-3, we should create: mount0 (red), mount1-3 (green), mount4-31 (red) + %base = getSubStr( %name, 0, %pos ); // array name + %first = getSubStr( %name, %pos, 1 ); // first index + %last = getSubStr( %name, %pos+2, 3 ); // last index + + // get the state of the first element + %arrayStart = %first; + %prevPresent = ShapeEditor.hintNameExists( %type, %base @ %first ); + + for ( %j = %first + 1; %j <= %last; %j++ ) + { + // if the state of this element is different to the previous one, we + // need to add a hint + %present = ShapeEditor.hintNameExists( %type, %base @ %j ); + if ( %present != %prevPresent ) + { + ShapeEdSelectWindow.addObjectHint( %type, %base, %desc, %prevPresent, %arrayStart, %j-1 ); + %arrayStart = %j; + %prevPresent = %present; + } + } + + // add hint for the last group + ShapeEdSelectWindow.addObjectHint( %type, %base, %desc, %prevPresent, %arrayStart, %last ); + } + else + { + // non-arrayed name + %present = ShapeEditor.hintNameExists( %type, %name ); + ShapeEdSelectWindow.addObjectHint( %type, %name, %desc, %present ); + } +} + +function ShapeEdSelectWindow::addObjectHint( %this, %type, %name, %desc, %present, %start, %end ) +{ + // Get a hint gui control (create one if needed) + if ( ShapeHintControls.getCount() == 0 ) + { + // Create a new hint gui control + %ctrl = new GuiIconButtonCtrl() + { + profile = "GuiCreatorIconButtonProfile"; + iconLocation = "Left"; + textLocation = "Right"; + extent = "348 19"; + textMargin = 8; + buttonMargin = "2 2"; + autoSize = true; + buttonType = "radioButton"; + groupNum = "-1"; + iconBitmap = "tools/editorClasses/gui/images/iconCancel"; + text = "hint"; + tooltip = ""; + }; + + ShapeHintControls.add( %ctrl ); + } + %ctrl = ShapeHintControls.getObject( 0 ); + + // Initialise the control, then add it to the appropriate list + %name = %name @ %start; + if ( %end !$= %start ) + %ctrl.text = %name @ "-" @ %end; + else + %ctrl.text = %name; + + %ctrl.tooltip = %desc; + %ctrl.setBitmap( "tools/editorClasses/gui/images/" @ ( %present ? "iconAccept" : "iconCancel" ) ); + %ctrl.setStateOn( false ); + %ctrl.resetState(); + + switch$ ( %type ) + { + case "node": + %ctrl.altCommand = %present ? "" : "ShapeEdNodes.onAddNode( \"" @ %name @ "\" );"; + ShapeEdSelectWindow-->nodeHints.addGuiControl( %ctrl ); + case "sequence": + %ctrl.altCommand = %present ? "" : "ShapeEdSequences.onAddSequence( \"" @ %name @ "\" );"; + ShapeEdSelectWindow-->sequenceHints.addGuiControl( %ctrl ); + } +} + +//------------------------------------------------------------------------------ + +function ShapeEdSeqNodeTabBook::onTabSelected( %this, %name, %index ) +{ + %this.activePage = %name; + + switch$ ( %name ) + { + case "Seq": + ShapeEdPropWindow-->newBtn.ToolTip = "Add new sequence"; + ShapeEdPropWindow-->newBtn.Command = "ShapeEdSequences.onAddSequence();"; + ShapeEdPropWindow-->newBtn.setActive( true ); + ShapeEdPropWindow-->deleteBtn.ToolTip = "Delete selected sequence (cannot be undone)"; + ShapeEdPropWindow-->deleteBtn.Command = "ShapeEdSequences.onDeleteSequence();"; + ShapeEdPropWindow-->deleteBtn.setActive( true ); + + case "Node": + ShapeEdPropWindow-->newBtn.ToolTip = "Add new node"; + ShapeEdPropWindow-->newBtn.Command = "ShapeEdNodes.onAddNode();"; + ShapeEdPropWindow-->newBtn.setActive( true ); + ShapeEdPropWindow-->deleteBtn.ToolTip = "Delete selected node (cannot be undone)"; + ShapeEdPropWindow-->deleteBtn.Command = "ShapeEdNodes.onDeleteNode();"; + ShapeEdPropWindow-->deleteBtn.setActive( true ); + + case "Detail": + ShapeEdPropWindow-->newBtn.ToolTip = ""; + ShapeEdPropWindow-->newBtn.Command = ""; + ShapeEdPropWindow-->newBtn.setActive( false ); + ShapeEdPropWindow-->deleteBtn.ToolTip = "Delete the selected mesh or detail level (cannot be undone)"; + ShapeEdPropWindow-->deleteBtn.Command = "ShapeEdDetails.onDeleteMesh();"; + ShapeEdPropWindow-->deleteBtn.setActive( true ); + + case "Mat": + ShapeEdPropWindow-->newBtn.ToolTip = ""; + ShapeEdPropWindow-->newBtn.Command = ""; + ShapeEdPropWindow-->newBtn.setActive( false ); + ShapeEdPropWindow-->deleteBtn.ToolTip = ""; + ShapeEdPropWindow-->deleteBtn.Command = ""; + ShapeEdPropWindow-->deleteBtn.setActive( false ); + + // For some reason, the header is not resized correctly until the Materials tab has been + // displayed at least once, so resize it here too + ShapeEdMaterials-->materialListHeader.setExtent( getWord( ShapeEdMaterialList.extent, 0 ) SPC "19" ); + } +} + +//------------------------------------------------------------------------------ +// Node Editing +//------------------------------------------------------------------------------ + +// Update the GUI in response to the node selection changing +function ShapeEdPropWindow::update_onNodeSelectionChanged( %this, %id ) +{ + if ( %id > 0 ) + { + // Enable delete button and edit boxes + if ( ShapeEdSeqNodeTabBook.activePage $= "Node" ) + ShapeEdPropWindow-->deleteBtn.setActive( true ); + ShapeEdNodes-->nodeName.setActive( true ); + ShapeEdNodes-->nodePosition.setActive( true ); + ShapeEdNodes-->nodeRotation.setActive( true ); + + // Update the node inspection data + %name = ShapeEdNodeTreeView.getItemText( %id ); + + ShapeEdNodes-->nodeName.setText( %name ); + + // Node parent list => ancestor and sibling nodes only (can't re-parent to a descendent) + ShapeEdNodeParentMenu.clear(); + %parentNames = ShapeEditor.getNodeNames( "", "<root>", %name ); + %count = getWordCount( %parentNames ); + for ( %i = 0; %i < %count; %i++ ) + ShapeEdNodeParentMenu.add( getWord(%parentNames, %i), %i ); + + %pName = ShapeEditor.shape.getNodeParentName( %name ); + if ( %pName $= "" ) + %pName = "<root>"; + ShapeEdNodeParentMenu.setText( %pName ); + + if ( ShapeEdNodes-->worldTransform.getValue() ) + { + // Global transform + %txfm = ShapeEditor.shape.getNodeTransform( %name, 1 ); + ShapeEdNodes-->nodePosition.setText( getWords( %txfm, 0, 2 ) ); + ShapeEdNodes-->nodeRotation.setText( getWords( %txfm, 3, 6 ) ); + } + else + { + // Local transform (relative to parent) + %txfm = ShapeEditor.shape.getNodeTransform( %name, 0 ); + ShapeEdNodes-->nodePosition.setText( getWords( %txfm, 0, 2 ) ); + ShapeEdNodes-->nodeRotation.setText( getWords( %txfm, 3, 6 ) ); + } + + ShapeEdShapeView.selectedNode = ShapeEditor.shape.getNodeIndex( %name ); + } + else + { + // Disable delete button and edit boxes + if ( ShapeEdSeqNodeTabBook.activePage $= "Node" ) + ShapeEdPropWindow-->deleteBtn.setActive( false ); + ShapeEdNodes-->nodeName.setActive( false ); + ShapeEdNodes-->nodePosition.setActive( false ); + ShapeEdNodes-->nodeRotation.setActive( false ); + + ShapeEdNodes-->nodeName.setText( "" ); + ShapeEdNodes-->nodePosition.setText( "" ); + ShapeEdNodes-->nodeRotation.setText( "" ); + + ShapeEdShapeView.selectedNode = -1; + } +} + +// Update the GUI in response to a node being added +function ShapeEdPropWindow::update_onNodeAdded( %this, %nodeName, %oldTreeIndex ) +{ + // --- MISC --- + ShapeEdShapeView.refreshShape(); + ShapeEdShapeView.updateNodeTransforms(); + ShapeEdSelectWindow.updateHints(); + + // --- MOUNT WINDOW --- + if ( ShapeEdMountWindow.isMountableNode( %nodeName ) ) + { + ShapeEdMountWindow-->mountNode.add( %nodeName ); + ShapeEdMountWindow-->mountNode.sort(); + } + + // --- NODES TAB --- + %id = ShapeEdNodeTreeView.addNodeTree( %nodeName ); + if ( %oldTreeIndex <= 0 ) + { + // This is a new node => make it the current selection + if ( %id > 0 ) + { + ShapeEdNodeTreeView.clearSelection(); + ShapeEdNodeTreeView.selectItem( %id ); + } + } + else + { + // This node has been un-deleted. Inserting a new item puts it at the + // end of the siblings, but we want to restore the original order as + // if the item was never deleted, so move it up as required. + %childIndex = ShapeEdNodeTreeView.getChildIndexByName( %nodeName ); + while ( %childIndex > %oldTreeIndex ) + { + ShapeEdNodeTreeView.moveItemUp( %id ); + %childIndex--; + } + } + + // --- DETAILS TAB --- + ShapeEdDetails-->objectNode.add( %nodeName ); +} + +// Update the GUI in response to a node(s) being removed +function ShapeEdPropWindow::update_onNodeRemoved( %this, %nameList, %nameCount ) +{ + // --- MISC --- + ShapeEdShapeView.refreshShape(); + ShapeEdShapeView.updateNodeTransforms(); + ShapeEdSelectWindow.updateHints(); + + // Remove nodes from the mountable list, and any shapes mounted to the node + for ( %i = 0; %i < %nameCount; %i++ ) + { + %nodeName = getField( %nameList, %i ); + ShapeEdMountWindow-->mountNode.clearEntry( ShapeEdMountWindow-->mountNode.findText( %nodeName ) ); + + for ( %j = ShapeEdMountWindow-->mountList.rowCount()-1; %j >= 1; %j-- ) + { + %text = ShapeEdMountWindow-->mountList.getRowText( %j ); + if ( getField( %text, 1 ) $= %nodeName ) + { + ShapeEdShapeView.unmountShape( %j-1 ); + ShapeEdMountWindow-->mountList.removeRow( %j ); + } + } + } + + // --- NODES TAB --- + %lastName = getField( %nameList, %nameCount-1 ); + %id = ShapeEdNodeTreeView.findItemByName( %lastName ); // only need to remove the parent item + if ( %id > 0 ) + { + ShapeEdNodeTreeView.removeItem( %id ); + if ( ShapeEdNodeTreeView.getSelectedItem() <= 0 ) + ShapeEdPropWindow.update_onNodeSelectionChanged( -1 ); + } + + // --- DETAILS TAB --- + for ( %i = 0; %i < %nameCount; %i++ ) + { + %nodeName = getField( %nameList, %i ); + ShapeEdDetails-->objectNode.clearEntry( ShapeEdDetails-->objectNode.findText( %nodeName ) ); + } +} + +// Update the GUI in response to a node being renamed +function ShapeEdPropWindow::update_onNodeRenamed( %this, %oldName, %newName ) +{ + // --- MISC --- + ShapeEdSelectWindow.updateHints(); + + // --- MOUNT WINDOW --- + // Update entries for any shapes mounted to this node + %rowCount = ShapeEdMountWindow-->mountList.rowCount(); + for ( %i = 1; %i < %rowCount; %i++ ) + { + %text = ShapeEdMountWindow-->mountList.getRowText( %i ); + if ( getField( %text, 1 ) $= %oldName ) + { + %text = setField( %text, 1, %newName ); + ShapeEdMountWindow-->mountList.setRowById( ShapeEdMountWindow-->mountList.getRowId( %i ), %text ); + } + } + + // Update list of mountable nodes + ShapeEdMountWindow-->mountNode.clearEntry( ShapeEdMountWindow-->mountNode.findText( %oldName ) ); + if ( ShapeEdMountWindow.isMountableNode( %newName ) ) + { + ShapeEdMountWindow-->mountNode.add( %newName ); + ShapeEdMountWindow-->mountNode.sort(); + } + + // --- NODES TAB --- + %id = ShapeEdNodeTreeView.findItemByName( %oldName ); + ShapeEdNodeTreeView.editItem( %id, %newName, 0 ); + if ( ShapeEdNodeTreeView.getSelectedItem() == %id ) + ShapeEdNodes-->nodeName.setText( %newName ); + + // --- DETAILS TAB --- + %id = ShapeEdDetails-->objectNode.findText( %oldName ); + if ( %id != -1 ) + { + ShapeEdDetails-->objectNode.clearEntry( %id ); + ShapeEdDetails-->objectNode.add( %newName, %id ); + ShapeEdDetails-->objectNode.sortID(); + if ( ShapeEdDetails-->objectNode.getText() $= %oldName ) + ShapeEdDetails-->objectNode.setText( %newName ); + } +} + +// Update the GUI in response to a node's parent being changed +function ShapeEdPropWindow::update_onNodeParentChanged( %this, %nodeName ) +{ + // --- MISC --- + ShapeEdShapeView.updateNodeTransforms(); + + // --- NODES TAB --- + %isSelected = 0; + %id = ShapeEdNodeTreeView.findItemByName( %nodeName ); + if ( %id > 0 ) + { + %isSelected = ( ShapeEdNodeTreeView.getSelectedItem() == %id ); + ShapeEdNodeTreeView.removeItem( %id ); + } + ShapeEdNodeTreeView.addNodeTree( %nodeName ); + if ( %isSelected ) + ShapeEdNodeTreeView.selectItem( ShapeEdNodeTreeView.findItemByName( %nodeName ) ); +} + +function ShapeEdPropWindow::update_onNodeTransformChanged( %this, %nodeName ) +{ + // Default to the selected node if none is specified + if ( %nodeName $= "" ) + { + %id = ShapeEdNodeTreeView.getSelectedItem(); + if ( %id > 0 ) + %nodeName = ShapeEdNodeTreeView.getItemText( %id ); + else + return; + } + + // --- MISC --- + ShapeEdShapeView.updateNodeTransforms(); + if ( ShapeEdNodes-->objectTransform.getValue() ) + GlobalGizmoProfile.setFieldValue(alignment, Object); + else + GlobalGizmoProfile.setFieldValue(alignment, World); + + // --- NODES TAB --- + // Update the node transform fields if necessary + %id = ShapeEdNodeTreeView.getSelectedItem(); + if ( ( %id > 0 ) && ( ShapeEdNodeTreeView.getItemText( %id ) $= %nodeName ) ) + { + %isWorld = ShapeEdNodes-->worldTransform.getValue(); + %transform = ShapeEditor.shape.getNodeTransform( %nodeName, %isWorld ); + ShapeEdNodes-->nodePosition.setText( getWords( %transform, 0, 2 ) ); + ShapeEdNodes-->nodeRotation.setText( getWords( %transform, 3, 6 ) ); + } +} + +function ShapeEdNodeTreeView::onClearSelection( %this ) +{ + ShapeEdPropWindow.update_onNodeSelectionChanged( -1 ); +} + +function ShapeEdNodeTreeView::onSelect( %this, %id ) +{ + // Update the node name and transform controls + ShapeEdPropWindow.update_onNodeSelectionChanged( %id ); + + // Update orbit position if orbiting the selected node + if ( ShapeEdShapeView.orbitNode ) + { + %name = %this.getItemText( %id ); + %transform = ShapeEditor.shape.getNodeTransform( %name, 1 ); + ShapeEdShapeView.setOrbitPos( getWords( %transform, 0, 2 ) ); + } +} + +function ShapeEdShapeView::onNodeSelected( %this, %index ) +{ + ShapeEdNodeTreeView.clearSelection(); + if ( %index > 0 ) + { + %name = ShapeEditor.shape.getNodeName( %index ); + %id = ShapeEdNodeTreeView.findItemByName( %name ); + if ( %id > 0 ) + ShapeEdNodeTreeView.selectItem( %id ); + } +} + +function ShapeEdNodes::onAddNode( %this, %name ) +{ + // Add a new node, using the currently selected node as the initial parent + if ( %name $= "" ) + %name = ShapeEditor.getUniqueName( "node", "myNode" ); + + %id = ShapeEdNodeTreeView.getSelectedItem(); + if ( %id <= 0 ) + %parent = ""; + else + %parent = ShapeEdNodeTreeView.getItemText( %id ); + + ShapeEditor.doAddNode( %name, %parent, "0 0 0 0 0 1 0" ); +} + +function ShapeEdNodes::onDeleteNode( %this ) +{ + // Remove the node and all its children from the shape + %id = ShapeEdNodeTreeView.getSelectedItem(); + if ( %id > 0 ) + { + %name = ShapeEdNodeTreeView.getItemText( %id ); + ShapeEditor.doRemoveShapeData( "Node", %name ); + } +} + +// Determine the index of a node in the tree relative to its parent +function ShapeEdNodeTreeView::getChildIndexByName( %this, %name ) +{ + %id = %this.findItemByName( %name ); + %parentId = %this.getParent( %id ); + %childId = %this.getChild( %parentId ); + if ( %childId <= 0 ) + return 0; // bad! + + %index = 0; + while ( %childId != %id ) + { + %childId = %this.getNextSibling( %childId ); + %index++; + } + + return %index; +} + +// Add a node and its children to the node tree view +function ShapeEdNodeTreeView::addNodeTree( %this, %nodeName ) +{ + // Abort if already added => something dodgy has happened and we'd end up + // recursing indefinitely + if ( %this.findItemByName( %nodeName ) ) + { + error( "Recursion error in ShapeEdNodeTreeView::addNodeTree" ); + return 0; + } + + // Find parent and add me to it + %parentName = ShapeEditor.shape.getNodeParentName( %nodeName ); + if ( %parentName $= "" ) + %parentName = "<root>"; + + %parentId = %this.findItemByName( %parentName ); + %id = %this.insertItem( %parentId, %nodeName, 0, "" ); + + // Add children + %count = ShapeEditor.shape.getNodeChildCount( %nodeName ); + for ( %i = 0; %i < %count; %i++ ) + %this.addNodeTree( ShapeEditor.shape.getNodeChildName( %nodeName, %i ) ); + + return %id; +} + +function ShapeEdNodes::onEditName( %this ) +{ + %id = ShapeEdNodeTreeView.getSelectedItem(); + if ( %id > 0 ) + { + %oldName = ShapeEdNodeTreeView.getItemText( %id ); + %newName = %this-->nodeName.getText(); + if ( %newName !$= "" ) + ShapeEditor.doRenameNode( %oldName, %newName ); + } +} + +function ShapeEdNodeParentMenu::onSelect( %this, %id, %text ) +{ + %id = ShapeEdNodeTreeView.getSelectedItem(); + if ( %id > 0 ) + { + %name = ShapeEdNodeTreeView.getItemText( %id ); + ShapeEditor.doSetNodeParent( %name, %text ); + } +} + +function ShapeEdNodes::onEditTransform( %this ) +{ + %id = ShapeEdNodeTreeView.getSelectedItem(); + if ( %id > 0 ) + { + %name = ShapeEdNodeTreeView.getItemText( %id ); + + // Get the node transform from the gui + %pos = %this-->nodePosition.getText(); + %rot = %this-->nodeRotation.getText(); + %txfm = %pos SPC %rot; + %isWorld = ShapeEdNodes-->worldTransform.getValue(); + + // Do a quick sanity check to avoid setting wildly invalid transforms + for ( %i = 0; %i < 7; %i++ ) // "x y z aa.x aa.y aa.z aa.angle" + { + if ( getWord( %txfm, %i ) $= "" ) + return; + } + + ShapeEditor.doEditNodeTransform( %name, %txfm, %isWorld, -1 ); + } +} + +function ShapeEdShapeView::onEditNodeTransform( %this, %node, %txfm, %gizmoID ) +{ + ShapeEditor.doEditNodeTransform( %node, %txfm, 1, %gizmoID ); +} + +//------------------------------------------------------------------------------ +// Sequence Editing +//------------------------------------------------------------------------------ + +function ShapeEdPropWindow::onWake( %this ) +{ + ShapeEdTriggerList.triggerId = 1; + + ShapeEdTriggerList.addRow( -1, "-1" TAB "Frame" TAB "Trigger" TAB "State" ); + ShapeEdTriggerList.setRowActive( -1, false ); +} + +function ShapeEdPropWindow::update_onSeqSelectionChanged( %this ) +{ + // Sync the Thread window sequence selection + %row = ShapeEdSequenceList.getSelectedRow(); + if ( ShapeEdThreadWindow-->seqList.getSelectedRow() != ( %row-1 ) ) + { + ShapeEdThreadWindow-->seqList.setSelectedRow( %row-1 ); + return; // selecting a sequence in the Thread window will re-call this function + } + + ShapeEdSeqFromMenu.clear(); + ShapeEdSequences-->blendSeq.clear(); + + // Clear the trigger list + ShapeEdTriggerList.removeAll(); + + // Update the active sequence data + %seqName = ShapeEdSequenceList.getSelectedName(); + if ( %seqName !$= "" ) + { + // Enable delete button and edit boxes + if ( ShapeEdSeqNodeTabBook.activePage $= "Seq" ) + ShapeEdPropWindow-->deleteBtn.setActive( true ); + ShapeEdSequences-->seqName.setActive( true ); + ShapeEdSequences-->blendFlag.setActive( true ); + ShapeEdSequences-->cyclicFlag.setActive( true ); + ShapeEdSequences-->priority.setActive( true ); + ShapeEdSequences-->addTriggerBtn.setActive( true ); + ShapeEdSequences-->deleteTriggerBtn.setActive( true ); + + // Initialise the sequence properties + %blendData = ShapeEditor.shape.getSequenceBlend( %seqName ); + ShapeEdSequences-->seqName.setText( %seqName ); + ShapeEdSequences-->cyclicFlag.setValue( ShapeEditor.shape.getSequenceCyclic( %seqName ) ); + ShapeEdSequences-->blendFlag.setValue( getField( %blendData, 0 ) ); + ShapeEdSequences-->priority.setText( ShapeEditor.shape.getSequencePriority( %seqName ) ); + + // 'From' and 'Blend' sequence menus + ShapeEdSeqFromMenu.add( "Browse..." ); + %count = ShapeEdSequenceList.rowCount(); + for ( %i = 2; %i < %count; %i++ ) // skip header row and <rootpose> + { + %name = ShapeEdSequenceList.getItemName( %i ); + if ( %name !$= %seqName ) + { + ShapeEdSeqFromMenu.add( %name ); + ShapeEdSequences-->blendSeq.add( %name ); + } + } + ShapeEdSequences-->blendSeq.setText( getField( %blendData, 1 ) ); + ShapeEdSequences-->blendFrame.setText( getField( %blendData, 2 ) ); + + %this.syncPlaybackDetails(); + + // Triggers (must occur after syncPlaybackDetails is called so the slider range is correct) + %count = ShapeEditor.shape.getTriggerCount( %seqName ); + for ( %i = 0; %i < %count; %i++ ) + { + %trigger = ShapeEditor.shape.getTrigger( %seqName, %i ); + ShapeEdTriggerList.addItem( getWord( %trigger, 0 ), getWord( %trigger, 1 ) ); + } + } + else + { + // Disable delete button and edit boxes + if ( ShapeEdSeqNodeTabBook.activePage $= "Seq" ) + ShapeEdPropWindow-->deleteBtn.setActive( false ); + ShapeEdSequences-->seqName.setActive( false ); + ShapeEdSequences-->blendFlag.setActive( false ); + ShapeEdSequences-->cyclicFlag.setActive( false ); + ShapeEdSequences-->priority.setActive( false ); + ShapeEdSequences-->addTriggerBtn.setActive( false ); + ShapeEdSequences-->deleteTriggerBtn.setActive( false ); + + // Clear sequence properties + ShapeEdSequences-->seqName.setText( "" ); + ShapeEdSequences-->cyclicFlag.setValue( 0 ); + ShapeEdSequences-->blendSeq.setText( "" ); + ShapeEdSequences-->blendFlag.setValue( 0 ); + ShapeEdSequences-->priority.setText( 0 ); + + %this.syncPlaybackDetails(); + } + + %this.onTriggerSelectionChanged(); + + ShapeEdSequences-->sequenceListHeader.setExtent( getWord( ShapeEdSequenceList.extent, 0 ) SPC "19" ); + + // Reset current frame + //ShapeEdAnimWindow.setKeyframe( ShapeEdAnimWindow-->seqIn.getText() ); +} + +// Update the GUI in response to a sequence being added +function ShapeEdPropWindow::update_onSequenceAdded( %this, %seqName, %oldIndex ) +{ + // --- MISC --- + ShapeEdSelectWindow.updateHints(); + + // --- SEQUENCES TAB --- + if ( %oldIndex == -1 ) + { + // This is a brand new sequence => add it to the list and make it the + // current selection + %row = ShapeEdSequenceList.insertItem( %seqName, ShapeEdSequenceList.rowCount() ); + ShapeEdSequenceList.scrollVisible( %row ); + ShapeEdSequenceList.setSelectedRow( %row ); + } + else + { + // This sequence has been un-deleted => add it back to the list at the + // original position + ShapeEdSequenceList.insertItem( %seqName, %oldIndex ); + } +} + +function ShapeEdPropWindow::update_onSequenceRemoved( %this, %seqName ) +{ + // --- MISC --- + ShapeEdSelectWindow.updateHints(); + + // --- SEQUENCES TAB --- + %isSelected = ( ShapeEdSequenceList.getSelectedName() $= %seqName ); + ShapeEdSequenceList.removeItem( %seqName ); + if ( %isSelected ) + ShapeEdPropWindow.update_onSeqSelectionChanged(); + + // --- THREADS WINDOW --- + ShapeEdShapeView.refreshThreadSequences(); +} + +function ShapeEdPropWindow::update_onSequenceRenamed( %this, %oldName, %newName ) +{ + // --- MISC --- + ShapeEdSelectWindow.updateHints(); + + // Rename the proxy sequence as well + %oldProxy = ShapeEditor.getProxyName( %oldName ); + %newProxy = ShapeEditor.getProxyName( %newName ); + if ( ShapeEditor.shape.getSequenceIndex( %oldProxy ) != -1 ) + ShapeEditor.shape.renameSequence( %oldProxy, %newProxy ); + + // --- SEQUENCES TAB --- + ShapeEdSequenceList.editColumn( %oldName, 0, %newName ); + if ( ShapeEdSequenceList.getSelectedName() $= %newName ) + ShapeEdSequences-->seqName.setText( %newName ); + + // --- THREADS WINDOW --- + // Update any threads that use this sequence + %active = ShapeEdShapeView.activeThread; + for ( %i = 0; %i < ShapeEdShapeView.getThreadCount(); %i++ ) + { + ShapeEdShapeView.activeThread = %i; + if ( ShapeEdShapeView.getThreadSequence() $= %oldName ) + ShapeEdShapeView.setThreadSequence( %newName, 0, ShapeEdShapeView.threadPos, 0 ); + else if ( ShapeEdShapeView.getThreadSequence() $= %oldProxy ) + ShapeEdShapeView.setThreadSequence( %newProxy, 0, ShapeEdShapeView.threadPos, 0 ); + } + ShapeEdShapeView.activeThread = %active; +} + +function ShapeEdPropWindow::update_onSequenceCyclicChanged( %this, %seqName, %cyclic ) +{ + // --- MISC --- + // Apply the same transformation to the proxy animation if necessary + %proxyName = ShapeEditor.getProxyName( %seqName ); + if ( ShapeEditor.shape.getSequenceIndex( %proxyName ) != -1 ) + ShapeEditor.shape.setSequenceCyclic( %proxyName, %cyclic ); + + // --- SEQUENCES TAB --- + ShapeEdSequenceList.editColumn( %seqName, 1, %cyclic ? "yes" : "no" ); + if ( ShapeEdSequenceList.getSelectedName() $= %seqName ) + ShapeEdSequences-->cyclicFlag.setStateOn( %cyclic ); +} + +function ShapeEdPropWindow::update_onSequenceBlendChanged( %this, %seqName, %blend, + %oldBlendSeq, %oldBlendFrame, %blendSeq, %blendFrame ) +{ + // --- MISC --- + // Apply the same transformation to the proxy animation if necessary + %proxyName = ShapeEditor.getProxyName( %seqName ); + if ( ShapeEditor.shape.getSequenceIndex( %proxyName ) != -1 ) + { + if ( %blend && %oldBlend ) + ShapeEditor.shape.setSequenceBlend( %proxyName, false, %oldBlendSeq, %oldBlendFrame ); + ShapeEditor.shape.setSequenceBlend( %proxyName, %blend, %blendSeq, %blendFrame ); + } + ShapeEdShapeView.updateNodeTransforms(); + + // --- SEQUENCES TAB --- + ShapeEdSequenceList.editColumn( %seqName, 2, %blend ? "yes" : "no" ); + if ( ShapeEdSequenceList.getSelectedName() $= %seqName ) + { + ShapeEdSequences-->blendFlag.setStateOn( %blend ); + ShapeEdSequences-->blendSeq.setText( %blendSeq ); + ShapeEdSequences-->blendFrame.setText( %blendFrame ); + } +} + +function ShapeEdPropWindow::update_onSequencePriorityChanged( %this, %seqName ) +{ + // --- SEQUENCES TAB --- + %priority = ShapeEditor.shape.getSequencePriority( %seqName ); + ShapeEdSequenceList.editColumn( %seqName, 4, %priority ); + if ( ShapeEdSequenceList.getSelectedName() $= %seqName ) + ShapeEdSequences-->priority.setText( %priority ); +} + +function ShapeEdPropWindow::update_onSequenceGroundSpeedChanged( %this, %seqName ) +{ + // nothing to do yet +} + +function ShapeEdPropWindow::syncPlaybackDetails( %this ) +{ + %seqName = ShapeEdSequenceList.getSelectedName(); + if ( %seqName !$= "" ) + { + // Show sequence in/out bars + ShapeEdAnimWindow-->seqInBar.setVisible( true ); + ShapeEdAnimWindow-->seqOutBar.setVisible( true ); + + // Sync playback controls + %sourceData = ShapeEditor.getSequenceSource( %seqName ); + %seqFrom = rtrim( getFields( %sourceData, 0, 1 ) ); + %seqStart = getField( %sourceData, 2 ); + %seqEnd = getField( %sourceData, 3 ); + %seqFromTotal = getField( %sourceData, 4 ); + + // Display the original source for edited sequences + if ( startswith( %seqFrom, "__backup__" ) ) + { + %backupData = ShapeEditor.getSequenceSource( getField( %seqFrom, 0 ) ); + %seqFrom = rtrim( getFields( %backupData, 0, 1 ) ); + } + + ShapeEdSeqFromMenu.setText( %seqFrom ); + ShapeEdSeqFromMenu.tooltip = ShapeEdSeqFromMenu.getText(); // use tooltip to show long names + ShapeEdSequences-->startFrame.setText( %seqStart ); + ShapeEdSequences-->endFrame.setText( %seqEnd ); + + %val = ShapeEdSeqSlider.getValue() / getWord( ShapeEdSeqSlider.range, 1 ); + ShapeEdSeqSlider.range = "0" SPC ( %seqFromTotal-1 ); + ShapeEdSeqSlider.setValue( %val * getWord( ShapeEdSeqSlider.range, 1 ) ); + ShapeEdThreadSlider.range = ShapeEdSeqSlider.range; + ShapeEdThreadSlider.setValue( ShapeEdSeqSlider.value ); + + ShapeEdAnimWindow.setSequence( %seqName ); + ShapeEdAnimWindow.setPlaybackLimit( "in", %seqStart ); + ShapeEdAnimWindow.setPlaybackLimit( "out", %seqEnd ); + } + else + { + // Hide sequence in/out bars + ShapeEdAnimWindow-->seqInBar.setVisible( false ); + ShapeEdAnimWindow-->seqOutBar.setVisible( false ); + + ShapeEdSeqFromMenu.setText( "" ); + ShapeEdSeqFromMenu.tooltip = ""; + ShapeEdSequences-->startFrame.setText( 0 ); + ShapeEdSequences-->endFrame.setText( 0 ); + + ShapeEdSeqSlider.range = "0 1"; + ShapeEdSeqSlider.setValue( 0 ); + ShapeEdThreadSlider.range = ShapeEdSeqSlider.range; + ShapeEdThreadSlider.setValue( ShapeEdSeqSlider.value ); + ShapeEdAnimWindow.setPlaybackLimit( "in", 0 ); + ShapeEdAnimWindow.setPlaybackLimit( "out", 1 ); + ShapeEdAnimWindow.setSequence( "" ); + } +} + +function ShapeEdSequences::onEditSeqInOut( %this, %type, %val ) +{ + %frameCount = getWord( ShapeEdSeqSlider.range, 1 ); + + // Force value to a frame index within the slider range + %val = mRound( %val ); + if ( %val < 0 ) + %val = 0; + if ( %val > %frameCount ) + %val = %frameCount; + + // Enforce 'in' value must be < 'out' value + if ( %type $= "in" ) + { + if ( %val >= %this-->endFrame.getText() ) + %val = %this-->endFrame.getText() - 1; + %this-->startFrame.setText( %val ); + } + else + { + if ( %val <= %this-->startFrame.getText() ) + %val = %this-->startFrame.getText() + 1; + %this-->endFrame.setText( %val ); + } + + %this.onEditSequenceSource( "" ); +} + +function ShapeEdSequences::onEditSequenceSource( %this, %from ) +{ + // ignore for shapes without sequences + if (ShapeEditor.shape.getSequenceCount() == 0) + return; + + %start = %this-->startFrame.getText(); + %end = %this-->endFrame.getText(); + + if ( ( %start !$= "" ) && ( %end !$= "" ) ) + { + %seqName = ShapeEdSequenceList.getSelectedName(); + %oldSource = ShapeEditor.getSequenceSource( %seqName ); + + if ( %from $= "" ) + %from = rtrim( getFields( %oldSource, 0, 0 ) ); + + if ( getFields( %oldSource, 0, 3 ) !$= ( %from TAB "" TAB %start TAB %end ) ) + ShapeEditor.doEditSeqSource( %seqName, %from, %start, %end ); + } +} + +function ShapeEdSequences::onToggleCyclic( %this ) +{ + %seqName = ShapeEdSequenceList.getSelectedName(); + if ( %seqName !$= "" ) + { + %cyclic = %this-->cyclicFlag.getValue(); + ShapeEditor.doEditCyclic( %seqName, %cyclic ); + } +} + +function ShapeEdSequences::onEditPriority( %this ) +{ + %seqName = ShapeEdSequenceList.getSelectedName(); + if ( %seqName !$= "" ) + { + %newPriority = %this-->priority.getText(); + if ( %newPriority !$= "" ) + ShapeEditor.doEditSequencePriority( %seqName, %newPriority ); + } +} + +function ShapeEdSequences::onEditBlend( %this ) +{ + %seqName = ShapeEdSequenceList.getSelectedName(); + if ( %seqName !$= "" ) + { + // Get the blend flags (current and new) + %oldBlendData = ShapeEditor.shape.getSequenceBlend( %seqName ); + %oldBlend = getField( %oldBlendData, 0 ); + %blend = %this-->blendFlag.getValue(); + + // Ignore changes to the blend reference for non-blend sequences + if ( !%oldBlend && !%blend ) + return; + + // OK - we're trying to change the blend properties of this sequence. The + // new reference sequence and frame must be set. + %blendSeq = %this-->blendSeq.getText(); + %blendFrame = %this-->blendFrame.getText(); + if ( ( %blendSeq $= "" ) || ( %blendFrame $= "" ) ) + { + MessageBoxOK( "Blend reference not set", "The blend reference sequence and " @ + "frame must be set before changing the blend flag or frame." ); + ShapeEdSequences-->blendFlag.setStateOn( %oldBlend ); + return; + } + + // Get the current blend properties (use new values if not specified) + %oldBlendSeq = getField( %oldBlendData, 1 ); + if ( %oldBlendSeq $= "" ) + %oldBlendSeq = %blendSeq; + %oldBlendFrame = getField( %oldBlendData, 2 ); + if ( %oldBlendFrame $= "" ) + %oldBlendFrame = %blendFrame; + + // Check if there is anything to do + if ( ( %oldBlend TAB %oldBlendSeq TAB %oldBlendFrame ) !$= ( %blend TAB %blendSeq TAB %blendFrame ) ) + ShapeEditor.doEditBlend( %seqName, %blend, %blendSeq, %blendFrame ); + } +} + +function ShapeEdSequences::onAddSequence( %this, %name ) +{ + if ( %name $= "" ) + %name = ShapeEditor.getUniqueName( "sequence", "mySequence" ); + + // Use the currently selected sequence as the base + %from = ShapeEdSequenceList.getSelectedName(); + %row = ShapeEdSequenceList.getSelectedRow(); + if ( ( %row < 2 ) && ( ShapeEdSequenceList.rowCount() > 2 ) ) + %row = 2; + if ( %from $= "" ) + { + // No sequence selected => open dialog to browse for one + getLoadFilename( "DSQ Files|*.dsq|COLLADA Files|*.dae|Google Earth Files|*.kmz", %this @ ".onAddSequenceFromBrowse", ShapeEdFromMenu.lastPath ); + return; + } + else + { + // Add the new sequence + %start = ShapeEdSequences-->startFrame.getText(); + %end = ShapeEdSequences-->endFrame.getText(); + ShapeEditor.doAddSequence( %name, %from, %start, %end ); + } +} + +function ShapeEdSequences::onAddSequenceFromBrowse( %this, %path ) +{ + // Add a new sequence from the browse path + %path = makeRelativePath( %path, getMainDotCSDir() ); + ShapeEdFromMenu.lastPath = %path; + + %name = ShapeEditor.getUniqueName( "sequence", "mySequence" ); + ShapeEditor.doAddSequence( %name, %path, 0, -1 ); +} + +// Delete the selected sequence +function ShapeEdSequences::onDeleteSequence( %this ) +{ + %row = ShapeEdSequenceList.getSelectedRow(); + if ( %row != -1 ) + { + %seqName = ShapeEdSequenceList.getItemName( %row ); + ShapeEditor.doRemoveShapeData( "Sequence", %seqName ); + } +} + +// Get the name of the currently selected sequence +function ShapeEdSequenceList::getSelectedName( %this ) +{ + %row = %this.getSelectedRow(); + return ( %row > 1 ) ? %this.getItemName( %row ) : ""; // ignore header row +} + +// Get the sequence name from the indexed row +function ShapeEdSequenceList::getItemName( %this, %row ) +{ + return getField( %this.getRowText( %row ), 0 ); +} + +// Get the index in the list of the sequence with the given name +function ShapeEdSequenceList::getItemIndex( %this, %name ) +{ + for ( %i = 1; %i < %this.rowCount(); %i++ ) // ignore header row + { + if ( %this.getItemName( %i ) $= %name ) + return %i; + } + return -1; +} + +// Change one of the fields in the sequence list +function ShapeEdSequenceList::editColumn( %this, %name, %col, %text ) +{ + %row = %this.getItemIndex( %name ); + %rowText = setField( %this.getRowText( %row ), %col, %text ); + + // Update the Properties and Thread sequence lists + %id = %this.getRowId( %row ); + if ( %col == 0 ) + ShapeEdThreadWindow-->seqList.setRowById( %id, %text ); // Sync name in Thread window + %this.setRowById( %id, %rowText ); +} + +function ShapeEdSequenceList::addItem( %this, %name ) +{ + return %this.insertItem( %name, %this.rowCount() ); +} + +function ShapeEdSequenceList::insertItem( %this, %name, %index ) +{ + %cyclic = ShapeEditor.shape.getSequenceCyclic( %name ) ? "yes" : "no"; + %blend = getField( ShapeEditor.shape.getSequenceBlend( %name ), 0 ) ? "yes" : "no"; + %frameCount = ShapeEditor.shape.getSequenceFrameCount( %name ); + %priority = ShapeEditor.shape.getSequencePriority( %name ); + + // Add the item to the Properties and Thread sequence lists + %this.seqId++; // use this to keep the row IDs synchronised + ShapeEdThreadWindow-->seqList.addRow( %this.seqId, %name, %index-1 ); // no header row + return %this.addRow( %this.seqId, %name TAB %cyclic TAB %blend TAB %frameCount TAB %priority, %index ); +} + +function ShapeEdSequenceList::removeItem( %this, %name ) +{ + %index = %this.getItemIndex( %name ); + if ( %index >= 0 ) + { + %this.removeRow( %index ); + ShapeEdThreadWindow-->seqList.removeRow( %index-1 ); // no header row + } +} + +function ShapeEdSeqFromMenu::onSelect( %this, %id, %text ) +{ + if ( %text $= "Browse..." ) + { + // Reset menu text + %seqName = ShapeEdSequenceList.getSelectedName(); + %seqFrom = rtrim( getFields( ShapeEditor.getSequenceSource( %seqName ), 0, 1 ) ); + %this.setText( %seqFrom ); + + // Allow the user to browse for an external source of animation data + getLoadFilename( "DSQ Files|*.dsq|COLLADA Files|*.dae|Google Earth Files|*.kmz", %this @ ".onBrowseSelect", %this.lastPath ); + } + else + { + ShapeEdSequences.onEditSequenceSource( %text ); + } +} + +function ShapeEdSeqFromMenu::onBrowseSelect( %this, %path ) +{ + %path = makeRelativePath( %path, getMainDotCSDir() ); + %this.lastPath = %path; + %this.setText( %path ); + ShapeEdSequences.onEditSequenceSource( %path ); +} + +//------------------------------------------------------------------------------ +// Threads and Animation +//------------------------------------------------------------------------------ + +function ShapeEdThreadWindow::onWake( %this ) +{ + %this-->useTransitions.setValue( 1 ); + %this-->transitionTime.setText( "0.5" ); + + %this-->transitionTo.clear(); + %this-->transitionTo.add( "synched position", 0 ); + %this-->transitionTo.add( "slider position", 1 ); + %this-->transitionTo.setSelected( 0 ); + + %this-->transitionTarget.clear(); + %this-->transitionTarget.add( "plays during transition", 0 ); + %this-->transitionTarget.add( "pauses during transition", 1 ); + %this-->transitionTarget.setSelected( 0 ); +} + +// Update the GUI in response to the shape selection changing +function ShapeEdThreadWindow::update_onShapeSelectionChanged( %this ) +{ + ShapeEdThreadList.clear(); + %this-->seqList.clear(); + %this-->seqList.addRow( 0, "<rootpose>" ); +} + +function ShapeEdAnimWIndow::threadPosToKeyframe( %this, %pos ) +{ + if ( %this.usingProxySeq ) + { + %start = getWord( ShapeEdSeqSlider.range, 0 ); + %end = getWord( ShapeEdSeqSlider.range, 1 ); + } + else + { + %start = ShapeEdAnimWindow.seqStartFrame; + %end = ShapeEdAnimWindow.seqEndFrame; + } + + return %start + ( %end - %start ) * %pos; +} + +function ShapeEdAnimWindow::keyframeToThreadPos( %this, %frame ) +{ + if ( %this.usingProxySeq ) + { + %start = getWord( ShapeEdSeqSlider.range, 0 ); + %end = getWord( ShapeEdSeqSlider.range, 1 ); + } + else + { + %start = ShapeEdAnimWindow.seqStartFrame; + %end = ShapeEdAnimWindow.seqEndFrame; + } + + return ( %frame - %start ) / ( %end - %start ); +} + +function ShapeEdAnimWindow::setKeyframe( %this, %frame ) +{ + ShapeEdSeqSlider.setValue( %frame ); + if ( ShapeEdThreadWindow-->transitionTo.getText() $= "synched position" ) + ShapeEdThreadSlider.setValue( %frame ); + + // Update the position of the active thread => if outside the in/out range, + // need to switch to the proxy sequence + if ( !%this.usingProxySeq ) + { + if ( ( %frame < %this.seqStartFrame ) || ( %frame > %this.seqEndFrame) ) + { + %this.usingProxySeq = true; + %proxyName = ShapeEditor.getProxyName( ShapeEdShapeView.getThreadSequence() ); + ShapeEdShapeView.setThreadSequence( %proxyName, 0, 0, false ); + } + } + + ShapeEdShapeView.threadPos = %this.keyframeToThreadPos( %frame ); +} + +function ShapeEdAnimWindow::setNoProxySequence( %this ) +{ + // no need to use the proxy sequence during playback + if ( %this.usingProxySeq ) + { + %this.usingProxySeq = false; + %seqName = ShapeEditor.getUnproxyName( ShapeEdShapeView.getThreadSequence() ); + ShapeEdShapeView.setThreadSequence( %seqName, 0, 0, false ); + ShapeEdShapeView.threadPos = %this.keyframeToThreadPos( ShapeEdSeqSlider.getValue() ); + } +} + +function ShapeEdAnimWindow::togglePause( %this ) +{ + if ( %this-->pauseBtn.getValue() == 0 ) + { + %this.lastDirBkwd = %this-->playBkwdBtn.getValue(); + %this-->pauseBtn.performClick(); + } + else + { + %this.setNoProxySequence(); + if ( %this.lastDirBkwd ) + %this-->playBkwdBtn.performClick(); + else + %this-->playFwdBtn.performClick(); + } +} + +function ShapeEdAnimWindow::togglePingPong( %this ) +{ + ShapeEdShapeView.threadPingPong = %this-->pingpong.getValue(); + if ( %this-->playFwdBtn.getValue() ) + %this-->playFwdBtn.performClick(); + else if ( %this-->playBkwdBtn.getValue() ) + %this-->playBkwdBtn.performClick(); +} + +function ShapeEdSeqSlider::onMouseDragged( %this ) +{ + // Pause the active thread when the slider is dragged + if ( ShapeEdAnimWindow-->pauseBtn.getValue() == 0 ) + ShapeEdAnimWindow-->pauseBtn.performClick(); + + ShapeEdAnimWindow.setKeyframe( %this.getValue() ); +} + +function ShapeEdThreadSlider::onMouseDragged( %this ) +{ + if ( ShapeEdThreadWindow-->transitionTo.getText() $= "synched position" ) + { + // Pause the active thread when the slider is dragged + if ( ShapeEdAnimWindow-->pauseBtn.getValue() == 0 ) + ShapeEdAnimWindow-->pauseBtn.performClick(); + + ShapeEdAnimWindow.setKeyframe( %this.getValue() ); + } +} + +function ShapeEdShapeView::onThreadPosChanged( %this, %pos, %inTransition ) +{ + // Update sliders + %frame = ShapeEdAnimWindow.threadPosToKeyframe( %pos ); + ShapeEdSeqSlider.setValue( %frame ); + + if ( ShapeEdThreadWindow-->transitionTo.getText() $= "synched position" ) + { + ShapeEdThreadSlider.setValue( %frame ); + + // Highlight the slider during transitions + if ( %inTransition ) + ShapeEdThreadSlider.profile = GuiShapeEdTransitionSliderProfile; + else + ShapeEdThreadSlider.profile = GuiSliderProfile; + } +} + +// Set the direction of the current thread (-1: reverse, 0: paused, 1: forward) +function ShapeEdAnimWindow::setThreadDirection( %this, %dir ) +{ + // Update thread direction + ShapeEdShapeView.threadDirection = %dir; + + // Sync the controls in the thread window + switch ( %dir ) + { + case -1: ShapeEdThreadWindow-->playBkwdBtn.setStateOn( 1 ); + case 0: ShapeEdThreadWindow-->pauseBtn.setStateOn( 1 ); + case 1: ShapeEdThreadWindow-->playFwdBtn.setStateOn( 1 ); + } +} + +// Set the sequence to play +function ShapeEdAnimWindow::setSequence( %this, %seqName ) +{ + %this.usingProxySeq = false; + + if ( ShapeEdThreadWindow-->useTransitions.getValue() ) + { + %transTime = ShapeEdThreadWindow-->transitionTime.getText(); + if ( ShapeEdThreadWindow-->transitionTo.getText() $= "synched position" ) + %transPos = -1; + else + %transPos = %this.keyframeToThreadPos( ShapeEdThreadSlider.getValue() ); + %transPlay = ( ShapeEdThreadWindow-->transitionTarget.getText() $= "plays during transition" ); + } + else + { + %transTime = 0; + %transPos = 0; + %transPlay = 0; + } + + // No transition when sequence is not changing + if ( %seqName $= ShapeEdShapeView.getThreadSequence() ) + %transTime = 0; + + if ( %seqName !$= "" ) + { + // To be able to effectively scrub through the animation, we need to have all + // frames available, even if it was added with only a subset. If that is the + // case, then create a proxy sequence that has all the frames instead. + %sourceData = ShapeEditor.getSequenceSource( %seqName ); + %from = rtrim( getFields( %sourceData, 0, 1 ) ); + %startFrame = getField( %sourceData, 2 ); + %endFrame = getField( %sourceData, 3 ); + %frameCount = getField( %sourceData, 4 ); + + if ( ( %startFrame != 0 ) || ( %endFrame != ( %frameCount-1 ) ) ) + { + %proxyName = ShapeEditor.getProxyName( %seqName ); + if ( ShapeEditor.shape.getSequenceIndex( %proxyName ) != -1 ) + { + ShapeEditor.shape.removeSequence( %proxyName ); + ShapeEdShapeView.refreshThreadSequences(); + } + ShapeEditor.shape.addSequence( %from, %proxyName ); + + // Limit the transition position to the in/out range + %transPos = mClamp( %transPos, 0, 1 ); + } + } + + ShapeEdShapeView.setThreadSequence( %seqName, %transTime, %transPos, %transPlay ); +} + +function ShapeEdAnimWindow::getTimelineBitmapPos( %this, %val, %width ) +{ + %frameCount = getWord( ShapeEdSeqSlider.range, 1 ); + %pos_x = getWord( ShapeEdSeqSlider.getPosition(), 0 ); + %len_x = getWord( ShapeEdSeqSlider.getExtent(), 0 ) - %width; + return %pos_x + ( ( %len_x * %val / %frameCount ) ); +} + +// Set the in or out sequence limit +function ShapeEdAnimWindow::setPlaybackLimit( %this, %limit, %val ) +{ + // Determine where to place the in/out bar on the slider + %thumbWidth = 8; // width of the thumb bitmap + %pos_x = %this.getTimelineBitmapPos( %val, %thumbWidth ); + + if ( %limit $= "in" ) + { + %this.seqStartFrame = %val; + %this-->seqIn.setText( %val ); + %this-->seqInBar.setPosition( %pos_x, 0 ); + } + else + { + %this.seqEndFrame = %val; + %this-->seqOut.setText( %val ); + %this-->seqOutBar.setPosition( %pos_x, 0 ); + } +} + +function ShapeEdThreadWindow::onAddThread( %this ) +{ + ShapeEdShapeView.addThread(); + ShapeEdThreadList.addRow( %this.threadID++, ShapeEdThreadList.rowCount() ); + ShapeEdThreadList.setSelectedRow( ShapeEdThreadList.rowCount()-1 ); +} + +function ShapeEdThreadWindow::onRemoveThread( %this ) +{ + if ( ShapeEdThreadList.rowCount() > 1 ) + { + // Remove the selected thread + %row = ShapeEdThreadList.getSelectedRow(); + ShapeEdShapeView.removeThread( %row ); + ShapeEdThreadList.removeRow( %row ); + + // Update list (threads are always numbered 0-N) + %rowCount = ShapeEdThreadList.rowCount(); + for ( %i = %row; %i < %rowCount; %i++ ) + ShapeEdThreadList.setRowById( ShapeEdThreadList.getRowId( %i ), %i ); + + // Select the next thread + if ( %row >= %rowCount ) + %row = %rowCount - 1; + + ShapeEdThreadList.setSelectedRow( %row ); + } +} + +function ShapeEdThreadList::onSelect( %this, %row, %text ) +{ + ShapeEdShapeView.activeThread = ShapeEdThreadList.getSelectedRow(); + + // Select the active thread's sequence in the list + %seqName = ShapeEdShapeView.getThreadSequence(); + if ( %seqName $= "" ) + %seqName = "<rootpose>"; + else if ( startswith( %seqName, "__proxy__" ) ) + %seqName = ShapeEditor.getUnproxyName( %seqName ); + + %seqIndex = ShapeEdSequenceList.getItemIndex( %seqName ); + ShapeEdSequenceList.setSelectedRow( %seqIndex ); + + // Update the playback controls + switch ( ShapeEdShapeView.threadDirection ) + { + case -1: ShapeEdAnimWindow-->playBkwdBtn.performClick(); + case 0: ShapeEdAnimWindow-->pauseBtn.performClick(); + case 1: ShapeEdAnimWindow-->playFwdBtn.performClick(); + } + SetToggleButtonValue( ShapeEdAnimWindow-->pingpong, ShapeEdShapeView.threadPingPong ); +} + +//------------------------------------------------------------------------------ +// Trigger Editing +//------------------------------------------------------------------------------ + +function ShapeEdPropWindow::onTriggerSelectionChanged( %this ) +{ + %row = ShapeEdTriggerList.getSelectedRow(); + if ( %row > 0 ) // skip header row + { + %text = ShapeEdTriggerList.getRowText( %row ); + + ShapeEdSequences-->triggerFrame.setActive( true ); + ShapeEdSequences-->triggerNum.setActive( true ); + ShapeEdSequences-->triggerOnOff.setActive( true ); + + ShapeEdSequences-->triggerFrame.setText( getField( %text, 1 ) ); + ShapeEdSequences-->triggerNum.setText( getField( %text, 2 ) ); + ShapeEdSequences-->triggerOnOff.setValue( getField( %text, 3 ) $= "on" ); + } + else + { + // No trigger selected + ShapeEdSequences-->triggerFrame.setActive( false ); + ShapeEdSequences-->triggerNum.setActive( false ); + ShapeEdSequences-->triggerOnOff.setActive( false ); + + ShapeEdSequences-->triggerFrame.setText( "" ); + ShapeEdSequences-->triggerNum.setText( "" ); + ShapeEdSequences-->triggerOnOff.setValue( 0 ); + } +} + +function ShapeEdSequences::onEditName( %this ) +{ + %seqName = ShapeEdSequenceList.getSelectedName(); + if ( %seqName !$= "" ) + { + %newName = %this-->seqName.getText(); + if ( %newName !$= "" ) + ShapeEditor.doRenameSequence( %seqName, %newName ); + } +} + +function ShapeEdPropWindow::update_onTriggerAdded( %this, %seqName, %frame, %state ) +{ + // --- SEQUENCES TAB --- + // Add trigger to list if this sequence is selected + if ( ShapeEdSequenceList.getSelectedName() $= %seqName ) + ShapeEdTriggerList.addItem( %frame, %state ); +} + +function ShapeEdPropWindow::update_onTriggerRemoved( %this, %seqName, %frame, %state ) +{ + // --- SEQUENCES TAB --- + // Remove trigger from list if this sequence is selected + if ( ShapeEdSequenceList.getSelectedName() $= %seqName ) + ShapeEdTriggerList.removeItem( %frame, %state ); +} + +function ShapeEdTriggerList::getTriggerText( %this, %frame, %state ) +{ + // First column is invisible and used only for sorting + %sortKey = ( %frame * 1000 ) + ( mAbs( %state ) * 10 ) + ( ( %state > 0 ) ? 1 : 0 ); + return %sortKey TAB %frame TAB mAbs( %state ) TAB ( ( %state > 0 ) ? "on" : "off" ); +} + +function ShapeEdTriggerList::addItem( %this, %frame, %state ) +{ + // Add to text list + %row = %this.addRow( %this.triggerId, %this.getTriggerText( %frame, %state ) ); + %this.sortNumerical( 0, true ); + + // Add marker to animation timeline + %pos = ShapeEdAnimWindow.getTimelineBitmapPos( ShapeEdAnimWindow-->seqIn.getText() + %frame, 2 ); + %ctrl = new GuiBitmapCtrl() + { + internalName = "trigger" @ %this.triggerId; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = %pos SPC "0"; + Extent = "2 12"; + bitmap = "tools/shapeEditor/images/trigger_marker"; + }; + ShapeEdAnimWindow.getObject(0).addGuiControl( %ctrl ); + %this.triggerId++; +} + +function ShapeEdTriggerList::removeItem( %this, %frame, %state ) +{ + // Remove from text list + %row = %this.findTextIndex( %this.getTriggerText( %frame, %state ) ); + if ( %row > 0 ) + { + eval( "ShapeEdAnimWindow-->trigger" @ %this.getRowId( %row ) @ ".delete();" ); + %this.removeRow( %row ); + } +} + +function ShapeEdTriggerList::removeAll( %this ) +{ + %count = %this.rowCount(); + for ( %row = %count-1; %row > 0; %row-- ) + { + eval( "ShapeEdAnimWindow-->trigger" @ %this.getRowId( %row ) @ ".delete();" ); + %this.removeRow( %row ); + } +} + +function ShapeEdTriggerList::updateItem( %this, %oldFrame, %oldState, %frame, %state ) +{ + // Update text list entry + %oldText = %this.getTriggerText( %oldFrame, %oldState ); + %row = %this.getSelectedRow(); + if ( ( %row <= 0 ) || ( %this.getRowText( %row ) !$= %oldText ) ) + %row = %this.findTextIndex( %oldText ); + if ( %row > 0 ) + { + %updatedId = %this.getRowId( %row ); + %newText = %this.getTriggerText( %frame, %state ); + %this.setRowById( %updatedId, %newText ); + + // keep selected row the same + %selectedId = %this.getSelectedId(); + %this.sortNumerical( 0, true ); + %this.setSelectedById( %selectedId ); + + // Update animation timeline marker + if ( %frame != %oldFrame ) + { + %pos = ShapeEdAnimWindow.getTimelineBitmapPos( ShapeEdAnimWindow-->seqIn.getText() + %frame, 2 ); + eval( "%ctrl = ShapeEdAnimWindow-->trigger" @ %updatedId @ ";" ); + %ctrl.position = %pos SPC "0"; + } + } +} + +function ShapeEdSequences::onAddTrigger( %this ) +{ + // Can only add triggers if a sequence is selected + %seqName = ShapeEdSequenceList.getSelectedName(); + if ( %seqName !$= "" ) + { + // Add a new trigger at the current frame + %frame = mRound( ShapeEdSeqSlider.getValue() ); + %state = ShapeEdTriggerList.rowCount() % 30; + ShapeEditor.doAddTrigger( %seqName, %frame, %state ); + } +} + +function ShapeEdTriggerList::onDeleteSelection( %this ) +{ + // Can only delete a trigger if a sequence and trigger are selected + %seqName = ShapeEdSequenceList.getSelectedName(); + if ( %seqName !$= "" ) + { + %row = %this.getSelectedRow(); + if ( %row > 0 ) + { + %text = %this.getRowText( %row ); + %frame = getWord( %text, 1 ); + %state = getWord( %text, 2 ); + %state *= ( getWord( %text, 3 ) $= "on" ) ? 1 : -1; + ShapeEditor.doRemoveTrigger( %seqName, %frame, %state ); + } + } +} + +function ShapeEdTriggerList::onEditSelection( %this ) +{ + // Can only edit triggers if a sequence and trigger are selected + %seqName = ShapeEdSequenceList.getSelectedName(); + if ( %seqName !$= "" ) + { + %row = ShapeEdTriggerList.getSelectedRow(); + if ( %row > 0 ) + { + %text = %this.getRowText( %row ); + %oldFrame = getWord( %text, 1 ); + %oldState = getWord( %text, 2 ); + %oldState *= ( getWord( %text, 3 ) $= "on" ) ? 1 : -1; + + %frame = mRound( ShapeEdSequences-->triggerFrame.getText() ); + %state = mRound( mAbs( ShapeEdSequences-->triggerNum.getText() ) ); + %state *= ShapeEdSequences-->triggerOnOff.getValue() ? 1 : -1; + + if ( ( %frame >= 0 ) && ( %state != 0 ) ) + ShapeEditor.doEditTrigger( %seqName, %oldFrame, %oldState, %frame, %state ); + } + } +} + +//------------------------------------------------------------------------------ +// Material Editing +//------------------------------------------------------------------------------ + +function ShapeEdMaterials::updateMaterialList( %this ) +{ + // --- MATERIALS TAB --- + ShapeEdMaterialList.clear(); + ShapeEdMaterialList.addRow( -2, "Name" TAB "Mapped" ); + ShapeEdMaterialList.setRowActive( -2, false ); + ShapeEdMaterialList.addRow( -1, "<none>" ); + %count = ShapeEditor.shape.getTargetCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %matName = ShapeEditor.shape.getTargetName( %i ); + %mapped = getMaterialMapping( %matName ); + if ( %mapped $= "" ) + ShapeEdMaterialList.addRow( WarningMaterial.getID(), %matName TAB "unmapped" ); + else + ShapeEdMaterialList.addRow( %mapped.getID(), %matName TAB %mapped ); + } + + ShapeEdMaterials-->materialListHeader.setExtent( getWord( ShapeEdMaterialList.extent, 0 ) SPC "19" ); +} + +function ShapeEdMaterials::updateSelectedMaterial( %this, %highlight ) +{ + // Remove the highlight effect from the old selection + if ( isObject( %this.selectedMaterial ) ) + { + %this.selectedMaterial.diffuseMap[1] = %this.savedMap; + %this.selectedMaterial.reload(); + } + + // Apply the highlight effect to the new selected material + %this.selectedMapTo = getField( ShapeEdMaterialList.getRowText( ShapeEdMaterialList.getSelectedRow() ), 0 ); + %this.selectedMaterial = ShapeEdMaterialList.getSelectedId(); + %this.savedMap = %this.selectedMaterial.diffuseMap[1]; + if ( %highlight && isObject( %this.selectedMaterial ) ) + { + %this.selectedMaterial.diffuseMap[1] = "tools/shapeEditor/images/highlight_material"; + %this.selectedMaterial.reload(); + } +} + +function ShapeEdMaterials::editSelectedMaterial( %this ) +{ + if ( isObject( %this.selectedMaterial ) ) + { + // Remove the highlight effect from the selected material, then switch + // to the Material Editor + %this.updateSelectedMaterial( false ); + + // Create a temporary TSStatic so the MaterialEditor can query the model's + // materials. + pushInstantGroup(); + %this.tempShape = new TSStatic() { + shapeName = ShapeEditor.shape.baseShape; + collisionType = "None"; + }; + popInstantGroup(); + + MaterialEditorGui.currentMaterial = %this.selectedMaterial; + MaterialEditorGui.currentObject = $Tools::materialEditorList = %this.tempShape; + + ShapeEdSelectWindow.setVisible( false ); + ShapeEdPropWindow.setVisible( false ); + + EditorGui-->MatEdPropertiesWindow.setVisible( true ); + EditorGui-->MatEdPreviewWindow.setVisible( true ); + + MatEd_phoBreadcrumb.setVisible( true ); + MatEd_phoBreadcrumb.command = "ShapeEdMaterials.editSelectedMaterialEnd();"; + + advancedTextureMapsRollout.Expanded = false; + materialAnimationPropertiesRollout.Expanded = false; + materialAdvancedPropertiesRollout.Expanded = false; + + MaterialEditorGui.open(); + MaterialEditorGui.setActiveMaterial( %this.selectedMaterial ); + + %id = SubMaterialSelector.findText( %this.selectedMapTo ); + if( %id != -1 ) + SubMaterialSelector.setSelected( %id ); + } +} + +function ShapeEdMaterials::editSelectedMaterialEnd( %this, %closeEditor ) +{ + MatEd_phoBreadcrumb.setVisible( false ); + MatEd_phoBreadcrumb.command = ""; + + MaterialEditorGui.quit(); + EditorGui-->MatEdPropertiesWindow.setVisible( false ); + EditorGui-->MatEdPreviewWindow.setVisible( false ); + + // Delete the temporary TSStatic + %this.tempShape.delete(); + + if( !%closeEditor ) + { + ShapeEdSelectWindow.setVisible( true ); + ShapeEdPropWindow.setVisible( true ); + } +} + +//------------------------------------------------------------------------------ +// Detail/Mesh Editing +//------------------------------------------------------------------------------ + +function ShapeEdDetails::onWake( %this ) +{ + // Initialise popup menus + %this-->bbType.clear(); + %this-->bbType.add( "None", 0 ); + %this-->bbType.add( "Billboard", 1 ); + %this-->bbType.add( "Z Billboard", 2 ); + + %this-->addGeomTo.clear(); + %this-->addGeomTo.add( "current detail", 0 ); + %this-->addGeomTo.add( "new detail", 1 ); + %this-->addGeomTo.setSelected( 0, false ); + + ShapeEdDetailTree.onDefineIcons(); +} + +function ShapeEdDetailTree::onDefineIcons(%this) +{ + // Set the tree view icon indices and texture paths + %this._imageNone = 0; + %this._imageHidden = 1; + + %icons = ":" @ // no icon + "tools/gui/images/visible_i:"; // hidden + + %this.buildIconTable( %icons ); +} + +// Return true if the item in the details tree view is a detail level (false if +// a mesh) +function ShapeEdDetailTree::isDetailItem( %this, %id ) +{ + return ( %this.getParent( %id ) == 1 ); +} + +// Get the detail level index from the ID of an item in the details tree view +function ShapeEdDetailTree::getDetailLevelFromItem( %this, %id ) +{ + if ( %this.isDetailItem( %id ) ) + %detSize = %this.getItemValue( %id ); + + else + %detSize = %this.getItemValue( %this.getParent( %id ) ); + return ShapeEditor.shape.getDetailLevelIndex( %detSize ); +} + +function ShapeEdDetailTree::addMeshEntry( %this, %name, %noSync ) +{ + // Add new detail level if required + %size = getTrailingNumber( %name ); + %detailID = %this.findItemByValue( %size ); + if ( %detailID <= 0 ) + { + %dl = ShapeEditor.shape.getDetailLevelIndex( %size ); + %detName = ShapeEditor.shape.getDetailLevelName( %dl ); + %detailID = ShapeEdDetailTree.insertItem( 1, %detName, %size, "" ); + + // Sort details by decreasing size + for ( %sibling = ShapeEdDetailTree.getPrevSibling( %detailID ); + ( %sibling > 0 ) && ( ShapeEdDetailTree.getItemValue( %sibling ) < %size ); + %sibling = ShapeEdDetailTree.getPrevSibling( %detailID ) ) + ShapeEdDetailTree.moveItemUp( %detailID ); + + if ( !%noSync ) + ShapeEdDetails.update_onDetailsChanged(); + } + return %this.insertItem( %detailID, %name, "", "" ); +} + +function ShapeEdDetailTree::removeMeshEntry( %this, %name, %size ) +{ + %size = getTrailingNumber( %name ); + %id = ShapeEdDetailTree.findItemByName( %name ); + if ( ShapeEditor.shape.getDetailLevelIndex( %size ) < 0 ) + { + // Last mesh of a detail level has been removed => remove the detail level + %this.removeItem( %this.getParent( %id ) ); + ShapeEdDetails.update_onDetailsChanged(); + } + else + %this.removeItem( %id ); +} + +function ShapeEdAdvancedWindow::update_onShapeSelectionChanged( %this ) +{ + ShapeEdShapeView.currentDL = 0; + ShapeEdShapeView.onDetailChanged(); +} + +function ShapeEdPropWindow::update_onDetailRenamed( %this, %oldName, %newName ) +{ + // --- DETAILS TAB --- + // Rename detail entry + %id = ShapeEdDetailTree.findItemByName( %oldName ); + if ( %id > 0 ) + { + %size = ShapeEdDetailTree.getItemValue( %id ); + ShapeEdDetailTree.editItem( %id, %newName, %size ); + + // Sync text if item is selected + if ( ShapeEdDetailTree.isItemSelected( %id ) && + ( ShapeEdDetails-->meshName.getText() !$= %newName ) ) + ShapeEdDetails-->meshName.setText( stripTrailingNumber( %newName ) ); + } +} + +function ShapeEdPropWindow::update_onDetailSizeChanged( %this, %oldSize, %newSize ) +{ + // --- MISC --- + ShapeEdShapeView.refreshShape(); + %dl = ShapeEditor.shape.getDetailLevelIndex( %newSize ); + if ( ShapeEdAdvancedWindow-->detailSize.getText() $= %oldSize ) + { + ShapeEdShapeView.currentDL = %dl; + ShapeEdAdvancedWindow-->detailSize.setText( %newSize ); + ShapeEdDetails-->meshSize.setText( %newSize ); + } + + // --- DETAILS TAB --- + // Update detail entry then resort details by size + %id = ShapeEdDetailTree.findItemByValue( %oldSize ); + %detName = ShapeEditor.shape.getDetailLevelName( %dl ); + ShapeEdDetailTree.editItem( %id, %detName, %newSize ); + + for ( %sibling = ShapeEdDetailTree.getPrevSibling( %id ); + ( %sibling > 0 ) && ( ShapeEdDetailTree.getItemValue( %sibling ) < %newSize ); + %sibling = ShapeEdDetailTree.getPrevSibling( %id ) ) + ShapeEdDetailTree.moveItemUp( %id ); + for ( %sibling = ShapeEdDetailTree.getNextSibling( %id ); + ( %sibling > 0 ) && ( ShapeEdDetailTree.getItemValue( %sibling ) > %newSize ); + %sibling = ShapeEdDetailTree.getNextSibling( %id ) ) + ShapeEdDetailTree.moveItemDown( %id ); + + // Update size values for meshes of this detail + for ( %child = ShapeEdDetailTree.getChild( %id ); + %child > 0; + %child = ShapeEdDetailTree.getNextSibling( %child ) ) + { + %meshName = stripTrailingNumber( ShapeEdDetailTree.getItemText( %child ) ); + ShapeEdDetailTree.editItem( %child, %meshName SPC %newSize, "" ); + } +} + +function ShapeEdDetails::update_onDetailsChanged( %this ) +{ + %detailCount = ShapeEditor.shape.getDetailLevelCount(); + ShapeEdAdvancedWindow-->detailSlider.range = "0" SPC ( %detailCount-1 ); + if ( %detailCount >= 2 ) + ShapeEdAdvancedWindow-->detailSlider.ticks = %detailCount - 2; + else + ShapeEdAdvancedWindow-->detailSlider.ticks = 0; + + // Initialise imposter settings + ShapeEdAdvancedWindow-->bbUseImposters.setValue( ShapeEditor.shape.getImposterDetailLevel() != -1 ); + + // Update detail parameters + if ( ShapeEdShapeView.currentDL < %detailCount ) + { + %settings = ShapeEditor.shape.getImposterSettings( ShapeEdShapeView.currentDL ); + %isImposter = getWord( %settings, 0 ); + + ShapeEdAdvancedWindow-->imposterInactive.setVisible( !%isImposter ); + + ShapeEdAdvancedWindow-->bbEquatorSteps.setText( getField( %settings, 1 ) ); + ShapeEdAdvancedWindow-->bbPolarSteps.setText( getField( %settings, 2 ) ); + ShapeEdAdvancedWindow-->bbDetailLevel.setText( getField( %settings, 3 ) ); + ShapeEdAdvancedWindow-->bbDimension.setText( getField( %settings, 4 ) ); + ShapeEdAdvancedWindow-->bbIncludePoles.setValue( getField( %settings, 5 ) ); + ShapeEdAdvancedWindow-->bbPolarAngle.setText( getField( %settings, 6 ) ); + } +} + +function ShapeEdPropWindow::update_onObjectNodeChanged( %this, %objName ) +{ + // --- MISC --- + ShapeEdShapeView.refreshShape(); + + // --- DETAILS TAB --- + // Update the node popup menu if this object is selected + if ( ShapeEdDetails-->meshName.getText() $= %objName ) + { + %nodeName = ShapeEditor.shape.getObjectNode( %objName ); + if ( %nodeName $= "" ) + %nodeName = "<root>"; + %id = ShapeEdDetails-->objectNode.findText( %nodeName ); + ShapeEdDetails-->objectNode.setSelected( %id, false ); + } +} + +function ShapeEdPropWindow::update_onObjectRenamed( %this, %oldName, %newName ) +{ + // --- DETAILS TAB --- + // Rename tree entries for this object + %count = ShapeEditor.shape.getMeshCount( %newName ); + for ( %i = 0; %i < %count; %i++ ) + { + %size = getTrailingNumber( ShapeEditor.shape.getMeshName( %newName, %i ) ); + %id = ShapeEdDetailTree.findItemByName( %oldName SPC %size ); + if ( %id > 0 ) + { + ShapeEdDetailTree.editItem( %id, %newName SPC %size, "" ); + + // Sync text if item is selected + if ( ShapeEdDetailTree.isItemSelected( %id ) && + ( ShapeEdDetails-->meshName.getText() !$= %newName ) ) + ShapeEdDetails-->meshName.setText( %newName ); + } + } +} + +function ShapeEdPropWindow::update_onMeshAdded( %this, %meshName ) +{ + // --- MISC --- + ShapeEdShapeView.refreshShape(); + ShapeEdShapeView.updateNodeTransforms(); + + // --- COLLISION WINDOW --- + // Add object to target list if it does not already exist + if ( !ShapeEditor.isCollisionMesh( %meshName ) ) + { + %objName = stripTrailingNumber( %meshName ); + %id = ShapeEdColWindow-->colTarget.findText( %objName ); + if ( %id == -1 ) + ShapeEdColWindow-->colTarget.add( %objName ); + } + + // --- DETAILS TAB --- + %id = ShapeEdDetailTree.addMeshEntry( %meshName ); + ShapeEdDetailTree.clearSelection(); + ShapeEdDetailTree.selectItem( %id ); +} + +function ShapeEdPropWindow::update_onMeshSizeChanged( %this, %meshName, %oldSize, %newSize ) +{ + // --- MISC --- + ShapeEdShapeView.refreshShape(); + + // --- DETAILS TAB --- + // Move the mesh to the new location in the tree + %selected = ShapeEdDetailTree.getSelectedItem(); + %id = ShapeEdDetailTree.findItemByName( %meshName SPC %oldSize ); + ShapeEdDetailTree.removeMeshEntry( %meshName SPC %oldSize ); + %newId = ShapeEdDetailTree.addMeshEntry( %meshName SPC %newSize ); + + // Re-select the new entry if it was selected + if ( %selected == %id ) + { + ShapeEdDetailTree.clearSelection(); + ShapeEdDetailTree.selectItem( %newId ); + } +} + +function ShapeEdPropWindow::update_onMeshRemoved( %this, %meshName ) +{ + // --- MISC --- + ShapeEdShapeView.refreshShape(); + + // --- COLLISION WINDOW --- + // Remove object from target list if it no longer exists + %objName = stripTrailingNumber( %meshName ); + if ( ShapeEditor.shape.getObjectIndex( %objName ) == -1 ) + { + %id = ShapeEdColWindow-->colTarget.findText( %objName ); + if ( %id != -1 ) + ShapeEdColWindow-->colTarget.clearEntry( %id ); + } + + // --- DETAILS TAB --- + // Determine which item to select next + %id = ShapeEdDetailTree.findItemByName( %meshName ); + if ( %id > 0 ) + { + %nextId = ShapeEdDetailTree.getPrevSibling( %id ); + if ( %nextId <= 0 ) + { + %nextId = ShapeEdDetailTree.getNextSibling( %id ); + if ( %nextId <= 0 ) + %nextId = 2; + } + + // Remove the entry from the tree + %meshSize = getTrailingNumber( %meshName ); + ShapeEdDetailTree.removeMeshEntry( %meshName, %meshSize ); + + // Change selection if needed + if ( ShapeEdDetailTree.getSelectedItem() == -1 ) + ShapeEdDetailTree.selectItem( %nextId ); + } +} + +function ShapeEdDetailTree::onSelect( %this, %id ) +{ + %name = %this.getItemText( %id ); + %baseName = stripTrailingNumber( %name ); + %size = getTrailingNumber( %name ); + + ShapeEdDetails-->meshName.setText( %baseName ); + ShapeEdDetails-->meshSize.setText( %size ); + + // Select the appropriate detail level + %dl = %this.getDetailLevelFromItem( %id ); + ShapeEdShapeView.currentDL = %dl; + + if ( %this.isDetailItem( %id ) ) + { + // Selected a detail => disable mesh controls + ShapeEdDetails-->editMeshInactive.setVisible( true ); + ShapeEdShapeView.selectedObject = -1; + ShapeEdShapeView.selectedObjDetail = 0; + } + else + { + // Selected a mesh => sync mesh controls + ShapeEdDetails-->editMeshInactive.setVisible( false ); + + switch$ ( ShapeEditor.shape.getMeshType( %name ) ) + { + case "normal": ShapeEdDetails-->bbType.setSelected( 0, false ); + case "billboard": ShapeEdDetails-->bbType.setSelected( 1, false ); + case "billboardzaxis": ShapeEdDetails-->bbType.setSelected( 2, false ); + } + + %node = ShapeEditor.shape.getObjectNode( %baseName ); + if ( %node $= "" ) + %node = "<root>"; + ShapeEdDetails-->objectNode.setSelected( ShapeEdDetails-->objectNode.findText( %node ), false ); + ShapeEdShapeView.selectedObject = ShapeEditor.shape.getObjectIndex( %baseName ); + ShapeEdShapeView.selectedObjDetail = %dl; + } +} + +function ShapeEdDetailTree::onRightMouseUp( %this, %itemId, %mouse ) +{ + // Open context menu if this is a Mesh item + if ( !%this.isDetailItem( %itemId ) ) + { + if( !isObject( "ShapeEdMeshPopup" ) ) + { + new PopupMenu( ShapeEdMeshPopup ) + { + superClass = "MenuBuilder"; + isPopup = "1"; + + item[ 0 ] = "Hidden" TAB "" TAB "ShapeEdDetailTree.onHideMeshItem( %this._objName, !%this._itemHidden );"; + item[ 1 ] = "-"; + item[ 2 ] = "Hide all" TAB "" TAB "ShapeEdDetailTree.onHideMeshItem( \"\", true );"; + item[ 3 ] = "Show all" TAB "" TAB "ShapeEdDetailTree.onHideMeshItem( \"\", false );"; + }; + } + + ShapeEdMeshPopup._objName = stripTrailingNumber( %this.getItemText( %itemId ) ); + ShapeEdMeshPopup._itemHidden = ShapeEdShapeView.getMeshHidden( ShapeEdMeshPopup._objName ); + + ShapeEdMeshPopup.checkItem( 0, ShapeEdMeshPopup._itemHidden ); + ShapeEdMeshPopup.showPopup( Canvas ); + } +} + +function ShapeEdDetailTree::onHideMeshItem( %this, %objName, %hide ) +{ + if ( %hide ) + %imageId = %this._imageHidden; + else + %imageId = %this._imageNone; + + if ( %objName $= "" ) + { + // Show/hide all + ShapeEdShapeView.setAllMeshesHidden( %hide ); + for ( %parent = %this.getChild(%this.getFirstRootItem()); %parent > 0; %parent = %this.getNextSibling(%parent) ) + for ( %child = %this.getChild(%parent); %child > 0; %child = %this.getNextSibling(%child) ) + %this.setItemImages( %child, %imageId, %imageId ); + } + else + { + // Show/hide all meshes for this object + ShapeEdShapeView.setMeshHidden( %objName, %hide ); + %count = ShapeEditor.shape.getMeshCount( %objName ); + for ( %i = 0; %i < %count; %i++ ) + { + %meshName = ShapeEditor.shape.getMeshName( %objName, %i ); + %id = ShapeEdDetailTree.findItemByName( %meshName ); + if ( %id > 0 ) + %this.setItemImages( %id, %imageId, %imageId ); + } + } +} + +function ShapeEdShapeView::onDetailChanged( %this ) +{ + // Update slider + if ( mRound( ShapeEdAdvancedWindow-->detailSlider.getValue() ) != %this.currentDL ) + ShapeEdAdvancedWindow-->detailSlider.setValue( %this.currentDL ); + ShapeEdAdvancedWindow-->detailSize.setText( %this.detailSize ); + + ShapeEdDetails.update_onDetailsChanged(); + + %id = ShapeEdDetailTree.getSelectedItem(); + if ( ( %id <= 0 ) || ( %this.currentDL != ShapeEdDetailTree.getDetailLevelFromItem( %id ) ) ) + { + %id = ShapeEdDetailTree.findItemByValue( %this.detailSize ); + if ( %id > 0 ) + { + ShapeEdDetailTree.clearSelection(); + ShapeEdDetailTree.selectItem( %id ); + } + } +} + +function ShapeEdAdvancedWindow::onEditDetailSize( %this ) +{ + // Change the size of the current detail level + %oldSize = ShapeEditor.shape.getDetailLevelSize( ShapeEdShapeView.currentDL ); + %detailSize = %this-->detailSize.getText(); + ShapeEditor.doEditDetailSize( %oldSize, %detailSize ); +} + +function ShapeEdDetails::onEditName( %this ) +{ + %newName = %this-->meshName.getText(); + + // Check if we are renaming a detail or a mesh + %id = ShapeEdDetailTree.getSelectedItem(); + %oldName = ShapeEdDetailTree.getItemText( %id ); + + if ( ShapeEdDetailTree.isDetailItem( %id ) ) + { + // Rename the selected detail level + %oldSize = getTrailingNumber( %oldName ); + ShapeEditor.doRenameDetail( %oldName, %newName @ %oldSize ); + } + else + { + // Rename the selected mesh + ShapeEditor.doRenameObject( stripTrailingNumber( %oldName ), %newName ); + } +} + +function ShapeEdDetails::onEditSize( %this ) +{ + %newSize = %this-->meshSize.getText(); + + // Check if we are changing the size for a detail or a mesh + %id = ShapeEdDetailTree.getSelectedItem(); + if ( ShapeEdDetailTree.isDetailItem( %id ) ) + { + // Change the size of the selected detail level + %oldSize = ShapeEdDetailTree.getItemValue( %id ); + ShapeEditor.doEditDetailSize( %oldSize, %newSize ); + } + else + { + // Change the size of the selected mesh + %meshName = ShapeEdDetailTree.getItemText( %id ); + ShapeEditor.doEditMeshSize( %meshName, %newSize ); + } +} + +function ShapeEdDetails::onEditBBType( %this ) +{ + // This command is only valid for meshes (not details) + %id = ShapeEdDetailTree.getSelectedItem(); + if ( !ShapeEdDetailTree.isDetailItem( %id ) ) + { + %meshName = ShapeEdDetailTree.getItemText( %id ); + %bbType = ShapeEdDetails-->bbType.getText(); + switch$ ( %bbType ) + { + case "None": %bbType = "normal"; + case "Billboard": %bbType = "billboard"; + case "Z Billboard": %bbType = "billboardzaxis"; + } + ShapeEditor.doEditMeshBillboard( %meshName, %bbType ); + } +} + +function ShapeEdDetails::onSetObjectNode( %this ) +{ + // This command is only valid for meshes (not details) + %id = ShapeEdDetailTree.getSelectedItem(); + if ( !ShapeEdDetailTree.isDetailItem( %id ) ) + { + %meshName = ShapeEdDetailTree.getItemText( %id ); + %objName = stripTrailingNumber( %meshName ); + %node = %this-->objectNode.getText(); + if ( %node $= "<root>" ) + %node = ""; + ShapeEditor.doSetObjectNode( %objName, %node ); + } +} + +function ShapeEdDetails::onAddMeshFromFile( %this, %path ) +{ + if ( %path $= "" ) + { + getLoadFilename( "DTS Files|*.dts|COLLADA Files|*.dae|Google Earth Files|*.kmz", %this @ ".onAddMeshFromFile", %this.lastPath ); + return; + } + + %path = makeRelativePath( %path, getMainDotCSDir() ); + %this.lastPath = %path; + + // Determine the detail level to use for the new geometry + if ( %this-->addGeomTo.getText() $= "current detail" ) + { + %size = ShapeEditor.shape.getDetailLevelSize( ShapeEdShapeView.currentDL ); + } + else + { + // Check if the file has an LODXXX hint at the end of it + %base = fileBase( %path ); + %pos = strstr( %base, "_LOD" ); + if ( %pos > 0 ) + %size = getSubStr( %base, %pos + 4, strlen( %base ) ) + 0; + else + %size = 2; + + // Make sure size is not in use + while ( ShapeEditor.shape.getDetailLevelIndex( %size ) != -1 ) + %size++; + } + + ShapeEditor.doAddMeshFromFile( %path, %size ); +} + +function ShapeEdDetails::onDeleteMesh( %this ) +{ + %id = ShapeEdDetailTree.getSelectedItem(); + if ( ShapeEdDetailTree.isDetailItem( %id ) ) + { + %detSize = ShapeEdDetailTree.getItemValue( %id ); + ShapeEditor.doRemoveShapeData( "Detail", %detSize ); + } + else + { + %name = ShapeEdDetailTree.getItemText( %id ); + ShapeEditor.doRemoveShapeData( "Mesh", %name ); + } +} + +function ShapeEdDetails::onToggleImposter( %this, %useImposter ) +{ + %hasImposterDetail = ( ShapeEditor.shape.getImposterDetailLevel() != -1 ); + if ( %useImposter == %hasImposterDetail ) + return; + + if ( %useImposter ) + { + // Determine an unused detail size + for ( %detailSize = 0; %detailSize < 50; %detailSize++ ) + { + if ( ShapeEditor.shape.getDetailLevelIndex( %detailSize ) == -1 ) + break; + } + + // Set some initial values for the imposter + %bbEquatorSteps = 6; + %bbPolarSteps = 0; + %bbDetailLevel = 0; + %bbDimension = 128; + %bbIncludePoles = 0; + %bbPolarAngle = 0; + + // Add a new imposter detail level to the shape + ShapeEditor.doEditImposter( -1, %detailSize, %bbEquatorSteps, %bbPolarSteps, + %bbDetailLevel, %bbDimension, %bbIncludePoles, %bbPolarAngle ); + } + else + { + // Remove the imposter detail level + ShapeEditor.doRemoveImposter(); + } +} + +function ShapeEdDetails::onEditImposter( %this ) +{ + // Modify the parameters of the current imposter detail level + %detailSize = ShapeEditor.shape.getDetailLevelSize( ShapeEdShapeView.currentDL ); + %bbDimension = ShapeEdAdvancedWindow-->bbDimension.getText(); + %bbDetailLevel = ShapeEdAdvancedWindow-->bbDetailLevel.getText(); + %bbEquatorSteps = ShapeEdAdvancedWindow-->bbEquatorSteps.getText(); + %bbIncludePoles = ShapeEdAdvancedWindow-->bbIncludePoles.getValue(); + %bbPolarSteps = ShapeEdAdvancedWindow-->bbPolarSteps.getText(); + %bbPolarAngle = ShapeEdAdvancedWindow-->bbPolarAngle.getText(); + + ShapeEditor.doEditImposter( ShapeEdShapeView.currentDL, %detailSize, + %bbEquatorSteps, %bbPolarSteps, %bbDetailLevel, %bbDimension, + %bbIncludePoles, %bbPolarAngle ); +} + + +function ShapeEditor::autoAddDetails( %this, %dest ) +{ + // Sets of LOD files are named like: + // + // MyShape_LOD200.dae + // MyShape_LOD64.dae + // MyShape_LOD2.dae + // + // Determine the base name of the input file (MyShape_LOD in the example above) + // and use that to find any other shapes in the set. + %base = fileBase( %dest.baseShape ); + %pos = strstr( %base, "_LOD" ); + if ( %pos < 0 ) + { + echo( "Not an LOD shape file" ); + return; + } + + %base = getSubStr( %base, 0, %pos + 4 ); + + echo( "Base is: " @ %base ); + + %filePatterns = filePath( %dest.baseShape ) @ "/" @ %base @ "*" @ fileExt( %dest.baseShape ); + + echo( "Pattern is: " @ %filePatterns ); + + %fullPath = findFirstFileMultiExpr( %filePatterns ); + while ( %fullPath !$= "" ) + { + %fullPath = makeRelativePath( %fullPath, getMainDotCSDir() ); + + if ( %fullPath !$= %dest.baseShape ) + { + echo( "Found LOD shape file: " @ %fullPath ); + + // Determine the detail size ( number after the base name ), then add the + // new mesh + %size = strreplace( fileBase( %fullPath ), %base, "" ); + ShapeEditor.addLODFromFile( %dest, %fullPath, %size, 0 ); + } + + %fullPath = findNextFileMultiExpr( %filePatterns ); + } + + if ( %this.shape == %dest ) + { + ShapeEdShapeView.refreshShape(); + ShapeEdDetails.update_onDetailsChanged(); + } +} + +function ShapeEditor::addLODFromFile( %this, %dest, %filename, %size, %allowUnmatched ) +{ + // Get (or create) a TSShapeConstructor object for the source shape. Need to + // exec the script manually as the resource may not have been loaded yet + %csPath = filePath( %filename ) @ "/" @ fileBase( %filename ) @ ".cs"; + if ( isFile( %csPath ) ) + exec( %csPath ); + + %source = ShapeEditor.findConstructor( %filename ); + if ( %source == -1 ) + %source = ShapeEditor.createConstructor( %filename ); + %source.lodType = "SingleSize"; + %source.singleDetailSize = %size; + + // Create a temporary TSStatic to ensure the resource is loaded + %temp = new TSStatic() { + shapeName = %filename; + collisionType = "None"; + }; + + %meshList = ""; + if ( isObject( %temp ) ) + { + // Add a new mesh for each object in the source shape + %objCount = %source.getObjectCount(); + for ( %i = 0; %i < %objCount; %i++ ) + { + %objName = %source.getObjectName( %i ); + + echo( "Checking for object " @ %objName ); + + if ( %allowUnmatched || ( %dest.getObjectIndex( %objName ) != -1 ) ) + { + // Add the source object's highest LOD mesh to the destination shape + echo( "Adding detail size" SPC %size SPC "for object" SPC %objName ); + %srcName = %source.getMeshName( %objName, 0 ); + %destName = %objName SPC %size; + %dest.addMesh( %destName, %filename, %srcName ); + %meshList = %meshList TAB %destName; + } + } + + %temp.delete(); + } + + return trim( %meshList ); +} + +//------------------------------------------------------------------------------ +// Collision editing +//------------------------------------------------------------------------------ + +function ShapeEdColWindow::onWake( %this ) +{ + %this-->colType.clear(); + %this-->colType.add( "Box" ); + %this-->colType.add( "Sphere" ); + %this-->colType.add( "Capsule" ); + %this-->colType.add( "10-DOP X" ); + %this-->colType.add( "10-DOP Y" ); + %this-->colType.add( "10-DOP Z" ); + %this-->colType.add( "18-DOP" ); + %this-->colType.add( "26-DOP" ); + %this-->colType.add( "Convex Hulls" ); +} + +function ShapeEdColWindow::update_onShapeSelectionChanged( %this ) +{ + %this.lastColSettings = "" TAB "Bounds"; + + // Initialise collision mesh target list + %this-->colTarget.clear(); + %this-->colTarget.add( "Bounds" ); + %objCount = ShapeEditor.shape.getObjectCount(); + for ( %i = 0; %i < %objCount; %i++ ) + %this-->colTarget.add( ShapeEditor.shape.getObjectName( %i ) ); + + %this-->colTarget.setSelected( %this-->colTarget.findText( "Bounds" ), false ); +} + +function ShapeEdColWindow::update_onCollisionChanged( %this ) +{ + // Sync collision settings + %colData = %this.lastColSettings; + + %typeId = %this-->colType.findText( getField( %colData, 0 ) ); + %this-->colType.setSelected( %typeId, false ); + + %targetId = %this-->colTarget.findText( getField( %colData, 1 ) ); + %this-->colTarget.setSelected( %targetId, false ); + + if ( %this-->colType.getText() $= "Convex Hulls" ) + { + %this-->hullInactive.setVisible( false ); + %this-->hullDepth.setValue( getField( %colData, 2 ) ); + %this-->hullDepthText.setText( mFloor( %this-->hullDepth.getValue() ) ); + %this-->hullMergeThreshold.setValue( getField( %colData, 3 ) ); + %this-->hullMergeText.setText( mFloor( %this-->hullMergeThreshold.getValue() ) ); + %this-->hullConcaveThreshold.setValue( getField( %colData, 4 ) ); + %this-->hullConcaveText.setText( mFloor( %this-->hullConcaveThreshold.getValue() ) ); + %this-->hullMaxVerts.setValue( getField( %colData, 5 ) ); + %this-->hullMaxVertsText.setText( mFloor( %this-->hullMaxVerts.getValue() ) ); + %this-->hullMaxBoxError.setValue( getField( %colData, 6 ) ); + %this-->hullMaxBoxErrorText.setText( mFloor( %this-->hullMaxBoxError.getValue() ) ); + %this-->hullMaxSphereError.setValue( getField( %colData, 7 ) ); + %this-->hullMaxSphereErrorText.setText( mFloor( %this-->hullMaxSphereError.getValue() ) ); + %this-->hullMaxCapsuleError.setValue( getField( %colData, 8 ) ); + %this-->hullMaxCapsuleErrorText.setText( mFloor( %this-->hullMaxCapsuleError.getValue() ) ); + } + else + { + %this-->hullInactive.setVisible( true ); + } +} + +function ShapeEdColWindow::editCollision( %this ) +{ + // If the shape already contains a collision detail size-1, warn the user + // that it will be removed + if ( ( ShapeEditor.shape.getDetailLevelIndex( -1 ) >= 0 ) && + ( getField(%this.lastColSettings, 0) $= "" ) ) + { + MessageBoxYesNo( "Warning", "Existing collision geometry at detail size " @ + "-1 will be removed, and this cannot be undone. Do you want to continue?", + "ShapeEdColWindow.editCollisionOK();", "" ); + } + else + { + %this.editCollisionOK(); + } +} + +function ShapeEdColWindow::editCollisionOK( %this ) +{ + %type = %this-->colType.getText(); + %target = %this-->colTarget.getText(); + %depth = %this-->hullDepth.getValue(); + %merge = %this-->hullMergeThreshold.getValue(); + %concavity = %this-->hullConcaveThreshold.getValue(); + %maxVerts = %this-->hullMaxVerts.getValue(); + %maxBox = %this-->hullMaxBoxError.getValue(); + %maxSphere = %this-->hullMaxSphereError.getValue(); + %maxCapsule = %this-->hullMaxCapsuleError.getValue(); + + ShapeEditor.doEditCollision( %type, %target, %depth, %merge, %concavity, %maxVerts, + %maxBox, %maxSphere, %maxCapsule ); +} + +//------------------------------------------------------------------------------ +// Mounted Shapes +//------------------------------------------------------------------------------ + +function ShapeEdMountWindow::onWake( %this ) +{ + %this-->mountType.clear(); + %this-->mountType.add( "Object", 0 ); + %this-->mountType.add( "Image", 1 ); + %this-->mountType.add( "Wheel", 2 ); + %this-->mountType.setSelected( 1, false ); + + %this-->mountSeq.clear(); + %this-->mountSeq.add( "<rootpose>", 0 ); + %this-->mountSeq.setSelected( 0, false ); + %this-->mountPlayBtn.setStateOn( false ); + + // Only add the Browse entry the first time so we keep any files the user has + // set up previously + if ( ShapeEdMountShapeMenu.size() == 0 ) + { + ShapeEdMountShapeMenu.add( "Browse...", 0 ); + ShapeEdMountShapeMenu.setSelected( 0, false ); + } +} + +function ShapeEdMountWindow::isMountableNode( %this, %nodeName ) +{ + return ( startswith( %nodeName, "mount" ) || startswith( %nodeName, "hub" ) ); +} + +function ShapeEdMountWindow::update_onShapeSelectionChanged( %this ) +{ + %this.unmountAll(); + + // Initialise the dropdown menus + %this-->mountNode.clear(); + %this-->mountNode.add( "<origin>" ); + %count = ShapeEditor.shape.getNodeCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %name = ShapeEditor.shape.getNodeName( %i ); + if ( %this.isMountableNode( %name ) ) + %this-->mountNode.add( %name ); + } + %this-->mountNode.sort(); + %this-->mountNode.setFirstSelected(); + + %this-->mountSeq.clear(); + %this-->mountSeq.add( "<rootpose>", 0 ); + %this-->mountSeq.setSelected( 0, false ); +} + +function ShapeEdMountWindow::update_onMountSelectionChanged( %this ) +{ + %row = %this-->mountList.getSelectedRow(); + if ( %row > 0 ) + { + %text = %this-->mountList.getRowText( %row ); + %shapePath = getField( %text, 0 ); + + ShapeEdMountShapeMenu.setText( %shapePath ); + %this-->mountNode.setText( getField( %text, 2 ) ); + %this-->mountType.setText( getField( %text, 3 ) ); + + // Fill in sequence list + %this-->mountSeq.clear(); + %this-->mountSeq.add( "<rootpose>", 0 ); + + %tss = ShapeEditor.findConstructor( %shapePath ); + if ( !isObject( %tss ) ) + %tss = ShapeEditor.createConstructor( %shapePath ); + if ( isObject( %tss ) ) + { + %count = %tss.getSequenceCount(); + for ( %i = 0; %i < %count; %i++ ) + %this-->mountSeq.add( %tss.getSequenceName( %i ) ); + } + + // Select the currently playing sequence + %slot = %row - 1; + %seq = ShapeEdShapeView.getMountThreadSequence( %slot ); + %id = %this-->mountSeq.findText( %seq ); + if ( %id == -1 ) + %id = 0; + %this-->mountSeq.setSelected( %id, false ); + + ShapeEdMountSeqSlider.setValue( ShapeEdShapeView.getMountThreadPos( %slot ) ); + %this-->mountPlayBtn.setStateOn( ShapeEdShapeView.getMountThreadPos( %slot ) != 0 ); + } +} + +function ShapeEdMountWindow::updateSelectedMount( %this ) +{ + %row = %this-->mountList.getSelectedRow(); + if ( %row > 0 ) + %this.mountShape( %row-1 ); +} + +function ShapeEdMountWindow::setMountThreadSequence( %this ) +{ + %row = %this-->mountList.getSelectedRow(); + if ( %row > 0 ) + { + ShapeEdShapeView.setMountThreadSequence( %row-1, %this-->mountSeq.getText() ); + ShapeEdShapeView.setMountThreadDir( %row-1, %this-->mountPlayBtn.getValue() ); + } +} + +function ShapeEdMountSeqSlider::onMouseDragged( %this ) +{ + %row = ShapeEdMountWindow-->mountList.getSelectedRow(); + if ( %row > 0 ) + { + ShapeEdShapeView.setMountThreadPos( %row-1, %this.getValue() ); + + // Pause the sequence when the slider is dragged + ShapeEdShapeView.setMountThreadDir( %row-1, 0 ); + ShapeEdMountWindow-->mountPlayBtn.setStateOn( false ); + } +} + +function ShapeEdMountWindow::toggleMountThreadPlayback( %this ) +{ + %row = %this-->mountList.getSelectedRow(); + if ( %row > 0 ) + ShapeEdShapeView.setMountThreadDir( %row-1, %this-->mountPlayBtn.getValue() ); +} + +function ShapeEdMountShapeMenu::onSelect( %this, %id, %text ) +{ + if ( %text $= "Browse..." ) + { + // Allow the user to browse for an external model file + getLoadFilename( "DTS Files|*.dts|COLLADA Files|*.dae|Google Earth Files|*.kmz", %this @ ".onBrowseSelect", %this.lastPath ); + } + else + { + // Modify the current mount + ShapeEdMountWindow.updateSelectedMount(); + } +} + +function ShapeEdMountShapeMenu::onBrowseSelect( %this, %path ) +{ + %path = makeRelativePath( %path, getMainDotCSDir() ); + %this.lastPath = %path; + %this.setText( %path ); + + // Add entry if unique + if ( %this.findText( %path ) == -1 ) + %this.add( %path ); + + ShapeEdMountWindow.updateSelectedMount(); +} + +function ShapeEdMountWindow::mountShape( %this, %slot ) +{ + %model = ShapeEdMountShapeMenu.getText(); + %node = %this-->mountNode.getText(); + %type = %this-->mountType.getText(); + + if ( %model $= "Browse..." ) + %model = "core/art/shapes/octahedron.dts"; + + if ( ShapeEdShapeView.mountShape( %model, %node, %type, %slot ) ) + { + %rowText = %model TAB fileName( %model ) TAB %node TAB %type; + if ( %slot == -1 ) + { + %id = %this.mounts++; + %this-->mountList.addRow( %id, %rowText ); + } + else + { + %id = %this-->mountList.getRowId( %slot+1 ); + %this-->mountList.setRowById( %id, %rowText ); + } + + %this-->mountList.setSelectedById( %id ); + } + else + { + MessageBoxOK( "Error", "Failed to mount \"" @ %model @ "\". Check the console for error messages.", "" ); + } +} + +function ShapeEdMountWindow::unmountShape( %this ) +{ + %row = %this-->mountList.getSelectedRow(); + if ( %row > 0 ) + { + ShapeEdShapeView.unmountShape( %row-1 ); + %this-->mountList.removeRow( %row ); + + // Select the next row (if any) + %count = %this-->mountList.rowCount(); + if ( %row >= %count ) + %row = %count-1; + if ( %row > 0 ) + %this-->mountList.setSelectedRow( %row ); + } +} + +function ShapeEdMountWindow::unmountAll( %this ) +{ + ShapeEdShapeView.unmountAll(); + %this-->mountList.clear(); + %this-->mountList.addRow( -1, "FullPath" TAB "Filename" TAB "Node" TAB "Type" ); + %this-->mountList.setRowActive( -1, false ); +} + +//------------------------------------------------------------------------------ +// Shape Preview +//------------------------------------------------------------------------------ + +function ShapeEdPreviewGui::updatePreviewBackground( %color ) +{ + ShapeEdPreviewGui-->previewBackground.color = %color; + ShapeEditorToolbar-->previewBackgroundPicker.color = %color; +} + +function showShapeEditorPreview() +{ + %visible = ShapeEditorToolbar-->showPreview.getValue(); + ShapeEdPreviewGui.setVisible( %visible ); +} diff --git a/Templates/Empty/game/tools/shapeEditor/scripts/shapeEditorActions.ed.cs b/Templates/Empty/game/tools/shapeEditor/scripts/shapeEditorActions.ed.cs new file mode 100644 index 000000000..2c48b25a1 --- /dev/null +++ b/Templates/Empty/game/tools/shapeEditor/scripts/shapeEditorActions.ed.cs @@ -0,0 +1,1304 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// The TSShapeConstructor object allows you to apply a set of transformations +// to a 3space shape after it is loaded by Torque, but _before_ the shape is used +// by any other object (eg. Player, StaticShape etc). The sort of transformations +// available include adding, renaming and removing nodes and sequences. This GUI +// is a visual wrapper around TSShapeConstructor which allows you to build up the +// transformation set without having to get your hands dirty with TorqueScript. +// +// Removing a node, sequence, mesh or detail poses a problem. These operations +// permanently delete a potentially large amount of data scattered throughout +// the shape, and there is no easy way to restore it if the user 'undoes' the +// delete. Although it is possible to store the deleted data somewhere and restore +// it on undo, it is not easy to get right, and ugly as hell to implement. For +// example, removing a node would require storing the node name, the +// translation/rotation/scale matters bit for each sequence, all node transform +// keyframes, the IDs of any objects that were attached to the node, skin weights +// etc, then restoring all that data into the original place on undo. Frankly, +// TSShape was never designed to be modified dynamically like that. +// +// So......currently we wimp out completely and just don't support undo for those +// remove operations. Lame, I know, but the best I can do for now. +// +// This file implements all of the actions that can be applied by the GUI. Each +// action has 3 methods: +// +// doit: called the first time the action is performed +// undo: called to undo the action +// redo: called to redo the action (usually the same as doit) +// +// In each case, the appropriate change is made to the shape, and the GUI updated. +// +// TSShapeConstructor keeps track of all the changes made and provides a simple +// way to save the modifications back out to a script file. + +// The ShapeEditor uses its own UndoManager +if ( !isObject( ShapeEdUndoManager ) ) + new UndoManager( ShapeEdUndoManager ); + +function ShapeEdUndoManager::updateUndoMenu( %this, %editMenu ) +{ + %undoName = %this.getNextUndoName(); + %redoName = %this.getNextRedoName(); + + %editMenu.setItemName( 0, "Undo " @ %undoName ); + %editMenu.setItemName( 1, "Redo " @ %redoName ); + + %editMenu.enableItem( 0, %undoName !$= "" ); + %editMenu.enableItem( 1, %redoName !$= "" ); +} + +//------------------------------------------------------------------------------ +// Helper functions for creating and applying GUI operations + +function ShapeEditor::createAction( %this, %class, %desc ) +{ + pushInstantGroup(); + %action = new UndoScriptAction() + { + class = %class; + superClass = BaseShapeEdAction; + actionName = %desc; + done = 0; + }; + popInstantGroup(); + return %action; +} + +function ShapeEditor::doAction( %this, %action ) +{ + if ( %action.doit() ) + { + ShapeEditor.setDirty( true ); + %action.addToManager( ShapeEdUndoManager ); + } + else + { + MessageBoxOK( "Error", %action.actionName SPC "failed. Check the console for error messages.", "" ); + } +} + +function BaseShapeEdAction::redo( %this ) +{ + // Default redo action is the same as the doit action + if ( %this.doit() ) + { + ShapeEditor.setDirty( true ); + } + else + { + MessageBoxOK( "Error", "Redo" SPC %this.actionName SPC "failed. Check the console for error messages.", "" ); + } +} + +function BaseShapeEdAction::undo( %this ) +{ + ShapeEditor.setDirty( true ); +} + +//------------------------------------------------------------------------------ + +function ShapeEditor::doRemoveShapeData( %this, %type, %name ) +{ + // Removing data from the shape cannot be undone => so warn the user first + MessageBoxYesNo( "Warning", "Deleting a " @ %type @ " cannot be undone. Do " @ + "you want to continue?", "ShapeEditor.doRemove" @ %type @ "( \"" @ %name @ "\" );", "" ); +} + +//------------------------------------------------------------------------------ +// Add node +function ShapeEditor::doAddNode( %this, %nodeName, %parentName, %transform ) +{ + %action = %this.createAction( ActionAddNode, "Add node" ); + %action.nodeName = %nodeName; + %action.parentName = %parentName; + %action.transform = %transform; + + %this.doAction( %action ); +} + +function ActionAddNode::doit( %this ) +{ + if ( ShapeEditor.shape.addNode( %this.nodeName, %this.parentName, %this.transform ) ) + { + ShapeEdPropWindow.update_onNodeAdded( %this.nodeName, -1 ); + return true; + } + return false; +} + +function ActionAddNode::undo( %this ) +{ + Parent::undo( %this ); + + if ( ShapeEditor.shape.removeNode( %this.nodeName ) ) + ShapeEdPropWindow.update_onNodeRemoved( %this.nodeName, 1 ); +} + +//------------------------------------------------------------------------------ +// Remove node +function ShapeEditor::doRemoveNode( %this, %nodeName ) +{ + %action = %this.createAction( ActionRemoveNode, "Remove node" ); + %action.nodeName =%nodeName; + %action.nodeChildIndex = ShapeEdNodeTreeView.getChildIndexByName( %nodeName ); + + // Need to delete all child nodes of this node as well, so recursively collect + // all of the names. + %action.nameList = %this.getNodeNames( %nodeName, "" ); + %action.nameCount = getFieldCount( %action.nameList ); + for ( %i = 0; %i < %action.nameCount; %i++ ) + %action.names[%i] = getField( %action.nameList, %i ); + + %this.doAction( %action ); +} + +function ActionRemoveNode::doit( %this ) +{ + for ( %i = 0; %i < %this.nameCount; %i++ ) + ShapeEditor.shape.removeNode( %this.names[%i] ); + + // Update GUI + ShapeEdPropWindow.update_onNodeRemoved( %this.nameList, %this.nameCount ); + + return true; +} + +function ActionRemoveNode::undo( %this ) +{ + Parent::undo( %this ); +} + +//------------------------------------------------------------------------------ +// Rename node +function ShapeEditor::doRenameNode( %this, %oldName, %newName ) +{ + %action = %this.createAction( ActionRenameNode, "Rename node" ); + %action.oldName = %oldName; + %action.newName = %newName; + + %this.doAction( %action ); +} + +function ActionRenameNode::doit( %this ) +{ + if ( ShapeEditor.shape.renameNode( %this.oldName, %this.newName ) ) + { + ShapeEdPropWindow.update_onNodeRenamed( %this.oldName, %this.newName ); + return true; + } + return false; +} + +function ActionRenameNode::undo( %this ) +{ + Parent::undo( %this ); + + if ( ShapeEditor.shape.renameNode( %this.newName, %this.oldName ) ) + ShapeEdPropWindow.update_onNodeRenamed( %this.newName, %this.oldName ); +} + +//------------------------------------------------------------------------------ +// Set node parent +function ShapeEditor::doSetNodeParent( %this, %name, %parent ) +{ + if ( %parent $= "<root>" ) + %parent = ""; + + %action = %this.createAction( ActionSetNodeParent, "Set parent node" ); + %action.nodeName = %name; + %action.parentName = %parent; + %action.oldParentName = ShapeEditor.shape.getNodeParentName( %name ); + + %this.doAction( %action ); +} + +function ActionSetNodeParent::doit( %this ) +{ + if ( ShapeEditor.shape.setNodeParent( %this.nodeName, %this.parentName ) ) + { + ShapeEdPropWindow.update_onNodeParentChanged( %this.nodeName ); + return true; + } + return false; +} + +function ActionSetNodeParent::undo( %this ) +{ + Parent::undo( %this ); + + if ( ShapeEditor.shape.setNodeParent( %this.nodeName, %this.oldParentName ) ) + ShapeEdPropWindow.update_onNodeParentChanged( %this.nodeName ); +} + +//------------------------------------------------------------------------------ +// Edit node transform +function ShapeEditor::doEditNodeTransform( %this, %nodeName, %newTransform, %isWorld, %gizmoID ) +{ + // If dragging the 3D gizmo, combine all movement into a single action. Undoing + // that action will return the node to where it was when the gizmo drag started. + %last = ShapeEdUndoManager.getUndoAction( ShapeEdUndoManager.getUndoCount() - 1 ); + if ( ( %last != -1 ) && ( %last.class $= ActionEditNodeTransform ) && + ( %last.nodeName $= %nodeName ) && ( %last.gizmoID != -1 ) && ( %last.gizmoID == %gizmoID ) ) + { + // Use the last action to do the edit, and modify it so it only applies + // the latest transform + %last.newTransform = %newTransform; + %last.isWorld = %isWorld; + %last.doit(); + ShapeEditor.setDirty( true ); + } + else + { + %action = %this.createAction( ActionEditNodeTransform, "Edit node transform" ); + %action.nodeName = %nodeName; + %action.newTransform = %newTransform; + %action.isWorld = %isWorld; + %action.gizmoID = %gizmoID; + %action.oldTransform = %this.shape.getNodeTransform( %nodeName, %isWorld ); + + %this.doAction( %action ); + } +} + +function ActionEditNodeTransform::doit( %this ) +{ + ShapeEditor.shape.setNodeTransform( %this.nodeName, %this.newTransform, %this.isWorld ); + ShapeEdPropWindow.update_onNodeTransformChanged(); + return true; +} + +function ActionEditNodeTransform::undo( %this ) +{ + Parent::undo( %this ); + + ShapeEditor.shape.setNodeTransform( %this.nodeName, %this.oldTransform, %this.isWorld ); + ShapeEdPropWindow.update_onNodeTransformChanged(); +} + +//------------------------------------------------------------------------------ +// Add sequence +function ShapeEditor::doAddSequence( %this, %seqName, %from, %start, %end ) +{ + %action = %this.createAction( ActionAddSequence, "Add sequence" ); + %action.seqName = %seqName; + %action.origFrom = %from; + %action.from = %from; + %action.start = %start; + %action.end = %end; + + %this.doAction( %action ); +} + +function ActionAddSequence::doit( %this ) +{ + // If adding this sequence from an existing sequence, make a backup copy of + // the existing sequence first, so we can edit the start/end frames later + // without having to worry if the original source sequence has changed. + if ( ShapeEditor.shape.getSequenceIndex( %this.from ) >= 0 ) + { + %this.from = ShapeEditor.getUniqueName( "sequence", "__backup__" @ %this.origFrom @ "_" ); + ShapeEditor.shape.addSequence( %this.origFrom, %this.from ); + } + + // Add the sequence + $collada::forceLoadDAE = EditorSettings.value( "forceLoadDAE" ); + %success = ShapeEditor.shape.addSequence( %this.from, %this.seqName, %this.start, %this.end ); + $collada::forceLoadDAE = false; + + if ( %success ) + { + ShapeEdPropWindow.update_onSequenceAdded( %this.seqName, -1 ); + return true; + } + return false; +} + +function ActionAddSequence::undo( %this ) +{ + Parent::undo( %this ); + + // Remove the backup sequence if one was created + if ( %this.origFrom !$= %this.from ) + { + ShapeEditor.shape.removeSequence( %this.from ); + %this.from = %this.origFrom; + } + + // Remove the actual sequence + if ( ShapeEditor.shape.removeSequence( %this.seqName ) ) + ShapeEdPropWindow.update_onSequenceRemoved( %this.seqName ); +} + +//------------------------------------------------------------------------------ +// Remove sequence + +function ShapeEditor::doRemoveSequence( %this, %seqName ) +{ + %action = %this.createAction( ActionRemoveSequence, "Remove sequence" ); + %action.seqName = %seqName; + + %this.doAction( %action ); +} + +function ActionRemoveSequence::doit( %this ) +{ + if ( ShapeEditor.shape.removeSequence( %this.seqName ) ) + { + ShapeEdPropWindow.update_onSequenceRemoved( %this.seqName ); + return true; + } + return false; +} + +function ActionRemoveSequence::undo( %this ) +{ + Parent::undo( %this ); +} + +//------------------------------------------------------------------------------ +// Rename sequence +function ShapeEditor::doRenameSequence( %this, %oldName, %newName ) +{ + %action = %this.createAction( ActionRenameSequence, "Rename sequence" ); + %action.oldName = %oldName; + %action.newName = %newName; + + %this.doAction( %action ); +} + +function ActionRenameSequence::doit( %this ) +{ + if ( ShapeEditor.shape.renameSequence( %this.oldName, %this.newName ) ) + { + ShapeEdPropWindow.update_onSequenceRenamed( %this.oldName, %this.newName ); + return true; + } + return false; +} + +function ActionRenameSequence::undo( %this ) +{ + Parent::undo( %this ); + + if ( ShapeEditor.shape.renameSequence( %this.newName, %this.oldName ) ) + ShapeEdPropWindow.update_onSequenceRenamed( %this.newName, %this.oldName ); +} + +//------------------------------------------------------------------------------ +// Edit sequence source data ( parent, start or end ) +function ShapeEditor::doEditSeqSource( %this, %seqName, %from, %start, %end ) +{ + %action = %this.createAction( ActionEditSeqSource, "Edit sequence source data" ); + %action.seqName = %seqName; + %action.origFrom = %from; + %action.from = %from; + %action.start = %start; + %action.end = %end; + + // To support undo, the sequence will be renamed instead of removed (undo just + // removes the added sequence and renames the original back). Generate a unique + // name for the backed up sequence + %action.seqBackup = ShapeEditor.getUniqueName( "sequence", "__backup__" @ %action.seqName @ "_" ); + + // If editing an internal sequence, the source is the renamed backup + if ( %action.from $= %action.seqName ) + %action.from = %action.seqBackup; + + %this.doAction( %action ); +} + +function ActionEditSeqSource::doit( %this ) +{ + // If changing the source to an existing sequence, make a backup copy of + // the existing sequence first, so we can edit the start/end frames later + // without having to worry if the original source sequence has changed. + if ( !startswith( %this.from, "__backup__" ) && + ShapeEditor.shape.getSequenceIndex( %this.from ) >= 0 ) + { + %this.from = ShapeEditor.getUniqueName( "sequence", "__backup__" @ %this.origFrom @ "_" ); + ShapeEditor.shape.addSequence( %this.origFrom, %this.from ); + } + + // Get settings we want to retain + %priority = ShapeEditor.shape.getSequencePriority( %this.seqName ); + %cyclic = ShapeEditor.shape.getSequenceCyclic( %this.seqName ); + %blend = ShapeEditor.shape.getSequenceBlend( %this.seqName ); + + // Rename this sequence (instead of removing it) so we can undo this action + ShapeEditor.shape.renameSequence( %this.seqName, %this.seqBackup ); + + // Add the new sequence + if ( ShapeEditor.shape.addSequence( %this.from, %this.seqName, %this.start, %this.end ) ) + { + // Restore original settings + if ( ShapeEditor.shape.getSequencePriority ( %this.seqName ) != %priority ) + ShapeEditor.shape.setSequencePriority( %this.seqName, %priority ); + if ( ShapeEditor.shape.getSequenceCyclic( %this.seqName ) != %cyclic ) + ShapeEditor.shape.setSequenceCyclic( %this.seqName, %cyclic ); + + %newBlend = ShapeEditor.shape.getSequenceBlend( %this.seqName ); + if ( %newBlend !$= %blend ) + { + // Undo current blend, then apply new one + ShapeEditor.shape.setSequenceBlend( %this.seqName, 0, getField( %newBlend, 1 ), getField( %newBlend, 2 ) ); + if ( getField( %blend, 0 ) == 1 ) + ShapeEditor.shape.setSequenceBlend( %this.seqName, getField( %blend, 0 ), getField( %blend, 1 ), getField( %blend, 2 ) ); + } + + if ( ShapeEdSequenceList.getSelectedName() $= %this.seqName ) + { + ShapeEdSequenceList.editColumn( %this.seqName, 3, %this.end - %this.start + 1 ); + ShapeEdPropWindow.syncPlaybackDetails(); + } + + return true; + } + return false; +} + +function ActionEditSeqSource::undo( %this ) +{ + Parent::undo( %this ); + + // Remove the source sequence backup if one was created + if ( ( %this.from !$= %this.origFrom ) && ( %this.from !$= %this.seqBackup ) ) + { + ShapeEditor.shape.removeSequence( %this.from ); + %this.from = %this.origFrom; + } + + // Remove the added sequence, and rename the backup back + if ( ShapeEditor.shape.removeSequence( %this.seqName ) && + ShapeEditor.shape.renameSequence( %this.seqBackup, %this.seqName ) ) + { + if ( ShapeEdSequenceList.getSelectedName() $= %this.seqName ) + { + ShapeEdSequenceList.editColumn( %this.seqName, 3, %this.end - %this.start + 1 ); + ShapeEdPropWindow.syncPlaybackDetails(); + } + } +} + +//------------------------------------------------------------------------------ +// Edit cyclic flag +function ShapeEditor::doEditCyclic( %this, %seqName, %cyclic ) +{ + %action = %this.createAction( ActionEditCyclic, "Toggle cyclic flag" ); + %action.seqName = %seqName; + %action.cyclic = %cyclic; + + %this.doAction( %action ); +} + +function ActionEditCyclic::doit( %this ) +{ + if ( ShapeEditor.shape.setSequenceCyclic( %this.seqName, %this.cyclic ) ) + { + ShapeEdPropWindow.update_onSequenceCyclicChanged( %this.seqName, %this.cyclic ); + return true; + } + return false; +} + +function ActionEditCyclic::undo( %this ) +{ + Parent::undo( %this ); + + if ( ShapeEditor.shape.setSequenceCyclic( %this.seqName, !%this.cyclic ) ) + ShapeEdPropWindow.update_onSequenceCyclicChanged( %this.seqName, !%this.cyclic ); +} + +//------------------------------------------------------------------------------ +// Edit blend properties +function ShapeEditor::doEditBlend( %this, %seqName, %blend, %blendSeq, %blendFrame ) +{ + %action = %this.createAction( ActionEditBlend, "Edit blend properties" ); + %action.seqName = %seqName; + %action.blend = %blend; + %action.blendSeq = %blendSeq; + %action.blendFrame = %blendFrame; + + // Store the current blend settings + %oldBlend = ShapeEditor.shape.getSequenceBlend( %seqName ); + %action.oldBlend = getField( %oldBlend, 0 ); + %action.oldBlendSeq = getField( %oldBlend, 1 ); + %action.oldBlendFrame = getField( %oldBlend, 2 ); + + // Use new values if the old ones do not exist ( for blend sequences embedded + // in the DTS/DSQ file ) + if ( %action.oldBlendSeq $= "" ) + %action.oldBlendSeq = %action.blendSeq; + if ( %action.oldBlendFrame $= "" ) + %action.oldBlendFrame = %action.blendFrame; + + %this.doAction( %action ); +} + +function ActionEditBlend::doit( %this ) +{ + // If we are changing the blend reference ( rather than just toggling the flag ) + // we need to undo the current blend first. + if ( %this.blend && %this.oldBlend ) + { + if ( !ShapeEditor.shape.setSequenceBlend( %this.seqName, false, %this.oldBlendSeq, %this.oldBlendFrame ) ) + return false; + } + + if ( ShapeEditor.shape.setSequenceBlend( %this.seqName, %this.blend, %this.blendSeq, %this.blendFrame ) ) + { + ShapeEdPropWindow.update_onSequenceBlendChanged( %this.seqName, %this.blend, + %this.oldBlendSeq, %this.oldBlendFrame, %this.blendSeq, %this.blendFrame ); + return true; + } + return false; +} + +function ActionEditBlend::undo( %this ) +{ + Parent::undo( %this ); + + // If we are changing the blend reference ( rather than just toggling the flag ) + // we need to undo the current blend first. + if ( %this.blend && %this.oldBlend ) + { + if ( !ShapeEditor.shape.setSequenceBlend( %this.seqName, false, %this.blendSeq, %this.blendFrame ) ) + return; + } + + if ( ShapeEditor.shape.setSequenceBlend( %this.seqName, %this.oldBlend, %this.oldBlendSeq, %this.oldBlendFrame ) ) + { + ShapeEdPropWindow.update_onSequenceBlendChanged( %this.seqName, !%this.blend, + %this.blendSeq, %this.blendFrame, %this.oldBlendSeq, %this.oldBlendFrame ); + } +} + +//------------------------------------------------------------------------------ +// Edit sequence priority +function ShapeEditor::doEditSequencePriority( %this, %seqName, %newPriority ) +{ + %action = %this.createAction( ActionEditSequencePriority, "Edit sequence priority" ); + %action.seqName = %seqName; + %action.newPriority = %newPriority; + %action.oldPriority = %this.shape.getSequencePriority( %seqName ); + + %this.doAction( %action ); +} + +function ActionEditSequencePriority::doit( %this ) +{ + if ( ShapeEditor.shape.setSequencePriority( %this.seqName, %this.newPriority ) ) + { + ShapeEdPropWindow.update_onSequencePriorityChanged( %this.seqName ); + return true; + } + return false; +} + +function ActionEditSequencePriority::undo( %this ) +{ + Parent::undo( %this ); + + if ( ShapeEditor.shape.setSequencePriority( %this.seqName, %this.oldPriority ) ) + ShapeEdPropWindow.update_onSequencePriorityChanged( %this.seqName ); +} + +//------------------------------------------------------------------------------ +// Edit sequence ground speed +function ShapeEditor::doEditSequenceGroundSpeed( %this, %seqName, %newSpeed ) +{ + %action = %this.createAction( ActionEditSequenceGroundSpeed, "Edit sequence ground speed" ); + %action.seqName = %seqName; + %action.newSpeed = %newSpeed; + %action.oldSpeed = %this.shape.getSequenceGroundSpeed( %seqName ); + + %this.doAction( %action ); +} + +function ActionEditSequenceGroundSpeed::doit( %this ) +{ + if ( ShapeEditor.shape.setSequenceGroundSpeed( %this.seqName, %this.newSpeed ) ) + { + ShapeEdPropWindow.update_onSequenceGroundSpeedChanged( %this.seqName ); + return true; + } + return false; +} + +function ActionEditSequenceGroundSpeed::undo( %this ) +{ + Parent::undo( %this ); + + if ( ShapeEditor.shape.setSequenceGroundSpeed( %this.seqName, %this.oldSpeed ) ) + ShapeEdPropWindow.update_onSequenceGroundSpeedChanged( %this.seqName ); +} + +//------------------------------------------------------------------------------ +// Add trigger +function ShapeEditor::doAddTrigger( %this, %seqName, %frame, %state ) +{ + %action = %this.createAction( ActionAddTrigger, "Add trigger" ); + %action.seqName = %seqName; + %action.frame = %frame; + %action.state = %state; + + %this.doAction( %action ); +} + +function ActionAddTrigger::doit( %this ) +{ + if ( ShapeEditor.shape.addTrigger( %this.seqName, %this.frame, %this.state ) ) + { + ShapeEdPropWindow.update_onTriggerAdded( %this.seqName, %this.frame, %this.state ); + return true; + } + return false; +} + +function ActionAddTrigger::undo( %this ) +{ + Parent::undo( %this ); + + if ( ShapeEditor.shape.removeTrigger( %this.seqName, %this.frame, %this.state ) ) + ShapeEdPropWindow.update_onTriggerRemoved( %this.seqName, %this.frame, %this.state ); +} + +//------------------------------------------------------------------------------ +// Remove trigger +function ShapeEditor::doRemoveTrigger( %this, %seqName, %frame, %state ) +{ + %action = %this.createAction( ActionRemoveTrigger, "Remove trigger" ); + %action.seqName = %seqName; + %action.frame = %frame; + %action.state = %state; + + %this.doAction( %action ); +} + +function ActionRemoveTrigger::doit( %this ) +{ + if ( ShapeEditor.shape.removeTrigger( %this.seqName, %this.frame, %this.state ) ) + { + ShapeEdPropWindow.update_onTriggerRemoved( %this.seqName, %this.frame, %this.state ); + return true; + } + return false; +} + +function ActionRemoveTrigger::undo( %this ) +{ + Parent::undo( %this ); + + if ( ShapeEditor.shape.addTrigger( %this.seqName, %this.frame, %this.state ) ) + ShapeEdPropWindow.update_onTriggerAdded( %this.seqName, %this.frame, %this.state ); +} + +//------------------------------------------------------------------------------ +// Edit trigger +function ShapeEditor::doEditTrigger( %this, %seqName, %oldFrame, %oldState, %frame, %state ) +{ + %action = %this.createAction( ActionEditTrigger, "Edit trigger" ); + %action.seqName = %seqName; + %action.oldFrame = %oldFrame; + %action.oldState = %oldState; + %action.frame = %frame; + %action.state = %state; + + %this.doAction( %action ); +} + +function ActionEditTrigger::doit( %this ) +{ + if ( ShapeEditor.shape.addTrigger( %this.seqName, %this.frame, %this.state ) && + ShapeEditor.shape.removeTrigger( %this.seqName, %this.oldFrame, %this.oldState ) ) + { + ShapeEdTriggerList.updateItem( %this.oldFrame, %this.oldState, %this.frame, %this.state ); + return true; + } + return false; +} + +function ActionEditTrigger::undo( %this ) +{ + Parent::undo( %this ); + + if ( ShapeEditor.shape.addTrigger( %this.seqName, %this.oldFrame, %this.oldState ) && + ShapeEditor.shape.removeTrigger( %this.seqName, %this.frame, %this.state ) ) + ShapeEdTriggerList.updateItem( %this.frame, %this.state, %this.oldFrame, %this.oldState ); +} + +//------------------------------------------------------------------------------ +// Rename detail +function ShapeEditor::doRenameDetail( %this, %oldName, %newName ) +{ + %action = %this.createAction( ActionRenameDetail, "Rename detail" ); + %action.oldName = %oldName; + %action.newName = %newName; + + %this.doAction( %action ); +} + +function ActionRenameDetail::doit( %this ) +{ + if ( ShapeEditor.shape.renameDetailLevel( %this.oldName, %this.newName ) ) + { + ShapeEdPropWindow.update_onDetailRenamed( %this.oldName, %this.newName ); + return true; + } + return false; +} + +function ActionRenameDetail::undo( %this ) +{ + Parent::undo( %this ); + if ( ShapeEditor.shape.renameDetailLevel( %this.newName, %this.oldName ) ) + ShapeEdPropWindow.update_onDetailRenamed( %this.newName, %this.oldName ); +} + +//------------------------------------------------------------------------------ +// Edit detail size +function ShapeEditor::doEditDetailSize( %this, %oldSize, %newSize ) +{ + %action = %this.createAction( ActionEditDetailSize, "Edit detail size" ); + %action.oldSize = %oldSize; + %action.newSize = %newSize; + + %this.doAction( %action ); +} + +function ActionEditDetailSize::doit( %this ) +{ + %dl = ShapeEditor.shape.setDetailLevelSize( %this.oldSize, %this.newSize ); + if ( %dl != -1 ) + { + ShapeEdPropWindow.update_onDetailSizeChanged( %this.oldSize, %this.newSize ); + return true; + } + return false; +} + +function ActionEditDetailSize::undo( %this ) +{ + Parent::undo( %this ); + %dl = ShapeEditor.shape.setDetailLevelSize( %this.newSize, %this.oldSize ); + if ( %dl != -1 ) + ShapeEdPropWindow.update_onDetailSizeChanged( %this.newSize, %this.oldSize ); +} + +//------------------------------------------------------------------------------ +// Rename object +function ShapeEditor::doRenameObject( %this, %oldName, %newName ) +{ + %action = %this.createAction( ActionRenameObject, "Rename object" ); + %action.oldName = %oldName; + %action.newName = %newName; + + %this.doAction( %action ); +} + +function ActionRenameObject::doit( %this ) +{ + if ( ShapeEditor.shape.renameObject( %this.oldName, %this.newName ) ) + { + ShapeEdPropWindow.update_onObjectRenamed( %this.oldName, %this.newName ); + return true; + } + return false; +} + +function ActionRenameObject::undo( %this ) +{ + Parent::undo( %this ); + if ( ShapeEditor.shape.renameObject( %this.newName, %this.oldName ) ) + ShapeEdPropWindow.update_onObjectRenamed( %this.newName, %this.oldName ); +} + +//------------------------------------------------------------------------------ +// Edit mesh size +function ShapeEditor::doEditMeshSize( %this, %meshName, %size ) +{ + %action = %this.createAction( ActionEditMeshSize, "Edit mesh size" ); + %action.meshName = stripTrailingNumber( %meshName ); + %action.oldSize = getTrailingNumber( %meshName ); + %action.newSize = %size; + + %this.doAction( %action ); +} + +function ActionEditMeshSize::doit( %this ) +{ + if ( ShapeEditor.shape.setMeshSize( %this.meshName SPC %this.oldSize, %this.newSize ) ) + { + ShapeEdPropWindow.update_onMeshSizeChanged( %this.meshName, %this.oldSize, %this.newSize ); + return true; + } + return false; +} + +function ActionEditMeshSize::undo( %this ) +{ + Parent::undo( %this ); + if ( ShapeEditor.shape.setMeshSize( %this.meshName SPC %this.newSize, %this.oldSize ) ) + ShapeEdPropWindow.update_onMeshSizeChanged( %this.meshName, %this.oldSize, %this.oldSize ); +} + +//------------------------------------------------------------------------------ +// Edit billboard type +function ShapeEditor::doEditMeshBillboard( %this, %meshName, %type ) +{ + %action = %this.createAction( ActionEditMeshBillboard, "Edit mesh billboard" ); + %action.meshName = %meshName; + %action.oldType = %this.shape.getMeshType( %meshName ); + %action.newType = %type; + + %this.doAction( %action ); +} + +function ActionEditMeshBillboard::doit( %this ) +{ + if ( ShapeEditor.shape.setMeshType( %this.meshName, %this.newType ) ) + { + switch$ ( ShapeEditor.shape.getMeshType( %this.meshName ) ) + { + case "normal": ShapeEdDetails-->bbType.setSelected( 0, false ); + case "billboard": ShapeEdDetails-->bbType.setSelected( 1, false ); + case "billboardzaxis": ShapeEdDetails-->bbType.setSelected( 2, false ); + } + return true; + } + return false; +} + +function ActionEditMeshBillboard::undo( %this ) +{ + Parent::undo( %this ); + if ( ShapeEditor.shape.setMeshType( %this.meshName, %this.oldType ) ) + { + %id = ShapeEdDetailTree.getSelectedItem(); + if ( ( %id > 1 ) && ( ShapeEdDetailTree.getItemText( %id ) $= %this.meshName ) ) + { + switch$ ( ShapeEditor.shape.getMeshType( %this.meshName ) ) + { + case "normal": ShapeEdDetails-->bbType.setSelected( 0, false ); + case "billboard": ShapeEdDetails-->bbType.setSelected( 1, false ); + case "billboardzaxis": ShapeEdDetails-->bbType.setSelected( 2, false ); + } + } + } +} + +//------------------------------------------------------------------------------ +// Edit object node +function ShapeEditor::doSetObjectNode( %this, %objName, %node ) +{ + %action = %this.createAction( ActionSetObjectNode, "Set object node" ); + %action.objName = %objName; + %action.oldNode = %this.shape.getObjectNode( %objName ); + %action.newNode = %node; + + %this.doAction( %action ); +} + +function ActionSetObjectNode::doit( %this ) +{ + if ( ShapeEditor.shape.setObjectNode( %this.objName, %this.newNode ) ) + { + ShapeEdPropWindow.update_onObjectNodeChanged( %this.objName ); + return true; + } + return false; +} + +function ActionSetObjectNode::undo( %this ) +{ + Parent::undo( %this ); + if ( ShapeEditor.shape.setObjectNode( %this.objName, %this.oldNode ) ) + ShapeEdPropWindow.update_onObjectNodeChanged( %this.objName ); +} + +//------------------------------------------------------------------------------ +// Remove mesh +function ShapeEditor::doRemoveMesh( %this, %meshName ) +{ + %action = %this.createAction( ActionRemoveMesh, "Remove mesh" ); + %action.meshName = %meshName; + + %this.doAction( %action ); +} + +function ActionRemoveMesh::doit( %this ) +{ + if ( ShapeEditor.shape.removeMesh( %this.meshName ) ) + { + ShapeEdPropWindow.update_onMeshRemoved( %this.meshName ); + return true; + } + return false; +} + +function ActionRemoveMesh::undo( %this ) +{ + Parent::undo( %this ); +} + +//------------------------------------------------------------------------------ +// Add meshes from file +function ShapeEditor::doAddMeshFromFile( %this, %filename, %size ) +{ + %action = %this.createAction( ActionAddMeshFromFile, "Add mesh from file" ); + %action.filename = %filename; + %action.size = %size; + + %this.doAction( %action ); +} + +function ActionAddMeshFromFile::doit( %this ) +{ + %this.meshList = ShapeEditor.addLODFromFile( ShapeEditor.shape, %this.filename, %this.size, 1 ); + if ( %this.meshList !$= "" ) + { + %count = getFieldCount( %this.meshList ); + for ( %i = 0; %i < %count; %i++ ) + ShapeEdPropWindow.update_onMeshAdded( getField( %this.meshList, %i ) ); + + ShapeEdMaterials.updateMaterialList(); + + return true; + } + return false; +} + +function ActionAddMeshFromFile::undo( %this ) +{ + // Remove all the meshes we added + %count = getFieldCount( %this.meshList ); + for ( %i = 0; %i < %count; %i ++ ) + { + %name = getField( %this.meshList, %i ); + ShapeEditor.shape.removeMesh( %name ); + ShapeEdPropWindow.update_onMeshRemoved( %name ); + } + ShapeEdMaterials.updateMaterialList(); +} + +//------------------------------------------------------------------------------ +// Add/edit collision geometry +function ShapeEditor::doEditCollision( %this, %type, %target, %depth, %merge, %concavity, + %maxVerts, %boxMax, %sphereMax, %capsuleMax ) +{ + %colData = ShapeEdColWindow.lastColSettings; + + %action = %this.createAction( ActionEditCollision, "Edit shape collision" ); + + %action.oldType = getField( %colData, 0 ); + %action.oldTarget = getField( %colData, 1 ); + %action.oldDepth = getField( %colData, 2 ); + %action.oldMerge = getField( %colData, 3 ); + %action.oldConcavity = getField( %colData, 4 ); + %action.oldMaxVerts = getField( %colData, 5 ); + %action.oldBoxMax = getField( %colData, 6 ); + %action.oldSphereMax = getField( %colData, 7 ); + %action.oldCapsuleMax = getField( %colData, 8 ); + + %action.newType = %type; + %action.newTarget = %target; + %action.newDepth = %depth; + %action.newMerge = %merge; + %action.newConcavity = %concavity; + %action.newMaxVerts = %maxVerts; + %action.newBoxMax = %boxMax; + %action.newSphereMax = %sphereMax; + %action.newCapsuleMax = %capsuleMax; + + %this.doAction( %action ); +} + +function ActionEditCollision::updateCollision( %this, %type, %target, %depth, %merge, %concavity, + %maxVerts, %boxMax, %sphereMax, %capsuleMax ) +{ + %colDetailSize = -1; + %colNode = "Col" @ %colDetailSize; + + // TreeView items are case sensitive, but TSShape names are not, so fixup case + // if needed + %index = ShapeEditor.shape.getNodeIndex( %colNode ); + if ( %index != -1 ) + %colNode = ShapeEditor.shape.getNodeName( %index ); + + // First remove the old detail and collision nodes + %meshList = ShapeEditor.getDetailMeshList( %colDetailSize ); + %meshCount = getFieldCount( %meshList ); + if ( %meshCount > 0 ) + { + ShapeEditor.shape.removeDetailLevel( %colDetailSize ); + for ( %i = 0; %i < %meshCount; %i++ ) + ShapeEdPropWindow.update_onMeshRemoved( getField( %meshList, %i ) ); + } + + %nodeList = ShapeEditor.getNodeNames( %colNode, "" ); + %nodeCount = getFieldCount( %nodeList ); + if ( %nodeCount > 0 ) + { + for ( %i = 0; %i < %nodeCount; %i++ ) + ShapeEditor.shape.removeNode( getField( %nodeList, %i ) ); + ShapeEdPropWindow.update_onNodeRemoved( %nodeList, %nodeCount ); + } + + // Add the new node and geometry + if ( %type $= "" ) + return; + + if ( !ShapeEditor.shape.addCollisionDetail( %colDetailSize, %type, %target, + %depth, %merge, %concavity, %maxVerts, + %boxMax, %sphereMax, %capsuleMax ) ) + return false; + + // Update UI + %meshList = ShapeEditor.getDetailMeshList( %colDetailSize ); + ShapeEdPropWindow.update_onNodeAdded( %colNode, ShapeEditor.shape.getNodeCount() ); // will also add child nodes + %count = getFieldCount( %meshList ); + for ( %i = 0; %i < %count; %i++ ) + ShapeEdPropWindow.update_onMeshAdded( getField( %meshList, %i ) ); + + ShapeEdColWindow.lastColSettings = %type TAB %target TAB %depth TAB %merge TAB + %concavity TAB %maxVerts TAB %boxMax TAB %sphereMax TAB %capsuleMax; + ShapeEdColWindow.update_onCollisionChanged(); + + return true; +} + +function ActionEditCollision::doit( %this ) +{ + ShapeEdWaitGui.show( "Generating collision geometry..." ); + %success = %this.updateCollision( %this.newType, %this.newTarget, %this.newDepth, %this.newMerge, + %this.newConcavity, %this.newMaxVerts, %this.newBoxMax, + %this.newSphereMax, %this.newCapsuleMax ); + ShapeEdWaitGui.hide(); + + return %success; +} + +function ActionEditCollision::undo( %this ) +{ + Parent::undo( %this ); + + ShapeEdWaitGui.show( "Generating collision geometry..." ); + %this.updateCollision( %this.oldType, %this.oldTarget, %this.oldDepth, %this.oldMerge, + %this.oldConcavity, %this.oldMaxVerts, %this.oldBoxMax, + %this.oldSphereMax, %this.oldCapsuleMax ); + ShapeEdWaitGui.hide(); +} + +//------------------------------------------------------------------------------ +// Remove Detail + +function ShapeEditor::doRemoveDetail( %this, %size ) +{ + %action = %this.createAction( ActionRemoveDetail, "Remove detail level" ); + %action.size = %size; + + %this.doAction( %action ); +} + +function ActionRemoveDetail::doit( %this ) +{ + %meshList = ShapeEditor.getDetailMeshList( %this.size ); + if ( ShapeEditor.shape.removeDetailLevel( %this.size ) ) + { + %meshCount = getFieldCount( %meshList ); + for ( %i = 0; %i < %meshCount; %i++ ) + ShapeEdPropWindow.update_onMeshRemoved( getField( %meshList, %i ) ); + return true; + } + return false; +} + +function ActionRemoveDetail::undo( %this ) +{ + Parent::undo( %this ); +} + +//------------------------------------------------------------------------------ +// Update bounds +function ShapeEditor::doSetBounds( %this ) +{ + %action = %this.createAction( ActionSetBounds, "Set bounds" ); + %action.oldBounds = ShapeEditor.shape.getBounds(); + %action.newBounds = ShapeEdShapeView.computeShapeBounds(); + + %this.doAction( %action ); +} + +function ActionSetBounds::doit( %this ) +{ + return ShapeEditor.shape.setBounds( %this.newBounds ); +} + +function ActionSetBounds::undo( %this ) +{ + Parent::undo( %this ); + + ShapeEditor.shape.setBounds( %this.oldBounds ); +} + +//------------------------------------------------------------------------------ +// Add/edit imposter +function ShapeEditor::doEditImposter( %this, %dl, %detailSize, %bbEquatorSteps, %bbPolarSteps, + %bbDetailLevel, %bbDimension, %bbIncludePoles, %bbPolarAngle ) +{ + %action = %this.createAction( ActionEditImposter, "Edit imposter" ); + %action.oldDL = %dl; + if ( %action.oldDL != -1 ) + { + %action.oldSize = ShapeEditor.shape.getDetailLevelSize( %dl ); + %action.oldImposter = ShapeEditor.shape.getImposterSettings( %dl ); + } + %action.newSize = %detailSize; + %action.newImposter = "1" TAB %bbEquatorSteps TAB %bbPolarSteps TAB %bbDetailLevel TAB + %bbDimension TAB %bbIncludePoles TAB %bbPolarAngle; + + %this.doAction( %action ); +} + +function ActionEditImposter::doit( %this ) +{ + // Unpack new imposter settings + for ( %i = 0; %i < 7; %i++ ) + %val[%i] = getField( %this.newImposter, %i ); + + ShapeEdWaitGui.show( "Generating imposter bitmaps..." ); + + // Need to de-highlight the current material, or the imposter will have the + // highlight effect baked in! + ShapeEdMaterials.updateSelectedMaterial( false ); + + %dl = ShapeEditor.shape.addImposter( %this.newSize, %val[1], %val[2], %val[3], %val[4], %val[5], %val[6] ); + ShapeEdWaitGui.hide(); + + // Restore highlight effect + ShapeEdMaterials.updateSelectedMaterial( ShapeEdMaterials-->highlightMaterial.getValue() ); + + if ( %dl != -1 ) + { + ShapeEdShapeView.refreshShape(); + ShapeEdShapeView.currentDL = %dl; + ShapeEdAdvancedWindow-->detailSize.setText( %this.newSize ); + ShapeEdDetails-->meshSize.setText( %this.newSize ); + ShapeEdDetails.update_onDetailsChanged(); + + return true; + } + return false; +} + +function ActionEditImposter::undo( %this ) +{ + Parent::undo( %this ); + + // If this was a new imposter, just remove it. Otherwise restore the old settings + if ( %this.oldDL < 0 ) + { + if ( ShapeEditor.shape.removeImposter() ) + { + ShapeEdShapeView.refreshShape(); + ShapeEdShapeView.currentDL = 0; + ShapeEdDetails.update_onDetailsChanged(); + } + } + else + { + // Unpack old imposter settings + for ( %i = 0; %i < 7; %i++ ) + %val[%i] = getField( %this.oldImposter, %i ); + + ShapeEdWaitGui.show( "Generating imposter bitmaps..." ); + + // Need to de-highlight the current material, or the imposter will have the + // highlight effect baked in! + ShapeEdMaterials.updateSelectedMaterial( false ); + + %dl = ShapeEditor.shape.addImposter( %this.oldSize, %val[1], %val[2], %val[3], %val[4], %val[5], %val[6] ); + ShapeEdWaitGui.hide(); + + // Restore highlight effect + ShapeEdMaterials.updateSelectedMaterial( ShapeEdMaterials-->highlightMaterial.getValue() ); + + if ( %dl != -1 ) + { + ShapeEdShapeView.refreshShape(); + ShapeEdShapeView.currentDL = %dl; + ShapeEdAdvancedWindow-->detailSize.setText( %this.oldSize ); + ShapeEdDetails-->meshSize.setText( %this.oldSize ); + } + } +} + +//------------------------------------------------------------------------------ +// Remove imposter +function ShapeEditor::doRemoveImposter( %this ) +{ + %action = %this.createAction( ActionRemoveImposter, "Remove imposter" ); + %dl = ShapeEditor.shape.getImposterDetailLevel(); + if ( %dl != -1 ) + { + %action.oldSize = ShapeEditor.shape.getDetailLevelSize( %dl ); + %action.oldImposter = ShapeEditor.shape.getImposterSettings( %dl ); + %this.doAction( %action ); + } +} + +function ActionRemoveImposter::doit( %this ) +{ + if ( ShapeEditor.shape.removeImposter() ) + { + ShapeEdShapeView.refreshShape(); + ShapeEdShapeView.currentDL = 0; + ShapeEdDetails.update_onDetailsChanged(); + + return true; + } + return false; +} + +function ActionRemoveImposter::undo( %this ) +{ + Parent::undo( %this ); + + // Unpack the old imposter settings + for ( %i = 0; %i < 7; %i++ ) + %val[%i] = getField( %this.oldImposter, %i ); + + ShapeEdWaitGui.show( "Generating imposter bitmaps..." ); + %dl = ShapeEditor.shape.addImposter( %this.oldSize, %val[1], %val[2], %val[3], %val[4], %val[5], %val[6] ); + ShapeEdWaitGui.hide(); + + if ( %dl != -1 ) + { + ShapeEdShapeView.refreshShape(); + ShapeEdShapeView.currentDL = %dl; + ShapeEdAdvancedWindow-->detailSize.setText( %this.oldSize ); + ShapeEdDetails-->meshSize.setText( %this.oldSize ); + ShapeEdDetails.update_onDetailsChanged(); + } +} diff --git a/Templates/Empty/game/tools/shapeEditor/scripts/shapeEditorHints.ed.cs b/Templates/Empty/game/tools/shapeEditor/scripts/shapeEditorHints.ed.cs new file mode 100644 index 000000000..c8a704644 --- /dev/null +++ b/Templates/Empty/game/tools/shapeEditor/scripts/shapeEditorHints.ed.cs @@ -0,0 +1,142 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// The Shape Editor tool can provide some simple hints about which nodes and +// sequences are required/desired for a particular type of shape to work with +// Torque. The following objects define the node and sequence hints, and the +// Shape Editor gui marks them as present or not-present in the current shape. + +new SimGroup (ShapeHintControls) +{ +}; + +new SimGroup (ShapeHintGroup) +{ + new ScriptObject() + { + objectType = "ShapeBase"; + node0 = "cam" TAB "This node is used as the 3rd person camera position."; + node1 = "eye" TAB "This node is used as the 1st person camera position."; + node2 = "ear" TAB "This node is where the SFX listener is mounted on (if missing, eye is used)."; + node3 = "mount0-31" TAB "Nodes used for mounting ShapeBaseImages to this object"; + node4 = "AIRepairNode" TAB "unused"; + sequence0 = "Visibility" TAB "2 frame sequence used to show object damage (start=no damage, end=fully damaged)"; + sequence1 = "Damage" TAB "Sequence used to show object damage (start=no damage, end=fully damaged)"; + }; + + new ScriptObject() + { + objectType = "ShapeBaseImageData"; + node0 = "ejectPoint" TAB "Node from which shell casings are emitted (for weapon ShapeImages)"; + node1 = "muzzlePoint" TAB "Node used to fire projectiles and particles (for weapon ShapeImages)"; + node2 = "retractionPoint" TAB "Nearest point to use as muzzle when up against a wall (and muzzle node is inside wall)"; + node3 = "mountPoint" TAB "Where to attach to on this object"; + sequence0 = "ambient" TAB "Cyclic sequence to play while image is mounted"; + sequence1 = "spin" TAB "Cyclic sequence to play while image is mounted"; + }; + + new ScriptObject() + { + objectType = "Player"; + node0 = "Bip01 Pelvis" TAB ""; + node1 = "Bip01 Spine" TAB ""; + node2 = "Bip01 Spine1" TAB ""; + node3 = "Bip01 Spine2" TAB ""; + node4 = "Bip01 Neck" TAB ""; + node5 = "Bip01 Head" TAB ""; + + sequence0 = "head" TAB "Vertical head movement (for looking) (start=full up, end=full down)"; + sequence1 = "headside" TAB "Horizontal head movement (for looking) (start=full left, end=full right)"; + sequence2 = "look" TAB "Vertical arm movement (for looking) (start=full up, end=full down)"; + sequence3 = "light_recoil" TAB "Player has been hit lightly"; + sequence4 = "medium_recoil" TAB "Player has been hit moderately hard"; + sequence5 = "heavy_recoil" TAB "Player has been hit hard"; + + sequence6 = "root" TAB "Player is not moving"; + sequence7 = "run" TAB "Player is running forward"; + sequence8 = "back" TAB "Player is running backward"; + sequence9 = "side" TAB "Player is running sideways left (strafing)"; + sequence9 = "side_right" TAB "Player is running sideways right (strafing)"; + + sequence10 = "crouch_root" TAB "Player is crouched and not moving"; + sequence11 = "crouch_forward" TAB "Player is crouched and moving forward"; + sequence11 = "crouch_backward" TAB "Player is crouched and moving backward"; + sequence11 = "crouch_side" TAB "Player is crouched and moving sideways left"; + sequence11 = "crouch_right" TAB "Player is crouched and moving sideways right"; + + sequence12 = "prone_root" TAB "Player is lying down and not moving"; + sequence13 = "prone_forward" TAB "Player is lying down and moving forward"; + sequence13 = "prone_backward" TAB "Player is lying down and moving backward"; + + sequence14 = "swim_root" TAB "Player is swimming and not moving"; + sequence15 = "swim_forward" TAB "Player is swimming and moving forward"; + sequence16 = "swim_backward" TAB "Player is swimming and moving backward"; + sequence17 = "swim_left" TAB "Player is swimming and moving left"; + sequence18 = "swim_right" TAB "Player is swimming and moving right"; + + sequence19 = "fall" TAB "Player is falling"; + sequence20 = "jump" TAB "Player has jumped from a moving start"; + sequence21 = "standjump" TAB "Player has jumped from a standing start"; + sequence22 = "land" TAB "Player has landed after falling"; + sequence23 = "jet" TAB "Player is jetting"; + + sequence24 = "death1-11" TAB "Player has been killed (only one of these will play)"; + }; + + new ScriptObject() + { + objectType = "WheeledVehicle"; + node0 = "hub0-7" TAB "Placement node for wheel X"; + sequence0 = "spring0-7" TAB "Spring suspension for wheel X (start=fully compressed, end=fully extended)"; + sequence1 = "steering" TAB "Steering mechanism (start=full left, end=full right)"; + sequence2 = "brakelight" TAB "Sequence to play when braking (start=brakes off, end=brakes on)"; + }; + + new ScriptObject() + { + objectType = "HoverVehicle"; + node0 = "JetNozzle0-3" TAB "Nodes for jet engine exhaust particle emission"; + node1 = "JetNozzleX" TAB "Nodes for jet engine exhaust particle emission"; + sequence0 = "activateBack" TAB "Non-cyclic sequence to play when vehicle first starts moving backwards"; + sequence1 = "maintainBack" TAB "Cyclic sequence to play when vehicle continues moving backwards"; + }; + + new ScriptObject() + { + objectType = "FlyingVehicle"; + node0 = "JetNozzle0-3" TAB "Nodes for jet engine exhaust particle emission"; + node1 = "JetNozzleX" TAB "Nodes for jet engine exhaust particle emission"; + node2 = "JetNozzleY" TAB "Nodes for jet engine exhaust particle emission"; + node3 = "contrail0-3" TAB "Nodes for contrail particle emission"; + sequence0 = "activateBack" TAB "Sequence to play when vehicle first starts thrusting backwards"; + sequence1 = "maintainBack" TAB "Cyclic sequence to play when vehicle continues thrusting backwards"; + sequence2 = "activateBot" TAB "Non-cyclic sequence to play when vehicle first starts thrusting upwards"; + sequence3 = "maintainBot" TAB "Cyclic sequence to play when vehicle continues thrusting upwards"; + }; + + new ScriptObject() + { + objectType = "Projectile"; + sequence0 = "activate" TAB "Non-cyclic sequence to play when projectile is first created"; + sequence1 = "maintain" TAB "Cyclic sequence to play for remainder of projectile lifetime"; + }; +}; diff --git a/Templates/Empty/game/tools/worldEditor/gui/AddFMODProjectDlg.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/AddFMODProjectDlg.ed.gui new file mode 100644 index 000000000..ed0a85bd4 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/AddFMODProjectDlg.ed.gui @@ -0,0 +1,284 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AddFMODProjectDlg,EditorGuiGroup) { + isContainer = "1"; + Profile = "GuiOverlayProfile";//DefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiWindowCtrl() { + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "AddFMODProjectDlg.onCancel();"; + EdgeSnap = "1"; + text = "Add FMOD Designer Audio"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "361 196"; + Extent = "303 236"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + internalName = "window"; + + new GuiBitmapBorderCtrl() { + isContainer = "1"; + Profile = "GuiGroupBorderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 26"; + Extent = "291 160"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Path to the compiled event file (.fev):"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiAutoSizeTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 51"; + Extent = "176 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "7 72"; + Extent = "254 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "fileNameField"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "7 127"; + Extent = "254 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "mediaPathField"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Name for the SFXFMODProject object:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiAutoSizeTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 10"; + Extent = "189 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "7 30"; + Extent = "277 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "projectNameField"; + canSaveDynamicFields = "0"; + }; + new GuiMLTextCtrl() { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + text = "Path to the project\'s media files (leave empty if files are in same directory as the project file):"; + useURLMouseCursor = "0"; + isContainer = "0"; + Profile = "GuiMLTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 96"; + Extent = "276 26"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "..."; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "266 72"; + Extent = "18 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + command = "AddFMODProjectDlg.onSelectFile();"; + }; + new GuiButtonCtrl() { + text = "..."; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "266 127"; + Extent = "18 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + command = "AddFMODProjectDlg.onSelectMediaPath();"; + }; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "206 196"; + Extent = "90 30"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "AddFMODProjectDlg.onCancel();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "OK"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "112 196"; + Extent = "90 30"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "AddFMODProjectDlg.onOK();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/worldEditor/gui/AxisGizmoSettingsTab.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/AxisGizmoSettingsTab.ed.gui new file mode 100644 index 000000000..5b364017f --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/AxisGizmoSettingsTab.ed.gui @@ -0,0 +1,524 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AxisGizmoSettingsTab,EditorGuiGroup) { + isContainer = "1"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiTabPageCtrl(EAxisGizmoSettingsPage) { + fitBook = "1"; + text = "Axis Gizmo"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "GuiSolidDefaultProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "208 568"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "GuiScrollProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "208 568"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + extent = "208 210"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Gizmo"; + Margin = "0 0 0 -3"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "-1 0"; + Extent = "208 79"; + Docking = "none"; + + new GuiTextCtrl() { + text = "Rotate Scalar:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 6"; + extent = "70 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + text = "0.8"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextEditNumericProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "81 5"; + extent = "121 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "AxisGizmo/mouseRotateScalar"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + new GuiTextCtrl() { + text = "Scale Scalar:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 26"; + extent = "70 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + text = "0.8"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextEditNumericProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "81 24"; + extent = "121 17"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "AxisGizmo/mouseScaleScalar"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Render When Manipulated"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 44"; + extent = "140 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowCheckbox"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "AxisGizmo/renderWhenUsed"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Render Tool Text"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 61"; + extent = "140 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowCheckbox"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "AxisGizmo/renderInfoText"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + }; + }; + }; + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Grid"; + Margin = "0 0 0 -3"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "-1 0"; + Extent = "208 82"; + Docking = "none"; + + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Render Plane"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 4"; + extent = "140 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowCheckbox"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "AxisGizmo/Grid/renderPlane"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Render Plane Hashes"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 21"; + extent = "140 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowCheckbox"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "AxisGizmo/Grid/renderPlaneHashes"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + new GuiTextCtrl() { + text = "Plane Size:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 40"; + extent = "70 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + text = "500"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextEditNumericProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "81 38"; + extent = "121 17"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "AxisGizmo/Grid/planeDim"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + new GuiControl() { + isContainer = "1"; + profile = "GuiDefaultProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "5 58"; + extent = "208 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "AxisGizmo/Grid/gridColor"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + + new GuiTextCtrl() { + text = "Plane Color:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 2"; + extent = "70 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "76 0"; + extent = "104 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "0 0 0 0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "184 2"; + extent = "14 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + }; + }; + }; + }; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/worldEditor/gui/CameraSettingsTab.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/CameraSettingsTab.ed.gui new file mode 100644 index 000000000..22dcb2c56 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/CameraSettingsTab.ed.gui @@ -0,0 +1,429 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(CameraSettingsTab,EditorGuiGroup) { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiTabPageCtrl(ECameraSettingsPage) { + fitBook = "1"; + text = "Camera Settings"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiSolidDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "245 568"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "245 568"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + internalName = "content"; + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + extent = "245 210"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Mouse Control"; + Margin = "0 0 0 -3"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "-1 0"; + Extent = "208 41"; + Docking = "none"; + + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Invert Y Axis"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 5"; + extent = "140 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowCheckbox"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "Camera/invertYAxis"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Invert X Axis"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 22"; + extent = "140 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowCheckbox"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "Camera/invertXAxis"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + }; + }; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- + +function ECameraSettingsPage::init(%this) +{ + %this.currentLevel = ""; + %this.currentRolloutCtrl = ""; + + %levelInfoPath = "LevelInformation/levels"; + for( %fieldName = EditorSettings.findFirstValue(%levelInfoPath, true, true); + %fieldName !$= ""; + %fieldName = EditorSettings.findNextValue() ) + { + %fieldSlashPos = 0; + %levelSlashPos = 0; + while( strpos( %fieldName, "/", %fieldSlashPos ) != -1 ) + { + %levelSlashPos = %fieldSlashPos; + + %temp = strpos( %fieldName, "/", %fieldSlashPos ); + %fieldSlashPos = %temp + 1; + } + %levelName = getSubStr( %fieldName , %levelSlashPos , ((%fieldSlashPos - %levelSlashPos) - 1)); + + for( %i = 0; %i < %this-->content.getCount(); %i++ ) + { + %alreadyExist = false; + if( %this-->content.getObject(%i).caption $= %levelName ) + { + %alreadyExist = true; + break; + } + } + + if( %this.currentLevel !$= %levelName && !%alreadyExist ) + { + //Hold current level and reset gui params + %this.currentLevel = %levelName; + //%this.currentLevel = "\""@%levelName@"\""; + + //Create and hold current rollout ctrl + %this.currentRolloutCtrl = new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = %levelName; + Margin = "0 0 0 -3"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ //spacer + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "208 2"; + }; + + new GuiContainer(){ + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "208 22"; + Docking = "none"; + + new GuiTextCtrl() { + text = "Camera Speed Min:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 3"; + extent = "96 16"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextEditNumericProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "106 2"; + extent = "95 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + editorSettingsRead = "EditorGui.readCameraSettings( \"" @ %levelName @ "\" );"; + editorSettingsValue = "LevelInformation/levels/" @ %levelName @ "/cameraSpeedMin"; + editorSettingsWrite = "EditorGui.writeCameraSettings( \"" @ %levelName @ "\" );"; // not in use + }; + }; + new GuiContainer(){ + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "208 22"; + Docking = "none"; + + new GuiTextCtrl() { + text = "Camera Speed Max:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 3"; + extent = "96 16"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextEditNumericProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "106 2"; + extent = "95 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + editorSettingsRead = "EditorGui.readCameraSettings( \"" @ %levelName @ "\" );"; + editorSettingsValue = "LevelInformation/levels/" @ %levelName @ "/cameraSpeedMax"; + editorSettingsWrite = "EditorGui.writeCameraSettings( \"" @ %levelName @ "\" );"; // not in use + }; + }; + new GuiContainer(){ + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "208 24"; + Docking = "none"; + + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "5 2"; + Extent = "196 18"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ECameraSettingsPage.deleteCameraSettingsGroup(\"" @ %levelName @ "\", $ThisControl.getParent().getParent().getParent());"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Delete Level Settings"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + }; + }; + }; + }; + %this-->content.add(%this.currentRolloutCtrl); + } + } +} + +function ECameraSettingsPage::deleteCameraSettingsGroup( %this, %levelName, %rolloutCtrl ) +{ + if( %levelName $= EditorGui.levelName ) + { + MessageBoxOK("Error", "You may not delete the settings group associated with the currently loaded level"); + return; + } + + %levelInfoPath = "LevelInformation/levels/" @ %levelName; + for( %fieldName = EditorSettings.findFirstValue(%levelInfoPath, true, true); + %fieldName !$= ""; + %fieldName = EditorSettings.findNextValue() ) + { + EditorSettings.remove( %fieldName, true ); + } + + %rolloutCtrl.delete(); +} diff --git a/Templates/Empty/game/tools/worldEditor/gui/EditorChooseLevelGui.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/EditorChooseLevelGui.ed.gui new file mode 100644 index 000000000..7a9042124 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/EditorChooseLevelGui.ed.gui @@ -0,0 +1,269 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiContainer(EditorChooseLevelGui, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiContentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiChunkedBitmapCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiContentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = "art/gui/background"; + useVariable = "0"; + tile = "0"; + }; +}; + +%guiContent = new GuiContainer(EditorChooseLevelContainer, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiContentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCtrl(EditorChooseLevelWindow) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + Position = "416 187"; + Extent = "192 393"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Level Selector"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "10 21"; + Extent = "171 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "1: Edit an Existing Level"; + maxLength = "255"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "42 360"; + Extent = "107 23"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "WE_ReturnToMainMenu();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Play Game"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "10 38"; + Extent = "171 194"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = false; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "4 0"; + + new GuiMLTextCtrl(WE_LevelList) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiMLTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 1"; + Extent = "148 70"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "1"; + }; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "10 250"; + Extent = "171 87"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = false; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "4 0"; + + new GuiMLTextCtrl(WE_TemplateList) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiMLTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 1"; + Extent = "148 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "1"; + }; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "10 232"; + Extent = "174 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "2: Create New from Template"; + maxLength = "255"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "10 338"; + Extent = "174 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "3: Play Game from Start"; + maxLength = "255"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/worldEditor/gui/EditorGui.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/EditorGui.ed.gui new file mode 100644 index 000000000..b042ae76a --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/EditorGui.ed.gui @@ -0,0 +1,1304 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiContainer(EditorGui,EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + + new GuiContainer(EditorGuiToolbar) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "menubarProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 32"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + + new GuiBitmapButtonCtrl(EHWorldEditor) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "4 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = ""; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Open the WorldEditor"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/toolbar/world"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(EHGuiEditor) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "34 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "toggleEditor( true ); GuiEdit(); $GuiEditorBtnPressed = true;"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Open the GuiEditor"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/toolbar/gui"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "64 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "Editor.close(\"PlayGui\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Play Game"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/toolbar/playbutton"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + position = "98 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-h.png"; + }; + + new GuiBitmapButtonCtrl(EWorldEditorToggleCamera) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "102 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "CameraTypesDropdownToggle();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Toggle Camera Modes"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/toolbar/player"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + + new GuiBitmapCtrl(){ + HorizSizing = "left"; + VertSizing = "top"; + Position = getWord(EWorldEditorToggleCamera.extent, 0)-6 SPC getWord(EWorldEditorToggleCamera.extent, 1)-6; + Extent = "4 4"; + MinExtent = "4 4"; + bitmap = "core/art/gui/images/dropdown-button-arrow"; + }; + }; + new GuiControl(CameraSpeedDropdownContainer, EditorGuiGroup) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "136 5"; + Extent = "136 27"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 6"; + Extent = "78 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Camera Speed"; + maxLength = "1024"; + }; + new GuiTextEditCtrl(EWorldEditorCameraSpeed) { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + isContainer = "0"; + profile="GuiTextEditDropSliderNumbersOnly"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "78 2"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "EWorldEditorCameraSpeed.updateMenuBar( $ThisControl );"; + hovertime = "1000"; + text = "100"; + maxLength = "4"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "112 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(CameraSpeedDropdownCtrlContainer);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Changes the Camera Speed"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "core/art/gui/images/dropslider"; + }; + }; + /*new GuiPopUpMenuCtrl(EWorldEditorCameraSpeed) { + canSaveDynamicFields = "0"; + internalName = "CameraSpeedDropdown"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "136 7"; + Extent = "130 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + };*/ + new GuiBitmapButtonCtrl(visibilityToggleBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "270 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "VisibilityDropdownToggle();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Toggle Visibility Modes (ALT V)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/visibility-toggle"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + + new GuiBitmapCtrl(){ + HorizSizing = "left"; + VertSizing = "top"; + Position = getWord(visibilityToggleBtn.extent, 0)-6 SPC getWord(visibilityToggleBtn.extent, 1)-6; + Extent = "4 4"; + MinExtent = "4 4"; + bitmap = "core/art/gui/images/dropdown-button-arrow"; + }; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + position = "303 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-h.png"; + }; + + new GuiPopUpMenuCtrl(EWorldEditorAlignPopup) { + canSaveDynamicFields = "0"; + internalName = ""; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "439 2"; + Extent = "70 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + }; + + new GuiContainer(EditorGuiStatusBar) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "menubarProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "0 578"; + Extent = "800 22"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Docking = "Bottom"; + + new GuiTextCtrl(EWorldEditorStatusBarInfo) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "3 2"; + Extent = "450 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Current Tool"; + maxLength = "255"; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "459 2"; + Extent = "2 18"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-h.png"; + }; + + new GuiTextCtrl(EWorldEditorStatusBarSelection) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "469 2"; + Extent = "180 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = ""; + maxLength = "255"; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "659 2"; + Extent = "2 18"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-h.png"; + }; + + new GuiPopUpMenuCtrl(EWorldEditorStatusBarCamera) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "667 2"; + Extent = "120 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "800 2"; + Extent = "2 18"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-h.png"; + }; + }; + + new WorldEditor(EWorldEditor) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "WorldEditorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Docking = "None"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + cameraZRot = "0"; + forceFOV = "0"; + renderMissionArea = "0"; + missionAreaFillColor = "255 0 0 20"; + missionAreaFrameColor = "255 0 0 128"; + allowBorderMove = "0"; + borderMovePixelSize = "20"; + borderMoveSpeed = "0.1"; + consoleFrameColor = "255 0 0 255"; + consoleFillColor = "0 0 0 0"; + consoleSphereLevel = "1"; + consoleCircleSegments = "32"; + consoleLineWidth = "1"; + GizmoProfile = "GlobalGizmoProfile"; + isDirty = "0"; + stickToGround = "0"; + dropAtBounds = "1"; + dropBelowCameraOffset = "15"; + dropType = "screenCenter"; + boundingBoxCollision = "1"; + renderPopupBackground = "1"; + popupBackgroundColor = "100 100 100 255"; + popupTextColor = "255 255 0 255"; + objectTextColor = "255 255 255 255"; + objectsUseBoxCenter = "1"; + objSelectColor = "255 0 0 255"; + objMouseOverSelectColor = "0 0 255 255"; + objMouseOverColor = "0 255 0 255"; + showMousePopupInfo = "1"; + dragRectColor = "255 255 0 255"; + renderObjText = "1"; + renderObjHandle = "1"; + objTextFormat = "$name|class$"; + faceSelectColor = "0 0 100 100"; + renderSelectionBox = "1"; + selectionBoxColor = "255 255 0 255"; + selectionLocked = "0"; + toggleIgnoreList = "0"; + selectHandle = "tools/worldEditor/images/SelectHandle.png"; + defaultHandle = "tools/worldEditor/images/DefaultHandle.png"; + lockedHandle = "tools/worldEditor/images/LockedHandle.png"; + }; + new TerrainEditor(ETerrainEditor) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "WorldEditorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + Docking = "None"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + cameraZRot = "0"; + forceFOV = "0"; + renderMissionArea = "0"; + missionAreaFillColor = "0 0 0 20";//"255 0 0 20"; + missionAreaFrameColor = "0 0 0 128";//"255 0 0 128"; + allowBorderMove = "0"; + borderMovePixelSize = "20"; + borderMoveSpeed = "0.1"; + consoleFrameColor = "0 0 0 255"; + consoleFillColor = "0 0 0 0"; + consoleSphereLevel = "1"; + consoleCircleSegments = "32"; + consoleLineWidth = "1"; + GizmoProfile = "GlobalGizmoProfile"; + isDirty = "0"; + isMissionDirty = "0"; + renderBorder = "1"; + borderHeight = "10"; + borderFillColor = "0 255 0 20"; + borderFrameColor = "0 255 0 128"; + borderLineMode = "0"; + selectionHidden = "1"; + renderVertexSelection = "1"; + processUsesBrush = "0"; + maxBrushSize = "40 40"; + adjustHeightVal = "10"; + setHeightVal = "100"; + scaleVal = "1"; + smoothFactor = "0.1"; + materialGroup = "0"; + softSelectRadius = "50"; + softSelectFilter = "1.000000 0.833333 0.666667 0.500000 0.333333 0.166667 0.000000"; + softSelectDefaultFilter = "1.000000 0.833333 0.666667 0.500000 0.333333 0.166667 0.000000"; + adjustHeightMouseScale = "0.1"; + paintIndex = "-1"; + + new GuiTextCtrl(TESelectionInfo) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "top"; + Position = "288 549"; + Extent = "120 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = " (Selection) #: 0 avg: 0"; + maxLength = "255"; + }; + new GuiTextCtrl(TEMouseBrushInfo) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "top"; + Position = "40 549"; + Extent = "107 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = " (Mouse) #: 0 avg: 0"; + maxLength = "255"; + }; + new GuiTextCtrl(TESelectionInfo1) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfileWhite"; + HorizSizing = "right"; + VertSizing = "top"; + Position = "289 550"; + Extent = "120 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = " (Selection) #: 0 avg: 0"; + maxLength = "255"; + }; + new GuiTextCtrl(TEMouseBrushInfo1) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfileWhite"; + HorizSizing = "right"; + VertSizing = "top"; + Position = "41 550"; + Extent = "107 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = " (Mouse) #: 0 avg: 0"; + maxLength = "255"; + }; + }; + + new GuiControl(RelightStatus) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiSolidDefaultProfile"; + HorizSizing = "center"; + VertSizing = "center"; + Position = "223 277"; + Extent = "353 45"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + + + new GuiProgressBitmapCtrl(RelightProgress) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiRLProgressBitmapProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "5 0"; + Extent = "440 24"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + + }; + new GuiTextCtrl(RelightProgressTxt) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiProgressTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 20"; + Extent = "440 20"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Loading Mission"; + maxLength = "255"; + }; + }; + new GuiControl(RelightMessage) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiSolidDefaultProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "19 570"; + Extent = "583 23"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "5 1"; + Extent = "449 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "A lightmapped object has been altered; relight the scene!"; + maxLength = "255"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "468 2"; + Extent = "75 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Editor.lightScene(\"\", forceAlways); RelightMessage.visible = false;"; + hovertime = "1000"; + text = "Relight Scene"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "548 2"; + Extent = "32 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RelightMessage.visible = false;"; + hovertime = "1000"; + text = "Hide"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; + new GuiControl(PhysicsEditMessage) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiSolidDefaultProfile"; + HorizSizing = "center"; + VertSizing = "top"; + Position = "180 560"; + Extent = "440 32"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "width"; + VertSizing = "center"; + Position = "5 0"; + Extent = "238 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "PHYSICS SIMULATION PAUSED FOR EDITING..."; + maxLength = "255"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "337 3"; + Extent = "43 26"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "physicsStart(); PhysicsEditMessage.visible = false;"; + hovertime = "1000"; + text = "Start"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "392 3"; + Extent = "43 26"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PhysicsEditMessage.visible = false;"; + hovertime = "1000"; + text = "Hide"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; + new GuiContainer(CameraTypesDropdown){ + Profile = "IconDropdownProfile"; + Position = getWord(EWorldEditorToggleCamera.position, 0)-5 SPC getWord(EditorGuiToolbar.extent, 1)-1; + Extent = "137" SPC ((6*28)+6);//97"; + isContainer = "1"; + visible = "0"; + + new GuiDynamicCtrlArrayControl(cameraDropdownArray) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "5 5"; + Extent = "132" SPC getWord(CameraTypesDropdown.extent, 1)-5; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + colCount = "1"; + colSize = "127"; + rowCount = "0"; + RowSize = "64"; + rowSpacing = "3"; + colSpacing = "3"; + autoCellSize = "1"; + fillRowFirst = "0"; + + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "StandardCamera"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiIconButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 5"; + Extent = "127 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "CameraTypesDropdownToggle(); EditorGuiStatusBar.setCamera(\"Standard Camera\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Free Camera"; + hovertime = "1000"; + iconBitmap = "tools/worldEditor/images/toolbar/camera_n"; + groupNum = "0"; + text="Free Camera"; + buttonMargin = "0 4"; + textMargin = "38"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "OrbitCamera"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiIconButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 32"; + Extent = "127 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "CameraTypesDropdownToggle(); EditorGuiStatusBar.setCamera(\"Orbit Camera\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Toggle Orbit Cam"; + hovertime = "1000"; + iconBitmap = "tools/gui/images/menubar/orbit-cam_n"; + groupNum = "0"; + text="Orbit Camera"; + buttonMargin = "0 4"; + textMargin = "38"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "PlayerCamera"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiIconButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 5"; + Extent = "127 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "CameraTypesDropdownToggle(); EditorGuiStatusBar.setCamera(\"1st Person Camera\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Player Camera"; + hovertime = "1000"; + iconBitmap = "tools/worldEditor/images/toolbar/player_n"; + groupNum = "0"; + text="Player Camera"; + buttonMargin = "0 4"; + textMargin = "38"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "trdPersonCamera"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiIconButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 5"; + Extent = "127 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "CameraTypesDropdownToggle(); EditorGuiStatusBar.setCamera(\"3rd Person Camera\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "3rd Person Camera"; + hovertime = "1000"; + iconBitmap = "tools/worldEditor/images/toolbar/3rd-person-camera_n"; + groupNum = "0"; + text="3rd Person Cam"; + buttonMargin = "0 4"; + textMargin = "38"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "NewtonianCamera"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiIconButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 64"; + Extent = "127 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "CameraTypesDropdownToggle(); EditorGuiStatusBar.setCamera(\"Smooth Camera\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Toggle Newtonian Cam"; + hovertime = "1000"; + iconBitmap = "tools/gui/images/menubar/smooth-cam_n"; + groupNum = "0"; + text="Smooth Camera"; + buttonMargin = "0 4"; + textMargin = "38"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "NewtonianRotationCamera"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiIconButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 64"; + Extent = "127 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "CameraTypesDropdownToggle(); EditorGuiStatusBar.setCamera(\"Smooth Rot Camera\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Toggle Smooth Camera with Smooth Rotation"; + hovertime = "1000"; + iconBitmap = "tools/gui/images/menubar/smooth-cam-rot_n"; + groupNum = "0"; + text="Smooth Rotate"; + buttonMargin = "0 4"; + textMargin = "38"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + }; + + new GuiDecoyCtrl(CameraTypesDropdownDecoy) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = getWord(CameraTypesDropdown.extent, 0) SPC getWord(CameraTypesDropdown.extent, 1); + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + useMouseEvents = "1"; + isDecoy = "1"; + }; + + }; + new GuiContainer(VisibilityDropdown){ + Profile = "IconDropdownProfile"; + Position = getWord(visibilityToggleBtn.position, 0)-5 SPC getWord(EditorGuiToolbar.extent, 1)-1; + Extent = "159 261"; //SPC ((6*28)+6);//97"; + isContainer = "1"; + visible = "0"; + + new GuiTabBookCtrl() { + canSaveDynamicFields = "0"; + Profile = "GuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Margin = "3 3 3 3"; + Position = "5 24"; + Extent = "170 226"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + TabPosition = "Top"; + TabHeight = "22"; + TabMargin = "7"; + MinTabWidth = "64"; + + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Profile = "GuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Margin = "-1 0 0 0"; + Position = "0 14"; + Extent = "164 220"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + text = "Viz Toggles"; + maxLength = "255"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Position = "4 12"; + Extent = "156 190"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "2 0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "-2"; + canSaveDynamicFields = "0"; + internalName = "theVisOptionsList"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 0"; + Extent = "156 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + }; + }; + }; + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Profile = "GuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Margin = "-1 0 0 0"; + Position = "0 14"; + Extent = "164 220"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + text = "Class Toggles"; + maxLength = "255"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Position = "4 12"; + Extent = "156 190"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "2 0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "-2"; + canSaveDynamicFields = "0"; + internalName = "theClassVisList"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 0"; + Extent = "156 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + }; + }; + }; + }; + }; +}; + + + + +new GuiMouseEventCtrl(CameraSpeedDropdownCtrlContainer, EditorGuiGroup) { + internalName = "AggregateControl"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiContainer(){ + position = firstWord(CameraSpeedDropdownContainer.position) + firstWord(EditorGuiToolbar.position) + -6 SPC + (getWord(CameraSpeedDropdownContainer, 1)) + 31; + extent = "146 39"; + isContainer = "1"; + Profile = "IconDropdownProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + + new GuiBitmapCtrl(){ // Fast + position = "105 15"; + extent = "2 8"; + bitmap = "core/art/gui/images/separator-h.png"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + }; + new GuiBitmapCtrl(){ // normal + position = "73 15"; + extent = "2 8"; + bitmap = "core/art/gui/images/separator-h.png"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + }; + new GuiBitmapCtrl(){ // slow + position = "41 15"; + extent = "2 8"; + bitmap = "core/art/gui/images/separator-h.png"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + }; + + new GuiSliderCtrl(){ //camera speed slider + internalName = "slider"; + position = "9 17"; + extent = "129 15"; + bitmap = "core/art/gui/images/separator-h.png"; + HorizSizing = "width"; + VertSizing = "bottom"; + range = "1 200"; + ticks = "0"; + value = "100"; + AltCommand = "EWorldEditorCameraSpeed.updateMenuBar( $ThisControl );"; + }; + new GuiTextCtrl(){ // Normal + internalName = "text"; + position = "54 3"; + extent = "39 18"; + text = "Normal"; + Profile = "GuiTextCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + }; + new GuiTextCtrl(){ // - + position = "11 2"; + extent = "39 18"; + text = "-"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + }; + new GuiTextCtrl(){ // + + position = "98 5"; + extent = "39 13"; + text = "+"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + }; + }; +}; +//--- OBJECT WRITE END --- \ No newline at end of file diff --git a/Templates/Empty/game/tools/worldEditor/gui/EditorSettingsWindow.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/EditorSettingsWindow.ed.gui new file mode 100644 index 000000000..9f75f59b2 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/EditorSettingsWindow.ed.gui @@ -0,0 +1,122 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(EditorSettingsWindow,EditorGuiGroup) { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiWindowCollapseCtrl(ESettingsWindow) { + internalName = "EditorSettingsWindow"; + resizeWidth = "0"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Editor Settings"; + closeCommand = "ESettingsWindow.hideDialog();"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "30 200"; + Extent = "319 320"; + MinExtent = "319 100"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTabBookCtrl(ESettingsWindowTabBook) { + TabPosition = "Top"; + TabMargin = "7"; + MinTabWidth = "64"; + TabHeight = "0"; + AllowReorder = "0"; + FrontTabPadding = "0"; + Docking = "Client"; + Margin = "3 1 4 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiTabBookNoBitmapProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "201 21"; + Extent = "334 425"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "AlwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Docking = "Left"; + Margin = "3 1 3 -1"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 21"; + Extent = "100 425"; + MinExtent = "100 50"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextListCtrl(ESettingsWindowList) { + AllowMultipleSelections = "1"; + fitParentWidth = "1"; + isContainer = "0"; + Profile = "GuiListBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "100 2"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/worldEditor/gui/GeneralSettingsTab.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/GeneralSettingsTab.ed.gui new file mode 100644 index 000000000..331e5e114 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/GeneralSettingsTab.ed.gui @@ -0,0 +1,213 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(GeneralSettingsTab,EditorGuiGroup) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiTabPageCtrl(EGeneralSettingsPage) { + fitBook = "1"; + text = "General Settings"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "432 568"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiSolidDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "432 568"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "0"; + dynamicSize = "1"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "1 1"; + extent = "430 41"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiRolloutCtrl() { + caption = "Paths"; + margin = "0 3 0 0"; + defaultHeight = "40"; + expanded = "1"; + clickCollapse = "1"; + hideHeader = "0"; + autoCollapseSiblings = "0"; + position = "0 0"; + extent = "430 41"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiRolloutProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "3"; + dynamicSize = "1"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "0 20"; + extent = "430 18"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiControl() { + position = "0 0"; + extent = "430 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "New Level"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "5 1"; + extent = "70 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextRightProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "tools/levels/BlankRoom.mis"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "81 0"; + extent = "345 17"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/newLevelFile"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + }; + }; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/worldEditor/gui/GenericPromptDialog.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/GenericPromptDialog.ed.gui new file mode 100644 index 000000000..edabbc996 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/GenericPromptDialog.ed.gui @@ -0,0 +1,115 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(GenericPromptDialog) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiOverlayProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCtrl() { + canSaveDynamicFields = "0"; + internalName = "GenericPromptWindow"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + Position = "336 337"; + Extent = "352 93"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Error"; + closeCommand = "Canvas.popDialog(GenericPromptDialog);"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + internalName = "GenericPromptText"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiProgressTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "13 33"; + Extent = "328 15"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Cannot use the Terrain Editor without a terrain"; + maxLength = "1024"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "center"; + VertSizing = "top"; + Position = "134 61"; + Extent = "88 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.popDialog(GenericPromptDialog);"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "OK"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "center"; + VertSizing = "top"; + Position = "230 61"; + Extent = "88 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + Command = "Canvas.popDialog(GenericPromptDialog);"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/worldEditor/gui/ManageBookmarksWindow.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/ManageBookmarksWindow.ed.gui new file mode 100644 index 000000000..54bde1ebd --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/ManageBookmarksWindow.ed.gui @@ -0,0 +1,145 @@ +%guiContent = new GuiControl(ManageBookmarksContainer, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiModelessDialogProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCollapseCtrl(EManageBookmarks) { + internalName = "ManageBookmarksWindow"; + Enabled = "1"; + isContainer = "1"; + profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + resizeWidth = "1"; + resizeHeight = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + position = "50 90"; + extent = "180 306"; + MinExtent = "120 130"; + text = "Camera Bookmark Manager"; + closeCommand = "EManageBookmarks.hideDialog();"; + EdgeSnap = "0"; + canCollapse = "0"; + visible = "0"; + Margin = "5 5 5 5"; + Padding = "5 5 5 5"; + + new GuiControl(){ + horizSizing = "width"; + vertSizing = "bottom"; + position = "4 23"; + extent = "170 20"; + //Docking = "Top"; + + new GuiTextCtrl() { + profile = "GuiCenterTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "1 2"; + extent = "24 16"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + text = "New"; + }; + new GuiTextEditCtrl(EAddBookmarkWindowName) { + profile = "GuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "27 2"; + extent = "126 18"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + historySize = "0"; + }; + new GuiBitmapButtonCtrl(EAddBookmarkWindowOK) { + profile = "GuiButtonProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "158 3"; + extent = "17 17"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + command = "ManageBookmarksContainer.onOK();"; + bitmap = "core/art/gui/images/new"; + helpTag = "0"; + text = "Create"; + tooltip = "Create New Camera Bookmark"; + accelerator = "return"; + }; + }; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "4 12"; + Extent = "300 200"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "26 1 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "2 2"; + + new GuiStackControl() { + internalName = "ManageBookmarksWindowStack"; + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "2"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "300 200"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + }; + }; + }; +}; diff --git a/Templates/Empty/game/tools/worldEditor/gui/ManageSFXParametersWindow.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/ManageSFXParametersWindow.ed.gui new file mode 100644 index 000000000..5a7fcb1da --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/ManageSFXParametersWindow.ed.gui @@ -0,0 +1,240 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ManageSFXParametersContainer,EditorGuiGroup) { + isContainer = "1"; + Profile = "GuiModelessDialogProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + enabled = "1"; + isDecoy = "0"; + + new GuiWindowCollapseCtrl(EManageSFXParameters) { + CollapseGroup = "-1"; + CollapseGroupNum = "-1"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "EManageSFXParameters.setVisible( false );"; + EdgeSnap = "0"; + text = "Audio Parameters"; + Margin = "5 5 5 5"; + Padding = "5 5 5 5"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + position = "49 68"; + Extent = "446 392"; + MinExtent = "120 130"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ManageSFXParametersWindow"; + canSaveDynamicFields = "0"; + + new GuiControl() { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "4 23"; + Extent = "484 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Name"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiAutoSizeTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 2"; + Extent = "29 17"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "36 2"; + Extent = "226 17"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "AddSFXParameterName"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "core/art/gui/images/new"; + autoFit = "0"; + text = "Create"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "266 2"; + Extent = "17 17"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "EManageSFXParameters.createNewParameter( EManageSFXParameters-->AddSFXParameterName.getText() );"; + Accelerator = "return"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Create New SFX Parameter"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "325 1"; + Extent = "113 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "EManageSFXParameters.initList( $ThisControl.getText() );"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "SFXParameterFilter"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Filter"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiAutoSizeTextProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "296 2"; + Extent = "24 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "2 2"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "4 46"; + Extent = "438 344"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "2"; + DynamicSize = "1"; + ChangeChildSizeToFit = "1"; + ChangeChildPosition = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "3 3"; + Extent = "419 10008"; + MinExtent = "16 16"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "SFXParametersStack"; + canSaveDynamicFields = "0"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/worldEditor/gui/ObjectEditorSettingsTab.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/ObjectEditorSettingsTab.ed.gui new file mode 100644 index 000000000..637e3349d --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/ObjectEditorSettingsTab.ed.gui @@ -0,0 +1,1093 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ObjectEditorSettingsTab,EditorGuiGroup) { + isContainer = "1"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiTabPageCtrl(EObjectEditorSettingsPage) { + fitBook = "1"; + text = "Object Editor"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "GuiSolidDefaultProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "208 568"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "GuiScrollProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "208 568"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + extent = "208 210"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Render"; + Margin = "4 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Object Icons"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 10"; + extent = "140 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowCheckbox"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Render/renderObjHandle"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Object Text"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 30"; + extent = "140 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowCheckbox"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Render/renderObjText"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Mouse Popup Info"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 50"; + extent = "140 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowCheckbox"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Render/showMousePopupInfo"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Popup Menu Background"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 70"; + extent = "140 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowCheckbox"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Render/renderPopupBackground"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + }; + }; + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Colors"; + Margin = "0 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiControl() { + isContainer = "1"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 90"; + extent = "204 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Grid/gridColor"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + + new GuiTextCtrl() { + text = "Grid Major:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 1"; + extent = "70 16"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "80 0"; + extent = "104 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + }; + }; + new GuiControl() { + isContainer = "1"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 110"; + extent = "204 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Grid/gridMinorColor"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + + new GuiTextCtrl() { + text = "Grid Minor:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 1"; + extent = "70 16"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "80 0"; + extent = "104 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + }; + }; + new GuiControl() { + isContainer = "1"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 130"; + extent = "204 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Grid/gridOriginColor"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + + new GuiTextCtrl() { + text = "Grid Origin:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 1"; + extent = "70 16"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "80 0"; + extent = "104 17"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + }; + }; + new GuiControl() { + isContainer = "1"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 10"; + extent = "204 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Color/dragRectColor"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + + new GuiTextCtrl() { + text = "Drag Rect:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 1"; + extent = "70 16"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "80 0"; + extent = "104 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + }; + }; + new GuiControl() { + isContainer = "1"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 30"; + extent = "204 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Color/objectTextColor"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + + new GuiTextCtrl() { + text = "Object Text:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 1"; + extent = "70 16"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "80 0"; + extent = "104 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + }; + }; + new GuiControl() { + isContainer = "1"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 50"; + extent = "204 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Color/popupTextColor"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + + new GuiTextCtrl() { + text = "Popup Text:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 1"; + extent = "70 16"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "80 0"; + extent = "104 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + }; + }; + new GuiControl() { + isContainer = "1"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 70"; + extent = "204 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Color/popupBackgroundColor"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + + new GuiTextCtrl() { + text = "Popup Back:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 1"; + extent = "70 16"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "80 0"; + extent = "104 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + }; + }; + }; + }; + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Misc"; + Margin = "0 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiControl() { + isContainer = "1"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "210 14"; + + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Force Load DAE"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "GuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 0"; + extent = "140 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + variable = "EWorldEditor.forceLoadDAE"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowCheckbox"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/forceLoadDAE"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 70"; + extent = "210 18"; + + new GuiTextCtrl() { + text = "Screen Center Scalar:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 1"; + extent = "110 16"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextEditNumericProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "120 0"; + extent = "80 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Tools/dropAtScreenCenterScalar"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 70"; + extent = "210 18"; + + new GuiTextCtrl() { + text = "Screen Center Max:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 1"; + extent = "110 16"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextEditNumericProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "120 0"; + extent = "80 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Tools/dropAtScreenCenterMax"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + }; + }; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/worldEditor/gui/ObjectSnapOptionsWindow.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/ObjectSnapOptionsWindow.ed.gui new file mode 100644 index 000000000..4c325b9dc --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/ObjectSnapOptionsWindow.ed.gui @@ -0,0 +1,871 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ObjectSnapOptionsContainer, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiModelessDialogProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCollapseCtrl(ESnapOptions) { + internalName = "SnapOptionsWindow"; + Enabled = "1"; + isContainer = "1"; + profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + resizeWidth = "0"; + resizeHeight = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + position = "400 31"; + extent =" 175 257"; + MinExtent = "175 130"; + text = "Snap Options"; + closeCommand = "ESnapOptions.hideDialog();"; + EdgeSnap = "0"; + canCollapse = "0"; + visible = "0"; + Margin = "5 5 5 5"; + Padding = "5 5 5 5"; + + new GuiTabBookCtrl(ESnapOptionsTabBook) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "5 52"; + Extent = "190 240"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Docking = "Client"; + Margin = "3 22 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + TabPosition = "Top"; + TabMargin = "10"; + MinTabWidth = "8"; + + new GuiTabPageCtrl(ESnapOptionsTabTerrain) { + canSaveDynamicFields = "0"; + Profile = "GuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Margin = "0 0 0 0"; + Position = "0 19"; + Extent = "190 220"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + Docking = "None"; + text = "Terrain"; + maxLength = "255"; + command = "toggleSnappingOptions(\"terrain\");"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Position = "4 12"; + Extent = "156 190"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "2 2"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "190 90"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiDynamicCtrlArrayControl() { + canSaveDynamicFields = "0"; + internalName = "TerrainSnapAlignment"; + Enabled = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 18"; + Extent = "190 72"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + colCount = "2"; + colSize = "78"; + rowSize = "20"; + rowSpacing = "2"; + colSpacing = "2"; + dynamicSize = true; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "190 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = " Alignment:"; + maxLength = "1024"; + }; + new GuiRadioCtrl() { + canSaveDynamicFields = "0"; + internalName = "NoAlignment"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiRadioProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setTerrainSnapAlignment(\"None\");"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "None"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "negX"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiIconButtonSmallProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setTerrainSnapAlignment(\"-X\");"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "- X Axis"; + iconBitmap = "tools/gui/images/axis-icon_-x"; + textMargin = "24"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "posX"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiIconButtonSmallProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setTerrainSnapAlignment(\"+X\");"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "+ X Axis"; + iconBitmap = "tools/gui/images/axis-icon_x"; + textMargin = "24"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "negY"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiIconButtonSmallProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setTerrainSnapAlignment(\"-Y\");"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "- Y Axis"; + iconBitmap = "tools/gui/images/axis-icon_-y"; + textMargin = "24"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "posY"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiIconButtonSmallProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setTerrainSnapAlignment(\"+Y\");"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "+ Y Axis"; + iconBitmap = "tools/gui/images/axis-icon_y"; + textMargin = "24"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "negZ"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiIconButtonSmallProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setTerrainSnapAlignment(\"-Z\");"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "- Z Axis"; + iconBitmap = "tools/gui/images/axis-icon_-z"; + textMargin = "24"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "posZ"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiIconButtonSmallProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setTerrainSnapAlignment(\"+Z\");"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "+ Z Axis"; + iconBitmap = "tools/gui/images/axis-icon_z"; + textMargin = "24"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + }; + new GuiCheckBoxCtrl() { + text = "Snap to object bounding box"; + groupNum = "1"; + useMouseEvents = "0"; + isContainer = "0"; + horizSizing = "right"; + vertSizing = "top"; + position = "4 249"; + extent = "165 24"; + minExtent = "8 8"; + visible = "1"; + active = "1"; + Variable = "EWorldEditor.dropAtBounds"; + Command = "EWorldEditor.dropAtBounds = $ThisControl.getValue();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; + new GuiTabPageCtrl(ESnapOptionsTabSoft) { + canSaveDynamicFields = "0"; + Profile = "GuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Margin = "0 0 0 0"; + Position = "0 19"; + Extent = "190 220"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + Docking = "None"; + text = "Soft"; + maxLength = "255"; + command = "toggleSnappingOptions(\"soft\");"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Position = "4 12"; + Extent = "186 190"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "2 2"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "5"; + canSaveDynamicFields = "0"; + internalName = "theVisOptionsList"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "2 2"; + Extent = "190 190"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + Position = "0 0"; + Extent = "190 18"; + MinExtent = "16 16"; + Visible = "1"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "90 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Snap Size:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + internalName = "SnapSize"; + profile="GuiTextEditProfileNumbersOnly"; + HorizSizing = "left"; + position = "136 0"; + Extent = "44 18"; + text ="2.0"; + maxLength = "6"; + AltCommand = "ESnapOptions.setSoftSnapSize();"; + }; + }; + + new GuiControl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + Position = "0 0"; + Extent = "190 90"; + MinExtent = "16 16"; + Visible = "1"; + + new GuiDynamicCtrlArrayControl() { + canSaveDynamicFields = "0"; + internalName = "SoftSnapAlignment"; + Enabled = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "190 90"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + colCount = "2"; + colSize = "78"; + rowSize = "20"; + rowSpacing = "2"; + colSpacing = "2"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "190 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = " Alignment:"; + maxLength = "1024"; + }; + new GuiRadioCtrl() { + canSaveDynamicFields = "0"; + internalName = "NoAlignment"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiRadioProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setSoftSnapAlignment(\"None\");"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "None"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "negX"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiIconButtonSmallProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setSoftSnapAlignment(\"-X\");"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "- X Axis"; + iconBitmap = "tools/gui/images/axis-icon_-x"; + textMargin = "24"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "posX"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiIconButtonSmallProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setSoftSnapAlignment(\"+X\");"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "+ X Axis"; + iconBitmap = "tools/gui/images/axis-icon_x"; + textMargin = "24"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "negY"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiIconButtonSmallProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setSoftSnapAlignment(\"-Y\");"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "- Y Axis"; + iconBitmap = "tools/gui/images/axis-icon_-y"; + textMargin = "24"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "posY"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiIconButtonSmallProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setSoftSnapAlignment(\"+Y\");"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "+ Y Axis"; + iconBitmap = "tools/gui/images/axis-icon_y"; + textMargin = "24"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "negZ"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiIconButtonSmallProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setSoftSnapAlignment(\"-Z\");"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "- Z Axis"; + iconBitmap = "tools/gui/images/axis-icon_-z"; + textMargin = "24"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "posZ"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiIconButtonSmallProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setSoftSnapAlignment(\"+Z\");"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "+ Z Axis"; + iconBitmap = "tools/gui/images/axis-icon_z"; + textMargin = "24"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + }; + }; + + new GuiCheckBoxCtrl(){ + internalName = "RenderSnapBounds"; + Enabled = "1"; + Profile = "GuiCheckBoxProfile"; + position = "1 0"; + Extent = "190 18"; + text = "Render Snap Bounds"; + Command = "ESnapOptions.toggleRenderSnapBounds();"; + }; + + new GuiCheckBoxCtrl(){ + internalName = "RenderSnappedTriangle"; + Enabled = "1"; + Profile = "GuiCheckBoxProfile"; + position = "1 0"; + Extent = "190 18"; + text = "Render Snapped Triangle"; + Command = "ESnapOptions.toggleRenderSnappedTriangle();"; + }; + + new GuiControl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + Position = "0 0"; + Extent = "190 18"; + MinExtent = "16 16"; + Visible = "1"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "110 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Backface Tolerance:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + internalName = "SnapBackfaceTolerance"; + profile="GuiTextEditProfileNumbersOnly"; + HorizSizing = "left"; + position = "136 0"; + Extent = "44 18"; + text ="0.5"; + maxLength = "6"; + AltCommand = "ESnapOptions.getSoftSnapBackfaceTolerance();"; + }; + }; + }; + }; + }; + }; + new GuiCheckBoxCtrl() { + text = "Grid Snapping"; + groupNum = "1"; + useMouseEvents = "0"; + isContainer = "0"; + horizSizing = "right"; + vertSizing = "top"; + position = "4 231"; + extent = "95 24"; + minExtent = "8 8"; + visible = "1"; + active = "1"; + command = "toggleSnappingOptions(\"grid\");"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "GridSnapButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Size"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "top"; + position = "103 234"; + extent = "25 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + text = "2.0"; + maxLength = "6"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "GuiTextEditProfileNumbersOnly"; + horizSizing = "left"; + vertSizing = "top"; + position = "127 235"; + extent = "44 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + altCommand = "ESnapOptions.setGridSnapSize();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "gridSize"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + internalName = "NoSnapButton"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "133 23"; + Extent = "38 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "toggleSnappingOptions(\"\");"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Off"; + groupNum = "1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + }; + }; +}; \ No newline at end of file diff --git a/Templates/Empty/game/tools/worldEditor/gui/SelectObjectsWindow.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/SelectObjectsWindow.ed.gui new file mode 100644 index 000000000..b6e183876 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/SelectObjectsWindow.ed.gui @@ -0,0 +1,566 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ESelectObjectsWindowContainer,EditorGuiGroup) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiWindowCtrl(ESelectObjectsWindow) { + text = "Select Objects"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "1"; + closeCommand = "$ThisControl.toggleVisibility();"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "268 177"; + extent = "380 373"; + minExtent = "200 100"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + class = "EObjectSelection"; + internalName = "SelectObjectsWindow"; + + new GuiBitmapBorderCtrl() { + position = "7 104"; + extent = "265 262"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiGroupBorderProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "10 25"; + extent = "246 200"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "0"; + dynamicSize = "1"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "1 1"; + extent = "246 1242"; + minExtent = "16 16"; + horizSizing = "width"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "classList"; + canSave = "1"; + canSaveDynamicFields = "0"; + + }; + }; + new GuiButtonCtrl() { + text = "Select All"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "10 231"; + extent = "65 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "ESelectObjectsWindow.selectAllInClassList( true );"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Classes"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "113 6"; + extent = "40 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiAutoSizeTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Deselect All"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "76 231"; + extent = "65 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "ESelectObjectsWindow.selectAllInClassList( false );"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapBorderCtrl() { + position = "7 25"; + extent = "366 74"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiGroupBorderProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Name Pattern"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "11 9"; + extent = "67 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiAutoSizeTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Retain Current Selection"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "216 46"; + extent = "140 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "retainSelection"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Create Selection Set"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "13 73"; + extent = "117 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiCheckBoxProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "createSelectionSet"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "•"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "157 80"; + extent = "199 17"; + minExtent = "20 2"; + horizSizing = "width"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiTextEditProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "selectionSetName"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "•"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "91 9"; + extent = "265 17"; + minExtent = "20 2"; + horizSizing = "width"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "namePattern"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Select Objects in Group"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "11 30"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiAutoSizeTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "138 30"; + extent = "218 17"; + minExtent = "20 2"; + horizSizing = "width"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "groupList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapBorderCtrl() { + position = "246 104"; + extent = "233 262"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiGroupBorderProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "9 25"; + extent = "215 200"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "0"; + dynamicSize = "1"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "1 1"; + extent = "215 16"; + minExtent = "16 16"; + horizSizing = "width"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "filterList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiButtonCtrl() { + text = "Select All"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "9 231"; + extent = "65 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Filters"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "101 6"; + extent = "30 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiAutoSizeTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Deselect All"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "75 231"; + extent = "65 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiButtonCtrl() { + text = "Select"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "278 104"; + extent = "95 30"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "ESelectObjectsWindow.onSelectObjects(true);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Deselect"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "278 137"; + extent = "95 30"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "ESelectObjectsWindow.onSelectObjects(false);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/worldEditor/gui/TerrainBrushSoftnessCurveDlg.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/TerrainBrushSoftnessCurveDlg.ed.gui new file mode 100644 index 000000000..b082dea49 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/TerrainBrushSoftnessCurveDlg.ed.gui @@ -0,0 +1,232 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(TerrainBrushSoftnessCurveDlg, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiOverlayProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "231 204"; + Extent = "175 228"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "0"; + text = "Brush Softness Curve"; + + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "84 196"; + Extent = "83 24"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "TerrainBrushSoftnessCurveDlg.onOk();"; + hovertime = "1000"; + text = "Ok"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiFilterCtrl() { + canSaveDynamicFields = "0"; + internalName = "FilterCurveCtrl"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "35 46"; + Extent = "130 128"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + controlPoints = "7"; + filter = "1 0.833333 0.666667 0.5 0.333333 0.166667 0"; + identity = "1 0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 43"; + Extent = "22 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Hard"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 159"; + Extent = "20 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Soft"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "36 174"; + Extent = "33 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Inside"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "129 176"; + Extent = "39 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Outside"; + maxLength = "1024"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "7 196"; + Extent = "69 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.popDialog( TerrainBrushSoftnessCurveDlg );"; + hovertime = "1000"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "122 26"; + Extent = "44 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainBrushSoftnessCurveDlg.resetCurve();"; + hovertime = "1000"; + text = "Reset"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + + +function TerrainBrushSoftnessCurveDlg::onWake( %this ) +{ + %curve = %this-->FilterCurveCtrl; + %curve.setValue( ETerrainEditor.softSelectFilter ); +} + +function TerrainBrushSoftnessCurveDlg::onOk( %this ) +{ + %curve = %this-->FilterCurveCtrl; + ETerrainEditor.softSelectFilter = %curve.getValue(); + ETerrainEditor.resetSelWeights(true); + + Canvas.popDialog( %this ); +} + +function TerrainBrushSoftnessCurveDlg::resetCurve( %this ) +{ + %curve = %this-->FilterCurveCtrl; + %curve.identity(); +} diff --git a/Templates/Empty/game/tools/worldEditor/gui/TerrainEditToolbar.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/TerrainEditToolbar.ed.gui new file mode 100644 index 000000000..c2f85935b --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/TerrainEditToolbar.ed.gui @@ -0,0 +1,615 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(EWTerrainEditToolbar,EditorGuiGroup) { + canSaveDynamicFields = "0"; + internalName = "TerrainEditToolbar"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "306 0"; + Extent = "800 40"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "6 7"; + extent = "70 16"; + minExtent = "8 8"; + visible = "1"; + text = "Brush Settings"; + maxLength = "255"; + helpTag = "0"; + }; + + new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "760 40"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiControl(EWTerrainEditToolbarBrushType){ + isContainer = "1"; + profile = "GuiDefaultProfile"; + Position = "83 2"; + Extent = "94 27"; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "ellipse"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.toggleBrushType($ThisControl);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Circle Brush (V)"; + hovertime = "750"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/circleBrush"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "box"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "31 0"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.toggleBrushType($ThisControl);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Box Brush (B)"; + hovertime = "750"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/boxBrush"; + }; + + /* + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "selection"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "62 0"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.toggleBrushType($ThisControl);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Toggles the brush type."; + hovertime = "750"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/maskBrush"; + }; + */ + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + position = "152 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-h.png"; + }; + + new GuiControl(TerrainBrushSizeTextEditContainer) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "145 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "21 5"; + Extent = "47 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Size"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + isContainer = "0"; + HorizSizing = "right"; + profile="GuiNumericDropSliderTextProfile"; + VertSizing = "bottom"; + position = "49 2"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.setBrushSize( $ThisControl.getText() );"; + validate = "TerrainEditorPlugin.validateBrushSize();"; + hovertime = "1000"; + text = "9"; + maxLength = "4"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "83 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(TerrainBrushSizeSliderCtrlContainer);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Changes size of the brush (CTRL + Mouse Wheel)"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "core/art/gui/images/dropslider"; + }; + }; + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + position = "272 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-h.png"; + }; + + new GuiControl(TerrainBrushPressureTextEditContainer) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "287 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 5"; + Extent = "47 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Pressure"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + isContainer = "0"; + profile="GuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "49 2"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.setBrushPressure( ($ThisControl.getValue() / 100) );"; + hovertime = "1000"; + text = "100"; + maxLength = "3"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "83 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(TerrainBrushPressureSliderCtrlContainer);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Changes the pressure (CTRL + SHIFT + Mouse Wheel)"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "core/art/gui/images/dropslider"; + }; + }; + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + position = "412 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-h.png"; + }; + + new GuiControl(TerrainBrushSoftnessTextEditContainer) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "429 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 5"; + Extent = "47 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Softness"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + isContainer = "0"; + HorizSizing = "right"; + profile="GuiNumericDropSliderTextProfile"; + VertSizing = "bottom"; + position = "49 2"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.setBrushSoftness( ($ThisControl.getValue() / 100) );"; + hovertime = "1000"; + text = "1"; + maxLength = "3"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "83 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(TerrainBrushSoftnessSliderCtrlContainer);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Changes the softness (SHIFT + Mouse Wheel)"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "core/art/gui/images/dropslider"; + }; + }; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "547 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog( TerrainBrushSoftnessCurveDlg );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Changes the softness curve"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/softCurve"; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + position = "589 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-h.png"; + }; + + new GuiControl(TerrainSetHeightTextEditContainer) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "605 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 5"; + Extent = "33 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Height"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + isContainer = "0"; + HorizSizing = "right"; + profile="GuiNumericDropSliderTextProfile"; + VertSizing = "bottom"; + position = "34 2"; + Extent = "62 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.setHeightVal = $ThisControl.getValue();"; + hovertime = "1000"; + text = "1"; + maxLength = "7"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "88 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(TerrainSetHeightSliderCtrlContainer);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Changes the height for the SetHeight tool (ALT + Left Mouse)"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "core/art/gui/images/dropslider"; + }; + }; + }; +}; + +new GuiMouseEventCtrl(TerrainBrushSizeSliderCtrlContainer,EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "GuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(TerrainBrushSizeTextEditContainer.position) + firstWord(EWTerrainEditToolbar.position)+11 SPC + (getWord(TerrainBrushSizeTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "TerrainBrushSizeTextEditContainer-->textEdit.setValue(mCeil($ThisControl.getValue())); ETerrainEditor.setBrushSize( $ThisControl.value );"; + range = "1 40"; + ticks = "0"; + value = "0"; + }; +}; + +new GuiMouseEventCtrl(TerrainBrushPressureSliderCtrlContainer,EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "GuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(TerrainBrushPressureTextEditContainer.position) + firstWord(EWTerrainEditToolbar.position) SPC + (getWord(TerrainBrushPressureTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "TerrainBrushPressureTextEditContainer-->textEdit.setValue( mCeil(100 * $ThisControl.getValue()) @ \"%\"); ETerrainEditor.setBrushPressure( $ThisControl.value );"; + range = "0.01 1"; + ticks = "0"; + value = "0"; + }; +}; + +new GuiMouseEventCtrl(TerrainBrushSoftnessSliderCtrlContainer,EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "GuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(TerrainBrushSoftnessTextEditContainer.position) + firstWord(EWTerrainEditToolbar.position) SPC + (getWord(TerrainBrushSoftnessTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "TerrainBrushSoftnessTextEditContainer-->textEdit.setValue( mCeil(100 * $ThisControl.getValue()) @ \"%\"); ETerrainEditor.setBrushSoftness( $ThisControl.value );"; + range = "0 1"; + ticks = "0"; + value = "0"; + }; +}; + +new GuiMouseEventCtrl(TerrainSetHeightSliderCtrlContainer,EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "GuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(TerrainSetHeightTextEditContainer.position) + firstWord(EWTerrainEditToolbar.position) SPC + (getWord(TerrainSetHeightTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "TerrainSetHeightTextEditContainer-->textEdit.setValue( $ThisControl.getValue() ); ETerrainEditor.setHeightVal = $ThisControl.getValue();"; + range = "0 2047"; + ticks = "0"; + value = "100"; + }; +}; +//--- OBJECT WRITE END --- \ No newline at end of file diff --git a/Templates/Empty/game/tools/worldEditor/gui/TerrainEditorSettingsTab.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/TerrainEditorSettingsTab.ed.gui new file mode 100644 index 000000000..5208a1c73 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/TerrainEditorSettingsTab.ed.gui @@ -0,0 +1,301 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(TerrainEditorSettingsTab,EditorGuiGroup) { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiTabPageCtrl(ETerrainEditorSettingsPage) { + fitBook = "1"; + text = "Terrain Editor"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiSolidDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "208 400"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "208 400"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + extent = "208 210"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Tool Values"; + Margin = "0 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Raise/Lower Height:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditNumericProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "ETerrainEditor.adjustHeightVal = EditorSettings.value(%this.editorSettingsValue);"; + editorSettingsValue = "TerrainEditor/ActionValues/adjustHeightVal"; + editorSettingsWrite = "EditorGui.writeTerrainEditorSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Smooth Factor:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditNumericProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "ETerrainEditor.smoothFactor = EditorSettings.value(%this.editorSettingsValue);"; + editorSettingsValue = "TerrainEditor/ActionValues/smoothFactor"; + editorSettingsWrite = "EditorGui.writeTerrainEditorSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Noise Factor:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditNumericProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "ETerrainEditor.noiseFactor = EditorSettings.value(%this.editorSettingsValue);"; + editorSettingsValue = "TerrainEditor/ActionValues/noiseFactor"; + editorSettingsWrite = "EditorGui.writeTerrainEditorSettings();"; + }; + }; + }; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/worldEditor/gui/TerrainEditorVSettingsGui.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/TerrainEditorVSettingsGui.ed.gui new file mode 100644 index 000000000..f5a48a203 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/TerrainEditorVSettingsGui.ed.gui @@ -0,0 +1,276 @@ +//--- OBJECT WRITE BEGIN --- +new GuiControl(TerrainEditorValuesSettingsGui, EditorGuiGroup) { + profile = "GuiOverlayProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new GuiWindowCtrl() { + profile = "GuiWindowProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "117 113"; + extent = "408 247"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + text = "Terrain Action Values"; + maxLength = "255"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "Canvas.popDIalog(TerrainEditorValuesSettingsGui);"; + + new GuiControl() { + profile = "GuiWindowProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "198 27"; + extent = "203 115"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new GuiTextEditCtrl() { + profile = "GuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "86 12"; + extent = "107 18"; + minExtent = "8 8"; + visible = "1"; + variable = "ETerrainEditor.adjustHeightVal"; + command = "ETerrainEditor.adjustHeightVal = $ThisControl.getValue();"; + helpTag = "0"; + maxLength = "255"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Adjust height increment."; + }; + new GuiTextEditCtrl() { + profile = "GuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "86 62"; + extent = "107 18"; + minExtent = "8 8"; + visible = "1"; + variable = "ETerrainEditor.scaleVal"; + command = "ETerrainEditor.scaleVal = $ThisControl.getValue();"; + helpTag = "0"; + maxLength = "255"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Scale height increment."; + }; + new GuiTextEditCtrl() { + profile = "GuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "86 87"; + extent = "107 18"; + minExtent = "8 8"; + visible = "1"; + variable = "ETerrainEditor.smoothFactor"; + command = "ETerrainEditor.smoothFactor = $ThisControl.getValue();"; + helpTag = "0"; + maxLength = "255"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Smoothing factor -- lower values are less agressive."; + }; + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "11 12"; + extent = "64 18"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + text = "Adjust Height"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Adjust height increment."; + maxLength = "255"; + }; + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "11 37"; + extent = "49 18"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + text = "Set Height"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Elevation for set height operation."; + maxLength = "255"; + }; + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "11 62"; + extent = "60 18"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + text = "Scale Height"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Scale height increment."; + maxLength = "255"; + }; + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "10 87"; + extent = "70 18"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + text = "Smooth Factor"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Smoothing factor -- lower values are less agressive."; + maxLength = "255"; + }; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "218 205"; + extent = "80 20"; + minExtent = "8 8"; + visible = "1"; + command = "Canvas.popDIalog(TerrainEditorValuesSettingsGui);"; + helpTag = "0"; + text = "OK"; + groupNum = "-1"; + buttonType = "PushButton"; + }; + new GuiControl() { + profile = "GuiWindowProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "7 27"; + extent = "188 212"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new GuiFilterCtrl(TESoftSelectFilter) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 22"; + extent = "155 162"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + controlPoints = "7"; + filter = "1.000000 0.833333 0.666667 0.500000 0.333333 0.166667 0.000000"; + }; + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "6 4"; + extent = "67 18"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + text = "Soft Selection"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "This spline scale modifies the hardness of the brush. Left is center, right is outer edge."; + maxLength = "255"; + }; + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "12 189"; + extent = "8 18"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + text = "0"; + maxLength = "255"; + }; + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "12 26"; + extent = "8 18"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + text = "1"; + maxLength = "255"; + }; + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "60 190"; + extent = "45 18"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + text = "<Radius>"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Brush radius for Selection Mode."; + maxLength = "255"; + }; + new GuiTextEditCtrl() { + profile = "GuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "125 187"; + extent = "50 18"; + minExtent = "8 8"; + visible = "1"; + variable = "ETerrainEditor.softSelectRadius"; + command = "ETerrainEditor.softSelectRadius = $ThisControl.getValue();"; + helpTag = "0"; + maxLength = "255"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Brush radius for Selection Mode."; + }; + }; + new GuiButtonCtrl(TESettingsApplyButton) { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "307 205"; + extent = "80 20"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + text = "Apply"; + groupNum = "-1"; + buttonType = "PushButton"; + }; + }; +}; +//--- OBJECT WRITE END --- + diff --git a/Templates/Empty/game/tools/worldEditor/gui/TerrainPainterToolbar.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/TerrainPainterToolbar.ed.gui new file mode 100644 index 000000000..ff2754805 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/TerrainPainterToolbar.ed.gui @@ -0,0 +1,637 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(EWTerrainPainterToolbar,EditorGuiGroup) { + canSaveDynamicFields = "0"; + internalName = "TerrainPainterToolbar"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "306 0"; + Extent = "800 40"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "6 7"; + extent = "70 16"; + minExtent = "8 8"; + visible = "1"; + text = "Brush Settings"; + maxLength = "255"; + helpTag = "0"; + }; + + new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "760 40"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiControl(EWTerrainPainterToolbarBrushType){ + isContainer = "1"; + profile = "GuiDefaultProfile"; + Position = "83 2"; + Extent = "94 27"; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "ellipse"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.toggleBrushType($ThisControl);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Circle Brush (V)"; + hovertime = "750"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/circleBrush"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "box"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "31 0"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.toggleBrushType($ThisControl);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Box Brush (B)"; + hovertime = "750"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/boxBrush"; + }; + + /* + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "selection"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "62 0"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.toggleBrushType($ThisControl);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Toggles the brush type."; + hovertime = "750"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/maskBrush"; + }; + */ + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + position = "152 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-h.png"; + }; + + new GuiControl(PaintBrushSizeTextEditContainer) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "145 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "21 5"; + Extent = "47 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Size"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + isContainer = "0"; + HorizSizing = "right"; + VertSizing = "bottom"; + profile="GuiNumericDropSliderTextProfile"; + position = "49 2"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.setBrushSize( $ThisControl.getText() );"; + validate = "TerrainPainterPlugin.validateBrushSize();"; + hovertime = "1000"; + text = "9"; + maxLength = "4"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "83 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(PaintBrushSizeSliderCtrlContainer);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Changes the size of the brush (CTRL + Mouse Wheel)"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "core/art/gui/images/dropslider"; + }; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + position = "270 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-h.png"; + }; + + new GuiControl(PaintBrushSlopeControl) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "262 5"; + Extent = "256 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "21 5"; + Extent = "78 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Allows painting on the terrain within a specified slope"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Slope Mask Min"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + internalName = "SlopeMinAngle"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "104 2"; + Extent = "51 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + validate = "TerrainPainterPlugin.validateSlopeMinAngle();"; + Command = "ETerrainEditor.setSlopeLimitMinAngle( $ThisControl.getText() );"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Minimum terrain angle that will be paintable"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "0.0"; + maxLength = "4"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "137 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Minimum terrain angle that will be paintable"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "core/art/gui/images/dropslider"; + Command = "Canvas.pushDialog(PaintBrushSlopeMinContainer);"; + }; + new GuiTextCtrl() { + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "165 5"; + Extent = "27 10"; + MinExtent = "8 2"; + text = "Max"; + tooltip = "Max terrain angle that will be paintable"; + }; + new GuiTextEditCtrl() { + internalName = "SlopeMaxAngle"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "190 2"; + Extent = "51 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + validate = "TerrainPainterPlugin.validateSlopeMaxAngle();"; + Command = "ETerrainEditor.setSlopeLimitMaxAngle( $ThisControl.getText() );"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Max terrain angle that will be paintable"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "90.0"; + maxLength = "4"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "223 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + groupNum = "-1"; + tooltip = "Max terrain angle that will be paintable"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "core/art/gui/images/dropslider"; + Command = "Canvas.pushDialog(PaintBrushSlopeMaxContainer);"; + }; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + position = "525 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-h.png"; + }; + + new GuiControl(PaintBrushPressureTextEditContainer,EditorGuiGroup) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "540 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 5"; + Extent = "47 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Pressure"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + isContainer = "0"; + profile="GuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "49 2"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.setBrushPressure( ($ThisControl.getValue() / 100) );"; + hovertime = "1000"; + text = "100"; + maxLength = "3"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "83 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(PaintBrushPressureSliderCtrlContainer);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Changes the pressure (CTRL + SHIFT + Mouse Wheel)"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "core/art/gui/images/dropslider"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- + +function setTerrainEditorMinSlope(%value) +{ + %val = ETerrainEditor.setSlopeLimitMinAngle( %value ); + PaintBrushSlopeControl-->SlopeMinAngle.setValue(mFloatLength( %val, 1 )); +} + +function setTerrainEditorMaxSlope(%value) +{ + %val = ETerrainEditor.setSlopeLimitMaxAngle( %value ); + PaintBrushSlopeControl-->SlopeMaxAngle.setValue(mFloatLength( %val, 1 )); +} + +new GuiMouseEventCtrl(PaintBrushSizeSliderCtrlContainer,EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "GuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(PaintBrushSizeTextEditContainer.position) + firstWord(EWTerrainPainterToolbar.position)+11 SPC + (getWord(PaintBrushSizeTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "PaintBrushSizeTextEditContainer-->textEdit.setValue(mFloatLength( ($ThisControl.getValue()), 2 )); ETerrainEditor.setBrushSize( $ThisControl.value );"; + range = "1 40"; + ticks = "0"; + value = "0"; + }; +}; + +new GuiMouseEventCtrl(PaintBrushSlopeMinContainer,EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "GuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(PaintBrushSlopeControl.position) + firstWord(EWTerrainPainterToolbar.position)+firstWord(PaintBrushSlopeControl->SlopeMinAngle.position) - 40 SPC + (getWord(PaintBrushSlopeControl, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "PaintBrushSlopeControl-->SlopeMinAngle.setValue(mFloatLength( ($ThisControl.getValue()), 1 )); ETerrainEditor.setSlopeLimitMinAngle(mFloatLength( ($ThisControl.getValue()), 1 ));TerrainPainterPlugin.validateSlopeMinAngle();"; + range = "0 89.9"; + ticks = "0"; + value = "0"; + }; +}; + +function PaintBrushSlopeMinContainer::onWake(%this) +{ + %this-->slider.setValue(PaintBrushSlopeControl-->SlopeMinAngle.getText()); +} + +new GuiMouseEventCtrl(PaintBrushSlopeMaxContainer,EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "GuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(PaintBrushSlopeControl.position) + firstWord(EWTerrainPainterToolbar.position)+firstWord(PaintBrushSlopeControl->SlopeMaxAngle.position) - 40 SPC + (getWord(PaintBrushSlopeControl, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "PaintBrushSlopeControl-->SlopeMaxAngle.setValue(mFloatLength( ($ThisControl.getValue()), 1 )); ETerrainEditor.setSlopeLimitMaxAngle(mFloatLength( ($ThisControl.getValue()), 1 ));TerrainPainterPlugin.validateSlopeMaxAngle();"; + range = "0.1 90.0"; + ticks = "0"; + value = "0"; + }; +}; + +function PaintBrushSlopeMaxContainer::onWake(%this) +{ + %this-->slider.setValue(PaintBrushSlopeControl-->SlopeMaxAngle.getText()); +} + +function PaintBrushSlopeMaxContainer::init(%this) +{ + %this-->slider.setValue("90.0"); +} + +new GuiMouseEventCtrl(PaintBrushPressureSliderCtrlContainer,EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "GuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(PaintBrushPressureTextEditContainer.position) + firstWord(EWTerrainPainterToolbar.position) SPC + (getWord(PaintBrushPressureTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "PaintBrushPressureTextEditContainer-->textEdit.setValue(mFloatLength( ($ThisControl.getValue()), 2 )); ETerrainEditor.setBrushPressure( $ThisControl.value );"; + range = "0 1"; + ticks = "0"; + value = "0"; + }; +}; + +new GuiMouseEventCtrl(PaintBrushSoftnessSliderCtrlContainer,EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "GuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(PaintBrushSoftnessTextEditContainer.position) + firstWord(EWTerrainPainterToolbar.position) SPC + (getWord(PaintBrushSoftnessTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "PaintBrushSoftnessTextEditContainer-->textEdit.setValue(mFloatLength( ($ThisControl.getValue()), 2 )); ETerrainEditor.setBrushSoftness( $ThisControl.value );"; + range = "0 1"; + ticks = "0"; + value = "0"; + }; +}; + diff --git a/Templates/Empty/game/tools/worldEditor/gui/TerrainPainterWindow.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/TerrainPainterWindow.ed.gui new file mode 100644 index 000000000..3559896ed --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/TerrainPainterWindow.ed.gui @@ -0,0 +1,229 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(TerrainPainterContainer,EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCollapseCtrl(EPainter) { + canSaveDynamicFields = "0"; + internalName = "TerrainPainter"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 SPC getWord(EditorGuiToolbar.extent, 1)+249; + Extent = "210 446"; + MinExtent = "210 100"; + canSave = "1"; + isDecoy = "0"; + Visible = "0"; + hovertime = "1000"; + Docking = "None"; + Margin = "4 4 4 4"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "152 300"; + closeCommand = "EPainter.parentGroup.setVisible(false);"; + EdgeSnap = "1"; + text = "Terrain Painter Material Selector"; + + new GuiScrollCtrl( EPainterScroll ) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "4 24"; + Extent = "202 418"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "3 1 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiStackControl( EPainterStack ) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "-2"; + canSaveDynamicFields = "0"; + internalName = "theMaterialList"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "200 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + }; + }; + }; + new GuiWindowCollapseCtrl(EPainterPreview) { + canSaveDynamicFields = "0"; + internalName = "TerrainPainterPreview"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 SPC getWord(EditorGuiToolbar.extent, 1)-1; + Extent = "210 251"; + MinExtent = "210 251"; + canSave = "1"; + isDecoy = "0"; + Visible = "0"; + hovertime = "1000"; + Docking = "None"; + Margin = "4 4 4 4"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "152 300"; + closeCommand = "EPainter.parentGroup.setVisible(false);"; + EdgeSnap = "1"; + text = "Terrain Painter Material Preview"; + + new GuiContainer(){ + Docking = "Client"; + Margin = "3 22 3 3"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "4 24"; + Extent = "202 202"; + + new GuiBitmapCtrl(ETerrainMaterialSelected) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 202"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + wrap = "0"; + bitmap= "tools/materialeditor/gui/unknownImage"; + }; + new GuiBitmapCtrl(ETerrainMaterialSelectedBorder) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 202"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/terrainpainter/terrain-painter-border-large"; + wrap = "0"; + }; + }; + new GuiButtonCtrl(ETerrainMaterialSelectedEdit) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "170 229"; + Extent = "36 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "0"; + Command = "TerrainMaterialDlg.show(ETerrainMaterialSelected.selectedMatIndex, ETerrainMaterialSelected.selectedMat, EPainter_TerrainMaterialUpdateCallback);"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Edit"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiTextCtrl(TerrainTextureText) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "5 230"; + Extent = "162 16"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/worldEditor/gui/TimeAdjustGui.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/TimeAdjustGui.ed.gui new file mode 100644 index 000000000..1d58b4285 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/TimeAdjustGui.ed.gui @@ -0,0 +1,214 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(TimeAdjustGui, EditorGuiGroup) { + isContainer = "1"; + Profile = "GuiModelessDialogProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiWindowCtrl() { + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Time Adjust Gui"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "338 63"; + Extent = "462 84"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + closeCommand = "Canvas.popDialog(TimeAdjustGui);"; + + new GuiSliderCtrl(TimeAdjustSliderCtrl) { + range = "0 1"; + ticks = "100"; + value = "0.1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "37 27"; + Extent = "389 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + altCommand = "$ThisControl.onAction();"; + }; + new GuiTextCtrl() { + text = "Sunrise"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 53"; + Extent = "59 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Sunset"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "206 53"; + Extent = "59 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Noon"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "108 53"; + Extent = "59 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Midnight"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "307 53"; + Extent = "59 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Sunrise"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "393 53"; + Extent = "59 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + +function TimeAdjustSliderCtrl::onAction(%this) +{ + // NOTE: Though this is a GuiControl which exists on the client-side + // we access and modify the server-side TimeOfDay object. This is acceptible + // because this is a "tools" gui which is not intended for a real-game + // or multiplayer situation. + + if ( !isObject( %this.tod ) ) + { + if ( isObject( MissionGroup ) ) + { + for ( %i = 0; %i < MissionGroup.getCount(); %i++ ) + { + %obj = MissionGroup.getObject( %i ); + + if ( %obj.getClassName() $= "TimeOfDay" ) + { + %this.tod = %obj; + break; + } + } + } + } + + if ( !isObject( %this.tod ) ) + return; + + %this.tod.time = %this.getValue(); +} + +function toggleTimeAdjustGui() +{ + if ( TimeAdjustGui.isAwake() ) + Canvas.popDialog( TimeAdjustGui ); + else + Canvas.pushDialog( TimeAdjustGui ); +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/ConvexEditorPalette.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/ConvexEditorPalette.ed.gui new file mode 100644 index 000000000..34b7e2b19 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/ConvexEditorPalette.ed.gui @@ -0,0 +1,102 @@ +%paletteId = new GuiControl(ConvexEditorPalette, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl(ConvexEditorNoneModeBtn) { + canSaveDynamicFields = "0"; + internalName = ""; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Select Arrow (1)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/arrow"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + Command = "GlobalGizmoProfile.mode = \"None\";"; + }; + + new GuiBitmapButtonCtrl(ConvexEditorMoveModeBtn) { + canSaveDynamicFields = "0"; + internalName = ""; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "28 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Move Selection (2)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/translate"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + Command = "GlobalGizmoProfile.mode = \"Move\";"; + }; + + new GuiBitmapButtonCtrl(ConvexEditorRotateModeBtn) { + canSaveDynamicFields = "0"; + internalName = ""; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "56 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Rotate Selection (3)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/rotate"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + Command = "GlobalGizmoProfile.mode = \"Rotate\";"; + }; + + new GuiBitmapButtonCtrl(ConvexEditorScaleModeBtn) { + canSaveDynamicFields = "0"; + internalName = ""; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "84 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Scale Selection (4)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/scale"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + Command = "GlobalGizmoProfile.mode = \"Scale\";"; + }; +}; \ No newline at end of file diff --git a/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/DecalEditorPalette.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/DecalEditorPalette.ed.gui new file mode 100644 index 000000000..412f02b03 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/DecalEditorPalette.ed.gui @@ -0,0 +1,121 @@ +%paletteId = new GuiControl(DecalEditorPalette,EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl(EDecalEditorSelectDecalBtn) { + canSaveDynamicFields = "0"; + internalName = "SelectDecalMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "DecalEditorGui.setMode(\"SelectDecalMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Select Decal (1)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/arrow"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(EDecalEditorMoveDecalBtn) { + canSaveDynamicFields = "0"; + internalName = "MoveDecalMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "DecalEditorGui.setMode(\"MoveDecalMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Move Decal (2)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/move-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(EDecalEditorRotateDecalBtn) { + canSaveDynamicFields = "0"; + internalName = "RotateDecalMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "DecalEditorGui.setMode(\"RotateDecalMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Rotate Decal (3)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/rotate-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(EDecalEditorScaleDecalBtn) { + canSaveDynamicFields = "0"; + internalName = "ScaleDecalMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "DecalEditorGui.setMode(\"ScaleDecalMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Scale Decal (4)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/scale-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(EDecalEditorAddDecalBtn) { + canSaveDynamicFields = "0"; + internalName = "AddDecalMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "DecalEditorGui.setMode(\"AddDecalMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Add Decal (5)"; + hovertime = "1000"; + bitmap = "tools/decalEditor/add-decal"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; +}; \ No newline at end of file diff --git a/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/ForestEditorPalette.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/ForestEditorPalette.ed.gui new file mode 100644 index 000000000..741d3b858 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/ForestEditorPalette.ed.gui @@ -0,0 +1,163 @@ +%paletteId = new GuiControl(ForestEditorPalette,EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl(ForestEditorSelectModeBtn) { + canSaveDynamicFields = "0"; + internalName = "ForestEditorSelectMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GlobalGizmoProfile.mode = \"None\"; ForestEditorGui.setActiveTool(ForestTools->SelectionTool);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Select Item (1)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/arrow"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ForestEditorMoveModeBtn) { + canSaveDynamicFields = "0"; + internalName = "ForestEditorMoveMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GlobalGizmoProfile.mode = \"Move\"; ForestEditorGui.setActiveTool(ForestTools->SelectionTool);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Move Item (2)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/translate"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ForestEditorRotateModeBtn) { + canSaveDynamicFields = "0"; + internalName = "ForestEditorRotateMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GlobalGizmoProfile.mode = \"Rotate\"; ForestEditorGui.setActiveTool(ForestTools->SelectionTool);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Rotate Item (3)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/rotate"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ForestEditorScaleModeBtn) { + canSaveDynamicFields = "0"; + internalName = "ForestEditorScaleMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GlobalGizmoProfile.mode = \"Scale\"; ForestEditorGui.setActiveTool(ForestTools->SelectionTool);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Scale Item (4)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/scale"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ForestEditorPaintModeBtn) { + canSaveDynamicFields = "0"; + internalName = "ForestEditorPaintMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ForestEditorGui.setActiveTool( ForestTools->BrushTool ); ForestTools->BrushTool.mode = \"Paint\";"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Paint (5)"; + hovertime = "1000"; + bitmap = "tools/foresteditor/images/paint-forest-btn"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ForestEditorEraseModeBtn) { + canSaveDynamicFields = "0"; + internalName = "ForestEditorEraseMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ForestEditorGui.setActiveTool( ForestTools->BrushTool ); ForestTools->BrushTool.mode = \"Erase\";"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Erase (6)"; + hovertime = "1000"; + bitmap = "tools/foresteditor/images/erase-all-btn"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(ForestEditorEraseSelectedModeBtn) { + canSaveDynamicFields = "0"; + internalName = "ForestEditorEraseSelectedMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ForestEditorGui.setActiveTool( ForestTools->BrushTool ); ForestTools->BrushTool.mode = \"EraseSelected\";"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Erase Selected (7)"; + hovertime = "1000"; + bitmap = "tools/foresteditor/images/erase-element-btn"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; +}; \ No newline at end of file diff --git a/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/MeshRoadEditorPalette.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/MeshRoadEditorPalette.ed.gui new file mode 100644 index 000000000..2f7a7d76e --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/MeshRoadEditorPalette.ed.gui @@ -0,0 +1,163 @@ +%paletteId = new GuiControl(MeshRoadEditorPalette,EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl(EMeshRoadEditorSelectModeBtn) { + canSaveDynamicFields = "0"; + internalName = "MeshRoadEditorSelectMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MeshRoadEditorGui.prepSelectionMode();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Select Mesh Road (1)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/arrow"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(EMeshRoadEditorMoveModeBtn) { + canSaveDynamicFields = "0"; + internalName = "MeshRoadEditorMoveMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MeshRoadEditorGui.setMode(\"MeshRoadEditorMoveMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Move Point (2)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/move-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(EMeshRoadEditorRotateModeBtn) { + canSaveDynamicFields = "0"; + internalName = "MeshRoadEditorRotateMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MeshRoadEditorGui.setMode(\"MeshRoadEditorRotateMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Rotate Point (3)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/rotate-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(EMeshRoadEditorScaleModeBtn) { + canSaveDynamicFields = "0"; + internalName = "MeshRoadEditorScaleMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MeshRoadEditorGui.setMode(\"MeshRoadEditorScaleMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Scale Point (4)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/scale-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(EMeshRoadEditorAddModeBtn) { + canSaveDynamicFields = "0"; + internalName = "MeshRoadEditorAddRoadMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MeshRoadEditorGui.setMode(\"MeshRoadEditorAddRoadMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Create Road (5)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/add-mesh-road"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(EMeshRoadEditorInsertModeBtn) { + canSaveDynamicFields = "0"; + internalName = "MeshRoadEditorInsertPointMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MeshRoadEditorGui.setMode(\"MeshRoadEditorInsertPointMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Insert Point (+)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/add-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(EMeshRoadEditorRemoveModeBtn) { + canSaveDynamicFields = "0"; + internalName = "MeshRoadEditorRemovePointMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MeshRoadEditorGui.setMode(\"MeshRoadEditorRemovePointMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Remove Point (-)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/subtract-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; +}; \ No newline at end of file diff --git a/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/RiverEditorPalette.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/RiverEditorPalette.ed.gui new file mode 100644 index 000000000..42c5ec588 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/RiverEditorPalette.ed.gui @@ -0,0 +1,163 @@ +%paletteId = new GuiControl(RiverEditorPalette,EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl(ERiverEditorSelectModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RiverEditorSelectMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RiverEditorGui.prepSelectionMode();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Select River (1)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/arrow"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ERiverEditorMoveModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RiverEditorMoveMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RiverEditorGui.setMode(\"RiverEditorMoveMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Move Point (2)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/move-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ERiverEditorRotateModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RiverEditorRotateMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RiverEditorGui.setMode(\"RiverEditorRotateMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Rotate Point (3)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/rotate-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ERiverEditorScaleModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RiverEditorScaleMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RiverEditorGui.setMode(\"RiverEditorScaleMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Scale Point (4)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/scale-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ERiverEditorAddModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RiverEditorAddRiverMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RiverEditorGui.setMode(\"RiverEditorAddRiverMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Create River (5)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/add-river"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ERiverEditorInsertModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RiverEditorInsertPointMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RiverEditorGui.setMode(\"RiverEditorInsertPointMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Insert Point (+)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/add-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(ERiverEditorRemoveModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RiverEditorRemovePointMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RiverEditorGui.setMode(\"RiverEditorRemovePointMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Remove Point (-)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/subtract-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; +}; \ No newline at end of file diff --git a/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/RoadEditorPalette.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/RoadEditorPalette.ed.gui new file mode 100644 index 000000000..576bc57aa --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/RoadEditorPalette.ed.gui @@ -0,0 +1,144 @@ +%paletteId = new GuiControl(RoadEditorPalette,EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl(ERoadEditorSelectModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RoadEditorSelectMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RoadEditorGui.prepSelectionMode();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Select Road (1)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/arrow"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(ERoadEditorMoveModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RoadEditorMoveMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RoadEditorGui.setMode(\"RoadEditorMoveMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Move Point (2)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/move-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(ERoadEditorScaleModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RoadEditorScaleMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RoadEditorGui.setMode(\"RoadEditorScaleMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Scale Point (4)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/scale-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ERoadEditorAddModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RoadEditorAddRoadMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RoadEditorGui.setMode(\"RoadEditorAddRoadMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Create Road (5)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/add-road-path"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ERoadEditorInsertModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RoadEditorInsertPointMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RoadEditorGui.setMode(\"RoadEditorInsertPointMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Insert Point (+)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/add-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(ERoadEditorRemoveModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RoadEditorRemovePointMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RoadEditorGui.setMode(\"RoadEditorRemovePointMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Remove Point (-)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/subtract-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; +}; \ No newline at end of file diff --git a/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/ShapeEditorPalette.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/ShapeEditorPalette.ed.gui new file mode 100644 index 000000000..403e0131c --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/ShapeEditorPalette.ed.gui @@ -0,0 +1,102 @@ +%paletteId = new GuiControl(ShapeEditorPalette,EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl(ShapeEditorNoneModeBtn) { + canSaveDynamicFields = "0"; + internalName = "WorldEditorSelectArrow"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GlobalGizmoProfile.mode = \"None\";"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Select Arrow (1)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/arrow"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(ShapeEditorMoveModeBtn) { + canSaveDynamicFields = "0"; + internalName = "WorldEditorMove"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "28 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GlobalGizmoProfile.mode = \"Move\";"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Move Selection (2)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/translate"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(ShapeEditorRotateModeBtn) { + canSaveDynamicFields = "0"; + internalName = "WorldEditorRotate"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "56 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GlobalGizmoProfile.mode = \"Rotate\";"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Rotate Selection (3)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/rotate"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(ShapeEditorSunModeBtn) { + canSaveDynamicFields = "0"; + internalName = ""; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "84 0"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Variable = "ShapeEdShapeView.editSun"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Rotate sun"; + hovertime = "1000"; + bitmap = "tools/shapeEditor/images/sun-btn"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; +}; diff --git a/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/TerrainEditPalette.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/TerrainEditPalette.ed.gui new file mode 100644 index 000000000..741350269 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/TerrainEditPalette.ed.gui @@ -0,0 +1,213 @@ +%paletteId = new GuiControl(TerrainEditorPalette,EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "brushAdjustHeight"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "72 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.switchAction( brushAdjustHeight );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Grab Terrain (1)"; + hovertime = "750"; + text = "Button"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/brushAdjustHeight"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "raiseHeight"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.switchAction( raiseHeight );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Raise Height (2)"; + hovertime = "750"; + text = "Button"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/raiseHeight"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "lowerHeight"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "36 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.switchAction( lowerHeight );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Lower Height (3)"; + hovertime = "750"; + text = "Button"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/lowerHeight"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "smoothHeight"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "144 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.switchAction( smoothHeight );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Smooth (4)"; + hovertime = "750"; + text = "Button"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/smoothHeight"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "paintNoise"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "72 36"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.switchAction( paintNoise );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Paint Noise (5)"; + hovertime = "750"; + text = "Button"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/brushPaintNoise"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "flattenHeight"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "108 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.switchAction( flattenHeight );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Flatten (6)"; + hovertime = "750"; + text = "Button"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/flattenHeight"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "setHeight"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "180 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.switchAction( setHeight );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Set Height (7)"; + hovertime = "750"; + text = "Button"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/setHeight"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "setEmpty"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 36"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.switchAction( setEmpty );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Clear Terrain (8)"; + hovertime = "750"; + text = "Button"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/setEmpty"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "clearEmpty"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "36 36"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.switchAction( clearEmpty );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Restore Terrain (9)"; + hovertime = "750"; + text = "Button"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/clearEmpty"; + }; +}; \ No newline at end of file diff --git a/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/TerrainPainterPalette.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/TerrainPainterPalette.ed.gui new file mode 100644 index 000000000..3a61a9dba --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/TerrainPainterPalette.ed.gui @@ -0,0 +1,14 @@ +%paletteId = new GuiControl(TerrainPainterPalette,EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; +}; \ No newline at end of file diff --git a/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/WorldEditorPalette.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/WorldEditorPalette.ed.gui new file mode 100644 index 000000000..923fe38c5 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/WorldEditorPalette.ed.gui @@ -0,0 +1,98 @@ +%paletteId = new GuiControl(WorldEditorInspectorPalette, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl(EWorldEditorNoneModeBtn) { + canSaveDynamicFields = "0"; + internalName = "WorldEditorSelectArrow"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Select Arrow (1)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/arrow"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(EWorldEditorMoveModeBtn) { + canSaveDynamicFields = "0"; + internalName = "WorldEditorMove"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "28 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Move Selection (2)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/translate"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(EWorldEditorRotateModeBtn) { + canSaveDynamicFields = "0"; + internalName = "WorldEditorRotate"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "56 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Rotate Selection (3)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/rotate"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(EWorldEditorScaleModeBtn) { + canSaveDynamicFields = "0"; + internalName = "WorldEditorScale"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "84 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Scale Selection (4)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/scale"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; +}; \ No newline at end of file diff --git a/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/init.cs b/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/init.cs new file mode 100644 index 000000000..637739745 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/init.cs @@ -0,0 +1,102 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function EWToolsPaletteWindow::loadToolsPalettes() +{ + %filespec = "tools/worldEditor/gui/ToolsPaletteGroups/*.ed.gui"; + + // were executing each gui file and adding them to the ToolsPaletteArray + for( %file = findFirstFile(%filespec); %file !$= ""; %file = findNextFile(%filespec)) + { + exec( %file ); + %paletteGroup = 0; + + %i = %paletteId.getCount(); + for( ; %i != 0; %i--) + { + %paletteId.getObject(0).visible = 0; + %paletteId.getObject(0).groupNum = %paletteGroup; + %paletteId.getObject(0).paletteName = %paletteId.getName(); + ToolsPaletteArray.addGuiControl(%paletteId.getObject(0)); + } + %paletteGroup++; + } + + %filespec = "tools/worldEditor/gui/ToolsPaletteGroups/*.ed.gui.edso"; + + // were executing each gui file and adding them to the ToolsPaletteArray + for( %file = findFirstFile(%filespec); %file !$= ""; %file = findNextFile(%filespec)) + { + exec( %file ); + %paletteGroup = 0; + + %i = %paletteId.getCount(); + for( ; %i != 0; %i--) + { + %paletteId.getObject(0).visible = 0; + %paletteId.getObject(0).groupNum = %paletteGroup; + %paletteId.getObject(0).paletteName = %paletteId.getName(); + ToolsPaletteArray.addGuiControl(%paletteId.getObject(0)); + } + %paletteGroup++; + } +} + +function EWToolsPaletteWindow::init() +{ + EWToolsPaletteWindow.loadToolsPalettes(); +} + +function EWToolsPaletteWindow::togglePalette(%this, %paletteName) +{ + // since the palette window ctrl auto adjusts to child ctrls being visible, + // loop through the array and pick out the children that belong to a certain tool + // and label them visible or not visible + + for( %i = 0; %i < ToolsPaletteArray.getCount(); %i++ ) + ToolsPaletteArray.getObject(%i).visible = 0; + + %windowMultiplier = 0; + %paletteNameWordCount = getWordCount( %paletteName ); + for(%pallateNum = 0; %pallateNum < %paletteNameWordCount; %pallateNum++) + { + %currentPalette = getWord(%paletteName, %pallateNum); + for( %i = 0; %i < ToolsPaletteArray.getCount(); %i++ ) + { + if( ToolsPaletteArray.getObject(%i).paletteName $= %currentPalette) + { + ToolsPaletteArray.getObject(%i).visible = 1; + %windowMultiplier++; + } + } + } + + // auto adjust the palette window extent according to how many + // children controls we found; if none found, the palette window becomes invisible + if( %windowMultiplier == 0 || %paletteName $= "") + EWToolsPaletteWindow.visible = 0; + else + { + EWToolsPaletteWindow.visible = 1; + EWToolsPaletteWindow.extent = getWord(EWToolsPaletteWindow.extent, 0) SPC (16 + 26 * %windowMultiplier); + } +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteWindow.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteWindow.ed.gui new file mode 100644 index 000000000..871886695 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteWindow.ed.gui @@ -0,0 +1,68 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl(EWToolsPaletteWindow) { + canSaveDynamicFields = "0"; + internalName = "ToolsPaletteWindow"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiToolbarWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Extent = "36 24"; + MinExtent = "36 24"; + Position = "-1 63"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "4 4 4 4"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = false; + text = ""; + class = "EWToolsPaletteWindowClass"; + + new GuiDynamicCtrlArrayControl(ToolsPaletteArray) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "5 15"; + Extent = "35 514"; + MinExtent = "35 514"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + colCount = "1"; + colSize = "26"; + RowSize = "22"; + rowSpacing = "3"; + colSpacing = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- \ No newline at end of file diff --git a/Templates/Empty/game/tools/worldEditor/gui/ToolsToolbar.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/ToolsToolbar.ed.gui new file mode 100644 index 000000000..ebe6a595a --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/ToolsToolbar.ed.gui @@ -0,0 +1,72 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiContainer(EWToolsToolbar) { + canSaveDynamicFields = "0"; + Enabled = "0"; + internalName = "ToolsToolbar"; + isContainer = "1"; + Profile = "editorMenubarProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 31"; + Extent = (29 + 4) * 14 + 12 SPC "33"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + isClosed = "0"; + isDynamic = "0"; + + new GuiDynamicCtrlArrayControl(ToolsToolbarArray) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "4 3"; + Extent = "264 32"; + MinExtent = "1024 32"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + colCount = "1"; + colSize = "29"; + RowSize = "27"; + rowSpacing = "2"; + colSpacing = "4"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + internalName = "resizeArrow"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = getWord(EWToolsToolbar.Extent, 0) - 7 SPC "0"; + extent = "7 33"; + MinExtent = "7 2"; + canSave = "1"; + Visible = "1"; + Command = "EWToolsToolbar.ToggleSize();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Collapse Toolbar"; + hovertime = "750"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "core/art/gui/images/collapse-toolbar"; + }; + new GuiDecoyCtrl(EWToolsToolbarDecoy) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "1 1"; + extent = "35 31"; + minExtent = "8 8"; + visible = "0"; + helpTag = "0"; + useMouseEvents = "1"; + isDecoy = "1"; + }; +}; + diff --git a/Templates/Empty/game/tools/worldEditor/gui/TransformSelectionWindow.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/TransformSelectionWindow.ed.gui new file mode 100644 index 000000000..1380822e8 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/TransformSelectionWindow.ed.gui @@ -0,0 +1,1026 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(TransformSelectionContainer, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiModelessDialogProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCollapseCtrl(ETransformSelection) { + internalName = "TransformSelectionWindow"; + Enabled = "1"; + isContainer = "1"; + profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + resizeWidth = "1"; + resizeHeight = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + position = "40 70"; + extent = "180 508"; + MinExtent = "120 130"; + text = "Transform Selection"; + closeCommand = "ETransformSelection.hideDialog();"; + EdgeSnap = "0"; + canCollapse = "0"; + visible = "0"; + Margin = "5 5 5 5"; + Padding = "5 5 5 5"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "4 12"; + Extent = "156 190"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "5 5 5 4"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "2 2"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "5"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "140 300"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "140 106"; + MinExtent = "16 16"; + Visible = "1"; + + new GuiCheckBoxCtrl(){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "DoPosition"; + Enabled = "1"; + Profile = "GuiCheckBoxProfile"; + position = "1 0"; + Extent = "190 18"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Apply changes to position"; + text = "Position"; + Command = ""; + }; + + new GuiButtonCtrl() { + class = "ETransformSelectionButtonClass"; + internalName = "GetPosButton"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "100 0"; + Extent = "30 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ETransformSelection.getAbsPosition();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Get absolute position for selected objects"; + text = "Get"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 22"; + Extent = "20 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "X:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + class = "ETransformSelectionTextEdit"; + internalName = "PosX"; + profile="GuiTextEditProfileNumbersOnly"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "40 22"; + Extent = "90 18"; + text ="0.0"; + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 44"; + Extent = "20 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Y:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + class = "ETransformSelectionTextEdit"; + internalName = "PosY"; + profile="GuiTextEditProfileNumbersOnly"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "40 44"; + Extent = "90 18"; + text ="0.0"; + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 66"; + Extent = "20 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Z:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + class = "ETransformSelectionTextEdit"; + internalName = "PosZ"; + profile="GuiTextEditProfileNumbersOnly"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "40 66"; + Extent = "90 18"; + text ="0.0"; + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiCheckBoxCtrl(){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "PosRelative"; + Enabled = "1"; + Profile = "GuiCheckBoxProfile"; + position = "40 88"; + Extent = "120 18"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Add values to current position (checked) or set absolute position (unchecked)"; + text = "Relative"; + Command = ""; + }; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + position = "0 0"; + Extent = "100 2"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-v.png"; + }; + + new GuiControl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "140 128"; + MinExtent = "16 16"; + Visible = "1"; + + new GuiCheckBoxCtrl(){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "DoRotation"; + Enabled = "1"; + Profile = "GuiCheckBoxProfile"; + position = "1 0"; + Extent = "190 18"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Apply changes to rotation"; + text = "Rotation"; + Command = ""; + }; + + new GuiButtonCtrl() { + class = "ETransformSelectionButtonClass"; + internalName = "GetRotButton"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "100 0"; + Extent = "30 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ETransformSelection.getAbsRotation();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Get absolute rotation for selected objects"; + text = "Get"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 22"; + Extent = "20 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "H:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + class = "ETransformSelectionTextEdit"; + internalName = "Heading"; + profile="GuiTextEditProfileNumbersOnly"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "40 22"; + Extent = "90 18"; + text ="0.0"; + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 44"; + Extent = "20 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "P:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + class = "ETransformSelectionTextEdit"; + internalName = "Pitch"; + profile="GuiTextEditProfileNumbersOnly"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "40 44"; + Extent = "90 18"; + text ="0.0"; + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 66"; + Extent = "20 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "B:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + class = "ETransformSelectionTextEdit"; + internalName = "Bank"; + profile="GuiTextEditProfileNumbersOnly"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "40 66"; + Extent = "90 18"; + text ="0.0"; + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiCheckBoxCtrl(){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "RotRelative"; + Enabled = "1"; + Profile = "GuiCheckBoxProfile"; + position = "40 88"; + Extent = "120 18"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Add values to current rotation (checked) or set absolute rotation (unchecked)"; + text = "Relative"; + Command = "ETransformSelection.RotRelativeChanged();"; + }; + + new GuiCheckBoxCtrl(){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "RotLocal"; + Enabled = "1"; + Profile = "GuiCheckBoxProfile"; + position = "40 110"; + Extent = "120 18"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Use object's local origin to rotate from"; + text = "Local Center"; + Command = "ETransformSelection.RotLocalChanged();"; + }; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + position = "0 0"; + Extent = "100 2"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-v.png"; + }; + + new GuiTabBookCtrl() { + internalName = "ScaleTabBook"; + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "140 176"; + MinExtent = "16 16"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "3 2 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + TabPosition = "Top"; + TabMargin = "0"; + MinTabWidth = "50"; + + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 19"; + Extent = "140 156"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Scale"; + maxLength = "1024"; + + new GuiBitmapBorderCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTabBorderProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "134 156"; + MinExtent = "8 2"; + canSave = "0"; + Visible = "1"; + hovertime = "1000"; + }; + + new GuiControl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "134 156"; + MinExtent = "16 16"; + Visible = "1"; + + new GuiCheckBoxCtrl(){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "DoScale"; + Enabled = "1"; + Profile = "GuiCheckBoxProfile"; + position = "2 4"; + Extent = "100 18"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Apply changes to scale"; + text = "Scale"; + Command = ""; + }; + + new GuiButtonCtrl() { + class = "ETransformSelectionButtonClass"; + internalName = "GetScaleButton"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "100 4"; + Extent = "30 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ETransformSelection.getAbsScale();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Get absolute scale for selected objects"; + text = "Get"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 26"; + Extent = "20 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "X:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + class = "ETransformSelectionTextEdit"; + internalName = "ScaleX"; + profile="GuiTextEditProfileNumbersOnly"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "40 26"; + Extent = "90 18"; + text ="1.0"; + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 48"; + Extent = "20 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Y:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + class = "ETransformSelectionTextEdit"; + internalName = "ScaleY"; + profile="GuiTextEditProfileNumbersOnly"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "40 48"; + Extent = "90 18"; + text ="1.0"; + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 70"; + Extent = "20 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Z:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + class = "ETransformSelectionTextEdit"; + internalName = "ScaleZ"; + profile="GuiTextEditProfileNumbersOnly"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "40 70"; + Extent = "90 18"; + text ="1.0"; + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiCheckBoxCtrl(){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "ScaleRelative"; + Enabled = "1"; + Profile = "GuiCheckBoxProfile"; + position = "40 92"; + Extent = "120 18"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Add values to current scale (checked) or set absolute scale (unchecked)"; + text = "Relative"; + Command = ""; + }; + + new GuiCheckBoxCtrl(){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "ScaleLocal"; + Enabled = "1"; + Profile = "GuiCheckBoxProfile"; + position = "40 114"; + Extent = "120 18"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Use object's local origin to scale from"; + text = "Local Center"; + Command = ""; + }; + + new GuiCheckBoxCtrl(ETransformSelectionScaleProportional){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "ScaleProportional"; + Enabled = "1"; + Profile = "GuiCheckBoxProfile"; + position = "40 136"; + Extent = "120 18"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Scale equally in all directions"; + text = "Constrain Proportions"; + Command = ""; + }; + }; + }; + + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 19"; + Extent = "140 156"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Size"; + maxLength = "1024"; + + new GuiBitmapBorderCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTabBorderProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "134 156"; + MinExtent = "8 2"; + canSave = "0"; + Visible = "1"; + hovertime = "1000"; + }; + + new GuiControl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "134 156"; + MinExtent = "16 16"; + Visible = "1"; + + new GuiCheckBoxCtrl(){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "DoSize"; + Enabled = "1"; + Profile = "GuiCheckBoxProfile"; + position = "2 4"; + Extent = "100 18"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Apply changes to size"; + text = "Size"; + Command = ""; + }; + + new GuiButtonCtrl() { + class = "ETransformSelectionButtonClass"; + internalName = "GetSizeButton"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "100 4"; + Extent = "30 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ETransformSelection.getAbsSize();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Get absolute size for selected objects"; + text = "Get"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 26"; + Extent = "20 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "X:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + class = "ETransformSelectionTextEdit"; + internalName = "SizeX"; + profile="GuiTextEditProfileNumbersOnly"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "40 26"; + Extent = "90 18"; + text ="1.0"; + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 48"; + Extent = "20 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Y:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + class = "ETransformSelectionTextEdit"; + internalName = "SizeY"; + profile="GuiTextEditProfileNumbersOnly"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "40 48"; + Extent = "90 18"; + text ="1.0"; + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 70"; + Extent = "20 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Z:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + class = "ETransformSelectionTextEdit"; + internalName = "SizeZ"; + profile="GuiTextEditProfileNumbersOnly"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "40 70"; + Extent = "90 18"; + text ="1.0"; + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiCheckBoxCtrl(){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "SizeRelative"; + Enabled = "1"; + Profile = "GuiCheckBoxProfile"; + position = "40 92"; + Extent = "120 18"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Add values to current size (checked) or set absolute size (unchecked)"; + text = "Relative"; + Command = ""; + }; + + new GuiCheckBoxCtrl(){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "SizeLocal"; + Enabled = "1"; + Profile = "GuiCheckBoxProfile"; + position = "40 114"; + Extent = "120 18"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Use object's local origin to size from"; + text = "Local Center"; + Command = ""; + }; + + new GuiCheckBoxCtrl(ETransformSelectionSizeProportional){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "SizeProportional"; + Enabled = "1"; + Profile = "GuiCheckBoxProfile"; + position = "40 136"; + Extent = "120 18"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Size equally in all directions"; + text = "Constrain Proportions"; + Command = ""; + }; + }; + }; + }; + }; + }; + + new GuiContainer(){ + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "190 24"; + Docking = "Bottom"; + Margin = "5 5 5 5"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + + new GuiButtonCtrl() { + class = "ETransformSelectionButtonClass"; + internalName = "ApplyButton"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "50 23"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ETransformSelection.apply();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Apply"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiButtonCtrl() { + class = "ETransformSelectionButtonClass"; + internalName = "CloseButton"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "140 0"; + Extent = "50 23"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ETransformSelection.hideDialog();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Close"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; + + }; +}; \ No newline at end of file diff --git a/Templates/Empty/game/tools/worldEditor/gui/VisibilityLayerWindow.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/VisibilityLayerWindow.ed.gui new file mode 100644 index 000000000..f3db70c76 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/VisibilityLayerWindow.ed.gui @@ -0,0 +1,278 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(VisibilityLayerContainer, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiModelessDialogProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCtrl(EVisibility) { + internalName = "VisibilityLayerWindow"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiToolbarWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord(visibilityToggleBtn.position, 0) SPC getWord(EditorGuiToolbar.extent, 1); + Extent = "161 250"; //175 696 = full length + MinExtent = "161 86"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + hovertime = "1000"; + Docking = "None"; + Margin = "4 4 4 4"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "152 300"; + closeCommand = ""; + EdgeSnap = "1"; + text = ""; + + new GuiTabBookCtrl(EVisibilityTabBook) { + canSaveDynamicFields = "0"; + Profile = "GuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Margin = "3 1 3 3"; + Position = "5 24"; + Extent = "170 226"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + TabPosition = "Top"; + TabHeight = "22"; + TabMargin = "7"; + MinTabWidth = "8"; + + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Profile = "GuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Margin = "-1 0 0 0"; + Position = "0 14"; + Extent = "164 220"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + text = "Visual"; + maxLength = "255"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Position = "4 12"; + Extent = "156 190"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "2 0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "-2"; + canSaveDynamicFields = "0"; + internalName = "theVisOptionsList"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 0"; + Extent = "156 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + }; + }; + }; + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Profile = "GuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Margin = "-1 0 0 0"; + Position = "0 14"; + Extent = "164 220"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + text = "Visible"; + maxLength = "255"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Position = "4 12"; + Extent = "156 190"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "2 0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "-2"; + canSaveDynamicFields = "0"; + internalName = "theClassVisList"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 0"; + Extent = "156 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + }; + }; + }; + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Profile = "GuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Margin = "-1 0 0 0"; + Position = "0 14"; + Extent = "164 220"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + text = "Select"; + maxLength = "255"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Position = "4 12"; + Extent = "156 190"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "2 0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "-2"; + canSaveDynamicFields = "0"; + internalName = "theClassSelList"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 0"; + Extent = "156 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + }; + }; + }; + }; + }; +}; \ No newline at end of file diff --git a/Templates/Empty/game/tools/worldEditor/gui/WorldEditorInspectorWindow.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/WorldEditorInspectorWindow.ed.gui new file mode 100644 index 000000000..671cee23f --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/WorldEditorInspectorWindow.ed.gui @@ -0,0 +1,143 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCollapseCtrl(EWInspectorWindow) { + canSaveDynamicFields = "0"; + internalName = "InspectorWindow"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + Position = getWord($pref::Video::mode, 0) - 209 SPC + getWord(EditorGuiToolbar.extent, 1) + getWord(EWTreeWindow.extent, 1) - 2; + Extent = "210 373"; + MinExtent = "210 140"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "8 8 8 8"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + closeCommand = "EWInspectorWindow.setVisible(false);"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Inspector"; + + new GuiContainer() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "4 24"; + Extent = "202 304"; + MinExtent = "64 64"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "client"; + Margin = "3 41 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 304"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiInspector(Inspector) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiInspectorProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "202 309"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + dividerMargin = "5"; + superClass = "EditorInspectorBase"; + }; + }; + }; + new GuiMLTextCtrl(FieldInfoControl) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorFieldInfoMLTextProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "1 328"; + Extent = "205 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/worldEditor/gui/WorldEditorToolbar.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/WorldEditorToolbar.ed.gui new file mode 100644 index 000000000..148c210c7 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/WorldEditorToolbar.ed.gui @@ -0,0 +1,673 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(EWorldEditorToolbar, EditorGuiGroup) { + canSaveDynamicFields = "0"; + internalName = "WorldEditorToolbar"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "306 0"; + Extent = "550" SPC getWord(EditorGuiToolbar.extent, 1); + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + + new GuiStackControl() { + StackingType = "Horizontal"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 3"; + Extent = "190 31"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + changeChildSizeToFit = false; + padding = "2"; + + new GuiBitmapButtonCtrl(FitToSelectionBtn) { + canSaveDynamicFields = "0"; + internalName = ""; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "2 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "commandToServer('EditorCameraAutoFit', EWorldEditor.getSelectionRadius()+1);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Fit View To Selection (F)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/fit-selection"; + text = ""; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + position = "34 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-h.png"; + }; + + new GuiTextCtrl() { + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "37 7"; + extent = "77 16"; + minExtent = "8 8"; + visible = "1"; + text = " World Settings"; + maxLength = "255"; + helpTag = "0"; + }; + + new GuiControl(SnapToBar){ + isContainer = "1"; + profile = "GuiDefaultProfile"; + Position = "116 3"; + Extent = "123 27"; + Padding = "4"; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "snappingSettingsBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command ="ESnapOptions.ToggleVisibility();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Snapping Options"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + buttonMargin = "0 0"; + bitmap = "tools/gui/images/menubar/snapping-settings"; + + new GuiBitmapCtrl(){ + HorizSizing = "left"; + VertSizing = "top"; + Position = "23 21"; + Extent = "4 4"; + MinExtent = "4 4"; + bitmap = "core/art/gui/images/dropdown-button-arrow"; + }; + }; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "objectGridSnapBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "31 0"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "toggleSnappingOptions(\"grid\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Toggles grid snapping (G)"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "toggleButton"; + useMouseEvents = "0"; + groupNum = "-1"; + bitmap = "tools/gui/images/menubar/snap-grid"; + textMargin = "4"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "objectSnapDownBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "62 0"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "toggleSnappingOptions(\"terrain\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "All objects will snap to the terrain (T)"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "toggleButton"; + useMouseEvents = "0"; + groupNum = "-1"; + bitmap = "tools/gui/images/menubar/snap-terrain"; + textMargin = "4"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "objectSnapBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "93 0"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "toggleSnappingOptions(\"soft\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Soft object snapping to other objects (B)"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "toggleButton"; + useMouseEvents = "0"; + groupNum = "-1"; + bitmap = "tools/gui/images/menubar/snap-objects"; + textMargin = "4"; + }; + }; + new GuiControl() { + canSaveDynamicFields = "0"; + internalName = "softSnapSizeTextEditContainer"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "178 5"; + Extent = "56 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "softSnapSizeTextEdit"; + isContainer = "0"; + HorizSizing = "right"; + profile="GuiNumericDropSliderTextProfile"; + VertSizing = "bottom"; + position = "0 2"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + AltCommand = "EWorldEditor.setSoftSnapSize( $ThisControl.getText() ); EWorldEditor.syncGui();"; + tooltip = "Object Snapping Distance"; + hovertime = "1000"; + text = "9"; + maxLength = "6"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "34 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(softSnapSizeSliderCtrlContainer);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Changes size of the soft snap region"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "core/art/gui/images/dropslider"; + }; + }; + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + position = "269 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-h.png"; + }; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "boundingBoxColBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "274 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Variable = "EWorldEditor.boundingBoxCollision"; + Command = "EWorldEditor.boundingBoxCollision = $ThisControl.getValue();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Object bounds selection toggle (V)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/select-bounds"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + position = "307 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-h.png"; + }; + + new GuiControl(ToggleButtonBar){ + isContainer = "1"; + profile = "GuiDefaultProfile"; + Position = "313 3"; + Extent = "65 27"; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "centerObject"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "objectCenterDropdown.toggle();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Toggles object center (O) and bounds center (P)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/object-center"; + text = "Button"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + + new GuiBitmapCtrl(){ + HorizSizing = "left"; + VertSizing = "top"; + Position = "23 21"; + Extent = "4 4"; + MinExtent = "4 4"; + bitmap = "core/art/gui/images/dropdown-button-arrow"; + }; + }; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "objectTransform"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "31 0"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "objectTransformDropdown.toggle();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Toggles object transform (K) and world transform (L)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/world-transform"; + groupNum = "-1"; + buttonType = "ToggleButton"; + text = ""; + + new GuiBitmapCtrl(){ + HorizSizing = "left"; + VertSizing = "top"; + Position = "23 21"; + Extent = "4 4"; + MinExtent = "4 4"; + bitmap = "core/art/gui/images/dropdown-button-arrow"; + }; + }; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + position = "379 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-h.png"; + }; + + new GuiControl(ToggleNodeBar){ + isContainer = "1"; + profile = "GuiDefaultProfile"; + Position = "386 3"; + Extent = "63 27"; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "renderHandleBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Variable = "EWorldEditor.renderObjHandle"; + Command = "EWorldEditor.renderObjHandle = $ThisControl.getValue();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Enables Render of Object Node Icons (N)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/object-node-icon"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "renderTextBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "33 0"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Variable = "EWorldEditor.renderObjText"; + Command = "EWorldEditor.renderObjText = $ThisControl.getValue();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Enables Render of Object Node Lables (SHIFT N)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/object-node-lable"; + text = ""; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + }; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "GuiDefaultProfile"; + position = "379 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "core/art/gui/images/separator-h.png"; + }; + + new GuiControl(PrefabBar){ + isContainer = "1"; + profile = "GuiDefaultProfile"; + Position = "386 3"; + Extent = "63 27"; + visible = true; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "makePrefabBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Variable = ""; + Command = "EditorMakePrefab();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Make the Selection a Prefab."; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/selection-to-prefab"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "explodePrefabBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "33 0"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Variable = ""; + Command = "EditorExplodePrefab();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Explode the Selected Prefab."; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/explode-prefab"; + text = ""; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; + + new GuiContainer(objectCenterDropdown){ + Profile = "IconDropdownProfile"; + Position = getWord(EWorldEditorToolbar.position, 0)+getWord(ToggleButtonBar.Position, 0)+getWord(EWorldEditorToolbar-->centerObject.position, 0)-5 SPC getWord(EditorGuiToolbar.extent, 1)-1; + Extent = "132 62"; + isContainer = "1"; + visible = "0"; + + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "objectBoxBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiIconButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 5"; + Extent = "122 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "EWorldEditor.objectsUseBoxCenter = 0; EWorldEditor.syncGui(); objectCenterDropdown.toggle(); "; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Use object defined center (O)"; + hovertime = "1000"; + iconBitmap = "tools/gui/images/menubar/object-center_n"; + text = "Object Center"; + buttonMargin = "0 4"; + textMargin = "38"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "objectBoundsBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiIconButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 33 "; + Extent = "122 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "EWorldEditor.objectsUseBoxCenter = 1; EWorldEditor.syncGui(); objectCenterDropdown.toggle(); "; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Use bounding box center (P)"; + hovertime = "1000"; + iconBitmap = "tools/gui/images/menubar/bounds-center_n"; + text = "Bounds Center"; + buttonMargin = "0 4"; + textMargin = "38"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiDecoyCtrl(objectCenterDropdownDecoy) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "132 62"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + useMouseEvents = "1"; + isDecoy = "1"; + }; + }; + + new GuiContainer(objectTransformDropdown){ + Profile = "IconDropdownProfile"; + Position = getWord(EWorldEditorToolbar.position, 0)+getWord(ToggleButtonBar.position, 0)+getWord(EWorldEditorToolbar-->objectTransform.position, 0)-5 SPC getWord(EditorGuiToolbar.extent, 1)-1; + Extent = "147 62"; + isContainer = "1"; + visible ="0"; + + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "worldTransformBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiIconProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 5"; + Extent = "137 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "GlobalGizmoProfile.setFieldValue(alignment, World); EWorldEditor.syncGui(); objectTransformDropdown.toggle(); "; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Use world normal for transformations (L)"; + hovertime = "1000"; + iconBitmap = "tools/gui/images/menubar/world-transform_n"; + text = "World Transform"; + buttonMargin = "0 4"; + textMargin = "38"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "objectTransformBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiIconButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 33"; + Extent = "137 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "GlobalGizmoProfile.setFieldValue(alignment, Object); EWorldEditor.syncGui(); objectTransformDropdown.toggle(); "; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Use object normal for transformations (K)"; + hovertime = "1000"; + iconBitmap = "tools/gui/images/menubar/object-transform_n"; + text = "Object Transform"; + buttonMargin = "0 4"; + textMargin = "38"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiDecoyCtrl(objectTransformDropdownDecoy) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "147 62"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + useMouseEvents = "1"; + isDecoy = "1"; + }; + }; + }; +}; + +new GuiMouseEventCtrl(softSnapSizeSliderCtrlContainer, EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "GuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(EWorldEditorToolbar-->softSnapSizeTextEdit.getGlobalPosition()) - 12 SPC + (getWord(EWorldEditorToolbar-->softSnapSizeTextEdit.getGlobalPosition(), 1)) + 18; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "softSnapSizeSliderCtrlContainer.onSliderChanged();"; + range = "0.01 10"; + ticks = "0"; + value = "0"; + }; +}; diff --git a/Templates/Empty/game/tools/worldEditor/gui/WorldEditorTreeWindow.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/WorldEditorTreeWindow.ed.gui new file mode 100644 index 000000000..7018a9596 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/WorldEditorTreeWindow.ed.gui @@ -0,0 +1,577 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCollapseCtrl(EWTreeWindow) { + canSaveDynamicFields = "0"; + internalName = "TreeWindow"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + Position = firstWord($pref::Video::mode) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) -1; + Extent = "210 324"; + MinExtent = "210 140"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "8 8 8 8"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "EWTreeWindow.setVisible(false);"; + EdgeSnap = "1"; + text = "Scene Tree"; + + new GuiTabBookCtrl(EditorTreeTabBook) { + canSaveDynamicFields = "0"; + isContainer = "1"; + internalName = "EditorTree"; + Profile = "GuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "6 27"; + Extent = "197 289"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "3 2 3 3"; + Docking = "client"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + TabPosition = "Top"; + TabMargin = "0"; + MinTabWidth = "64"; + + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "EditorTabPage"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 19"; + Extent = "197 271"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Scene"; + maxLength = "1024"; + + new GuiTextEditCtrl( EditorTreeFilter ) { + position = "2 4"; + extent = "175 18"; + profile = "GuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + class = "GuiTreeViewFilterText"; + treeView = EditorTree; + }; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/clear-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "180 5"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + class = "GuiTreeViewFilterClearButton"; + textCtrl = EditorTreeFilter; + }; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 25"; + Extent = "197 246"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "false"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiTreeViewCtrl(EditorTree) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "193 21"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "1"; + MultipleSelections = "1"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "1"; + showRoot = "1"; + useInspectorTooltips = "1"; + tooltipOnWidthOnly = "1"; + showObjectIds = "0"; + showClassNames = "0"; + showObjectNames = "1"; + showInternalNames = "1"; + showClassNameForUnnamedObjects = "1"; + }; + }; + }; + new GuiTabPageCtrl(EWCreatorWindow) { + canSaveDynamicFields = "0"; + internalName = "CreatorWindow"; + Enabled = "1"; + isContainer = "1"; + Profile = "EditorTabPage"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 19"; + Extent = "208 274"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Library"; + maxLength = "1024"; + + new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "198 271"; + MinExtent = "8 2"; + canSave = "0"; + Visible = "1"; + }; + new GuiBitmapBorderCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTabBorderProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "198 271"; + MinExtent = "8 2"; + canSave = "0"; + Visible = "1"; + hovertime = "1000"; + }; + new GuiBitmapBorderCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTabBorderProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 25"; + Extent = "198 246"; + MinExtent = "8 2"; + canSave = "0"; + Visible = "1"; + hovertime = "1000"; + }; + new GuiContainer() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "-4 47"; + Extent = "206 228"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "4 4 4 4"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "EditorLightScrollProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 4"; + Extent = "198 220"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "alwaysOff"; + lockHorizScroll = "false"; + lockVertScroll = "true"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiDynamicCtrlArrayControl(CreatorIconArray) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "1 1"; + Extent = "197 218"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + colCount = "20"; + colSize = "64"; + rowCount = "0"; + RowSize = "32"; + rowSpacing = "4"; + colSpacing = "4"; + frozen = "0"; + autoCellSize = "1"; + fillRowFirst = "0"; + dynamicSize = "1"; + }; + }; + }; + new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "-3 2"; + Extent = "202 55"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl(CreatorNavUpButton) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "9 28"; + Extent = "20 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "EWCreatorWindow.navigateUp();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "PushButton"; + + Bitmap = "tools/gui/images/folderUp"; + autoSize = "0"; + }; + new GuiPopUpMenuCtrl(CreatorPopupMenu) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "32 28"; + Extent = "163 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Interiors"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + new GuiTabBookCtrl(CreatorTabBook) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "6 4"; + Extent = "198 21"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "None"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + TabPosition = "Top"; + TabMargin = "4"; + MinTabWidth = "49"; + + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "0 0"; + MinExtent = "0 0"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Scripted"; + maxLength = "1024"; + }; + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "0 0"; + MinExtent = "0 0"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Meshes"; + maxLength = "1024"; + }; + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "0 0"; + MinExtent = "0 0"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Level"; + maxLength = "1024"; + }; + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "0 0"; + MinExtent = "0 0"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Prefabs"; + maxLength = "1024"; + }; + }; + }; + }; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "LockSelection"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "157 26"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "EWorldEditor.lockSelection(true); EditorTree.toggleLock();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Lock Selection"; + hovertime = "1000"; + bitmap = "tools/gui/images/lock"; + buttonType = "ToggleButton"; + groupNum = "-1"; + text = ""; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(EWAddSimGroupButton) { + canSaveDynamicFields = "0"; + internalName = "AddSimGroup"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "173 26"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Add Sim Group"; + hovertime = "1000"; + bitmap = "tools/gui/images/add-simgroup-btn"; + buttonType = "PushButton"; + groupNum = "-1"; + text = ""; + useMouseEvents = "0"; + useModifiers = "1"; + }; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "DeleteSelection"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "189 26"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "EditorMenuEditDelete();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Delete Selection"; + hovertime = "1000"; + bitmap = "tools/gui/images/delete"; + buttonType = "PushButton"; + groupNum = "-1"; + text = ""; + useMouseEvents = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/worldEditor/gui/guiCreateNewTerrainGui.gui b/Templates/Empty/game/tools/worldEditor/gui/guiCreateNewTerrainGui.gui new file mode 100644 index 000000000..f11e4578d --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/guiCreateNewTerrainGui.gui @@ -0,0 +1,352 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(CreateNewTerrainGui, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiOverlayProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "640 480"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + Position = "182 94"; + Extent = "250 140"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "1"; + AnchorLeft = "1"; + AnchorRight = "1"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "Canvas.popDialog( CreateNewTerrainGui );"; + EdgeSnap = "0"; + text = "Create New Terrain"; + + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "theName"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "68 30"; + Extent = "171 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + text = "myNewTerrain"; + passwordMask = "*"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "32 31"; + Extent = "31 16"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Name:"; + maxLength = "1024"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "10 108"; + Extent = "138 24"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "CreateNewTerrainGui.create();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Create New"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + accelerator = "return"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "159 108"; + Extent = "80 24"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "Canvas.popDialog( CreateNewTerrainGui );"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + accelerator = "escape"; + }; + new GuiRadioCtrl() { + canSaveDynamicFields = "0"; + internalName = "flatRadio"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiRadioProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "155 80"; + Extent = "40 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Flat"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiRadioCtrl() { + canSaveDynamicFields = "0"; + internalName = "noiseRadio"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiRadioProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "195 80"; + Extent = "45 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Noise"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "23 56"; + Extent = "40 16"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Material: "; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "10 81"; + Extent = "52 16"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Resolution:"; + maxLength = "1024"; + }; + new GuiPopUpMenuCtrl() { + canSaveDynamicFields = "0"; + internalName = "theRezList"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "68 80"; + Extent = "57 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + new GuiPopUpMenuCtrl() { + canSaveDynamicFields = "0"; + internalName = "theMaterialList"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "68 55"; + Extent = "171 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + }; +}; +//--- OBJECT WRITE END --- +function CreateNewTerrainGui::onWake( %this ) +{ + %this-->theName.setText( "" ); + + %matList = %this-->theMaterialList; + %matList.clear(); + %count = TerrainMaterialSet.getCount(); + for ( %i=0; %i < %count; %i++ ) + %matList.add( TerrainMaterialSet.getObject( %i ).internalName, %i ); + %matList.setSelected( 0 ); + + %rezList = %this-->theRezList; + %rezList.clear(); + %rezList.add( "256", 256 ); + %rezList.add( "512", 512 ); + %rezList.add( "1024", 1024 ); + %rezList.add( "2048", 2048 ); + //%rezList.add( "4096", 4096 ); + %rezList.setSelected( 256 ); + + %this-->flatRadio.setStateOn( true ); +} + +function CreateNewTerrainGui::create( %this ) +{ + %terrainName = %this-->theName.getText(); + %resolution = %this-->theRezList.getSelected(); + %materialName = %this-->theMaterialList.getText(); + %genNoise = %this-->noiseRadio.getValue(); + + %obj = TerrainBlock::createNew( %terrainName, %resolution, %materialName, %genNoise ); + + if( %genNoise ) + ETerrainEditor.isDirty = true; + + if( isObject( %obj ) ) + { + // Submit an undo action. + MECreateUndoAction::submit(%obj); + + assert( isObject( EWorldEditor ), + "ObjectBuilderGui::processNewObject - EWorldEditor is missing!" ); + + // Select it in the editor. + EWorldEditor.clearSelection(); + EWorldEditor.selectObject(%obj); + + // When we drop the selection don't store undo + // state for it... the creation deals with it. + EWorldEditor.dropSelection( true ); + } + + Canvas.popDialog( %this ); +} diff --git a/Templates/Empty/game/tools/worldEditor/gui/guiInteriorExportGui.gui b/Templates/Empty/game/tools/worldEditor/gui/guiInteriorExportGui.gui new file mode 100644 index 000000000..783a771f0 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/guiInteriorExportGui.gui @@ -0,0 +1,240 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(InteriorExportGui, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Profile = "GuiOverlayProfile"; + Enabled = "1"; + isContainer = "1"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl(InteriorExportWindow) { + profile = "GuiWindowProfile"; + canSaveDynamicFields = "0"; + internalName = "InteriorExport"; + Enabled = "1"; + isContainer = "1"; + HorizSizing = "center"; + VertSizing = "center"; + Position = "248 248"; + Extent = "290 235"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "1"; + AnchorLeft = "1"; + AnchorRight = "1"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "InteriorExportGui.close();"; + EdgeSnap = "0"; + canCollapse = "0"; + text = "Export Interiors to COLLADA"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "9 43"; + Extent = "272 112"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiListBoxCtrl(InteriorSelectListBox) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "2 2"; + Extent = "248 104"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + AllowMultipleSelections = "1"; + fitParentWidth = "1"; + }; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "9 25"; + Extent = "88 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Select Interior(s):"; + maxLength = "1024"; + }; + new GuiCheckBoxCtrl(InteriorSelectAllToggle) { + profile = "GuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "9 158"; + extent = "248 23"; + minExtent = "8 8"; + visible = "1"; + text = " Select / deselect all"; + groupNum = "-1"; + buttonType = "ToggleButton"; + helpTag = "0"; + maxLength = "255"; + }; + new GuiCheckBoxCtrl(InteriorExportTransToggle) { + profile = "GuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "9 176"; + extent = "248 23"; + minExtent = "8 8"; + visible = "1"; + text = " Export Interiors with transforms baked in"; + groupNum = "-1"; + buttonType = "ToggleButton"; + helpTag = "0"; + maxLength = "255"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "9 202"; + Extent = "107 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "InteriorExportGui.export();"; + hovertime = "1000"; + text = "Export"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "174 202"; + Extent = "107 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "InteriorExportGui.close();"; + hovertime = "1000"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + +function InteriorExportGui::findAllInteriors( %this ) +{ + InteriorSelectListBox.clearItems(); + + // Find all of the Interior files + initContainerTypeSearch( $TypeMasks::InteriorObjectType ); + + while ( (%interiorObject = containerSearchNext()) != 0 ) + { + %interiorName = %interiorObject.getName(); + if ( %interiorName $= "" ) + %interiorName = fileBase(%interiorObject.interiorFile); + + %text = %interiorName SPC "(" @ %interiorObject.getId() @ ")"; + InteriorSelectListBox.addItem( %text, %interiorObject ); + } +} + +function InteriorExportGui::export( %this ) +{ + %selected = InteriorSelectListBox.getSelectedItems(); + + %numSel = getWordCount(%selected); + + if ( %numSel == 0 ) + MessageBoxOk("Select Interior(s)", "You must select at least one Interior to export"); + + for (%i = 0; %i < %numSel; %i++) + { + %index = getWord(%selected, %i); + + %interiorObj = InteriorSelectListBox.getItemObject( %index ); + + if (!isObject(%interiorObj)) + continue; + + %interiorObj.exportToCollada(InteriorExportTransToggle.getValue()); + } + + %this.close(); +} + +function InteriorExportGui::onWake( %this ) +{ + %this.findAllInteriors(); + + InteriorSelectAllToggle.setValue(false); + InteriorExportTransToggle.setValue(true); +} + +function InteriorExportGui::close( %this ) +{ + Canvas.popDialog( %this ); +} + +function InteriorSelectAllToggle::onClick( %this ) +{ + if (InteriorSelectAllToggle.getValue()) + { + %numItems = InteriorSelectListBox.getItemCount(); + + for (%i = 0; %i < %numItems; %i++) + InteriorSelectListBox.setSelected(%i); + } + else + InteriorSelectListBox.clearSelection(); +} + diff --git a/Templates/Empty/game/tools/worldEditor/gui/guiTerrainEditorToolbar.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/guiTerrainEditorToolbar.ed.gui new file mode 100644 index 000000000..e69de29bb diff --git a/Templates/Empty/game/tools/worldEditor/gui/guiTerrainExportGui.gui b/Templates/Empty/game/tools/worldEditor/gui/guiTerrainExportGui.gui new file mode 100644 index 000000000..d4996b797 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/guiTerrainExportGui.gui @@ -0,0 +1,310 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(TerrainExportGui, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Profile = "GuiOverlayProfile"; + Enabled = "1"; + isContainer = "1"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl(TerrainExportWindow) { + profile = "GuiWindowProfile"; + canSaveDynamicFields = "0"; + internalName = "TerrainExport"; + Enabled = "1"; + isContainer = "1"; + HorizSizing = "center"; + VertSizing = "center"; + Position = "248 248"; + Extent = "290 235"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "1"; + AnchorLeft = "1"; + AnchorRight = "1"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "TerrainExportGui.close();"; + EdgeSnap = "0"; + canCollapse = "0"; + text = "Export Terrain"; + + new GuiScrollCtrl(TerrainSelectScroll) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "9 43"; + Extent = "272 112"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiListBoxCtrl(TerrainSelectListBox) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "2 2"; + Extent = "248 104"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + AllowMultipleSelections = "1"; + fitParentWidth = "1"; + }; + }; + new GuiTextCtrl(TerrainSelectText) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "9 25"; + Extent = "88 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Select Terrain(s):"; + maxLength = "1024"; + }; + new GuiTextEditCtrl(SelectFolderTextEdit) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "9 176"; + Extent = "195 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiButtonCtrl(SelectFolderButton) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "212 174"; + Extent = "69 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainExportGui.selectFolder();"; + hovertime = "1000"; + text = "Browse"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "174 202"; + Extent = "107 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainExportGui.close();"; + hovertime = "1000"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl(ExportButton) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "9 202"; + Extent = "107 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainExportGui.export();"; + hovertime = "1000"; + text = "Export"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiTextCtrl(FolderText) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "9 159"; + Extent = "96 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Folder:"; + maxLength = "1024"; + }; + }; +}; +//--- OBJECT WRITE END --- + +function TerrainExportGui::findAllTerrains( %this ) +{ + TerrainSelectListBox.clearItems(); + + if ( isObject( MegaTerrain ) ) + TerrainSelectListBox.addItem( "MegaTerrain" ); + + // Find all of the terrain files + initContainerTypeSearch( $TypeMasks::TerrainObjectType ); + + while ( (%terrainObject = containerSearchNext()) != 0 ) + { + %terrainId = %terrainObject.getId(); + %terrainName = %terrainObject.getName(); + if ( %terrainName $= "" ) + %terrainName = "Unnamed (" @ %terrainId @ ")"; + + TerrainSelectListBox.addItem( %terrainName, %terrainId ); + } +} + +function TerrainExportGui::init( %this ) +{ + %this.findAllTerrains(); +} + +function TerrainExportGui::export( %this ) +{ + %itemId = TerrainSelectListBox.getSelectedItem(); + %terrainObj = TerrainSelectListBox.getItemObject( %itemId ); + if ( !isObject( %terrainObj ) ) + { + MessageBoxOK( "Export failed", "Could not find the selected TerrainBlock!" ); + return; + } + + %filePath = SelectFolderTextEdit.getText(); + + %terrainName = %terrainObj.getName(); + if ( %terrainName $= "" ) + %terrainName = "Unnamed"; + + %fileName = %terrainName @ "_heightmap.png"; + %filePrefix = %terrainName @ "_layerMap"; + + %ret = %terrainObj.exportHeightMap( %filePath @ "/" @ %fileName, "png" ); + if ( %ret ) + %ret = %terrainObj.exportLayerMaps( %filePath @ "/" @ %filePrefix, "png" ); + + if ( %ret ) + %this.close(); +} + +function TerrainExportGui::onWake( %this ) +{ + TerrainExportGui.init(); +} + +function TerrainExportGui::close( %this ) +{ + Canvas.popDialog( %this ); +} + +function TerrainExportGui::showExportDialog( %this ) +{ + %this.findAllTerrains(); + + Canvas.pushDialog( %this ); +} + +function TerrainExportGui::openFolderCallback( %this, %path ) +{ + SelectFolderTextEdit.setText( %path ); +} + +function TerrainExportGui::selectFolder( %this ) +{ + %this.doOpenDialog( "", %this @ ".openFolderCallback" ); +} + +function TerrainExportGui::doOpenDialog( %this, %filter, %callback ) +{ + %dlg = new OpenFolderDialog() + { + Title = "Select Export Folder"; + Filters = %filter; + DefaultFile = %currentFile; + ChangePath = false; + MustExist = true; + MultipleFiles = false; + }; + + if(filePath( %currentFile ) !$= "") + %dlg.DefaultPath = filePath(%currentFile); + else + %dlg.DefaultPath = getMainDotCSDir(); + + if(%dlg.Execute()) + eval(%callback @ "(\"" @ %dlg.FileName @ "\");"); + + %dlg.delete(); +} diff --git a/Templates/Empty/game/tools/worldEditor/gui/guiTerrainImportGui.gui b/Templates/Empty/game/tools/worldEditor/gui/guiTerrainImportGui.gui new file mode 100644 index 000000000..e56cbab89 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/guiTerrainImportGui.gui @@ -0,0 +1,736 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(TerrainImportGui, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiOverlayProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCtrl() { + canSaveDynamicFields = "0"; + internalName = "TerrainImport"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + Position = "119 84"; + Extent = "391 257"; + MinExtent = "391 257"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "1"; + AnchorLeft = "1"; + AnchorRight = "1"; + resizeWidth = "1"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "4 4"; + closeCommand = "Canvas.popDialog( TerrainImportGui );"; + EdgeSnap = "0"; + text = "Import Terrain Height Map"; + + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "HeightfieldFilename"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "10 85"; + Extent = "298 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = " "; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "top"; + Position = "11 66"; + Extent = "120 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Height Map Image:"; + maxLength = "1024"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "316 83"; + Extent = "65 22"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "TerrainImportGui.browseForHeightfield();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Browse..."; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "MetersPerPixel"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "226 44"; + Extent = "82 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "1"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "226 26"; + Extent = "88 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Meters Per Pixel"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "316 26"; + Extent = "64 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Height Scale:"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "HeightScale"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "316 44"; + Extent = "64 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "256"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "10 112"; + Extent = "365 2"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = "core/art/gui/images/separator-v"; + wrap = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "top"; + Position = "14 123"; + Extent = "74 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "1"; + text = "Texture Map"; + maxLength = "1024"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "341 142"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "TerrainImportGui.browseForOpacityMap();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "+"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "341 165"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "TerrainImportGui.removeOpacitymap();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "-"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "195 225"; + Extent = "88 24"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "TerrainImportGui.import();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Import"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + internalName = "OpacityLayerScroll"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "10 142"; + Extent = "326 75"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiTextListCtrl() { + canSaveDynamicFields = "0"; + internalName = "OpacityLayerTextList"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTextListProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "1 1"; + Extent = "293 2"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + AltCommand = "TerrainImportGui.onOpacityListDblClick();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + enumerate = "0"; + resizeCell = "1"; + columns = "0 250 300"; + fitParentWidth = "1"; + clipColumnText = "1"; + }; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "264 123"; + Extent = "48 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Channels"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "11 26"; + Extent = "64 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Name:"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "TerrainName"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "10 44"; + Extent = "206 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "theTerrain"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "341 199"; + Extent = "40 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "TerrainImportGui.onOpacityListDblClick();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Edit"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "293 225"; + Extent = "88 24"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "Canvas.popDialog( TerrainImportGui );"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + + +function TerrainImportGui::onWake( %this ) +{ + if ( !isObject( %this.namesArray ) ) + %this.namesArray = new ArrayObject(); + + if ( !isObject( %this.channelsArray ) ) + %this.channelsArray = new ArrayObject(); +} + +function TerrainImportGui::import( %this ) +{ + // Gather all the import settings. + + %heightMapPng = %this-->HeightfieldFilename.getText(); + + %metersPerPixel = %this-->MetersPerPixel.getText(); + %heightScale = %this-->HeightScale.getText(); + + // Grab and validate terrain object name. + + %terrainName = %this-->TerrainName.getText(); + if( !( isObject( %terrainName ) && %terrainName.isMemberOfClass( "TerrainBlock" ) ) && + !Editor::validateObjectName( %terrainName ) ) + return; + + %opacityNames = ""; + %materialNames = ""; + + %opacityList = %this-->OpacityLayerTextList; + + for( %i = 0; %i < %opacityList.rowCount(); %i++ ) + { + %itemText = %opacityList.getRowTextById( %i ); + %opacityName = %this.namesArray.getValue( %i ); + + %channelInfo = %this.channelsArray.getValue( %i ); + %channel = getWord( %channelInfo, 0 ); + + %materialName = getField( %itemText, 2 ); + + %opacityNames = %opacityNames @ %opacityName TAB %channel @ "\n"; + %materialNames = %materialNames @ %materialName @ "\n"; + } + + %updated = nameToID( %terrainName ); + + // This will update an existing terrain with the name %terrainName, + // or create a new one if %terrainName isn't a TerrainBlock + %obj = TerrainBlock::import( %terrainName, + %heightMapPng, + %metersPerPixel, + %heightScale, + %opacityNames, + %materialNames ); + + Canvas.popDialog( %this ); + + if ( isObject( %obj ) ) + { + if( %obj != %updated ) + { + // created a new TerrainBlock + // Submit an undo action. + MECreateUndoAction::submit(%obj); + } + + assert( isObject( EWorldEditor ), + "ObjectBuilderGui::processNewObject - EWorldEditor is missing!" ); + + // Select it in the editor. + EWorldEditor.clearSelection(); + EWorldEditor.selectObject(%obj); + + // When we drop the selection don't store undo + // state for it... the creation deals with it. + EWorldEditor.dropSelection( true ); + + ETerrainEditor.isDirty = true; + EPainter.updateLayers(); + } + else + { + MessageBox( "Import Terrain", + "Terrain import failed! Check console for error messages.", + "Ok", "Error" ); + } +} + +function TerrainImportGui::doOpenDialog( %this, %filter, %callback ) +{ + %dlg = new OpenFileDialog() + { + Filters = %filter; + DefaultFile = %currentFile; + ChangePath = false; + MustExist = true; + MultipleFiles = false; + }; + + if(filePath( %currentFile ) !$= "") + %dlg.DefaultPath = filePath(%currentFile); + else + %dlg.DefaultPath = getMainDotCSDir(); + + if(%dlg.Execute()) + eval(%callback @ "(\"" @ %dlg.FileName @ "\");"); + + + %dlg.delete(); +} + +function TerrainImportGui_SetHeightfield( %name ) +{ + TerrainImportGui-->HeightfieldFilename.setText( %name ); +} + +$TerrainImportGui::HeightFieldFilter = "Heightfield Files (*.png, *.bmp, *.jpg, *.gif)|*.png;*.bmp;*.jpg;*.gif|All Files (*.*)|*.*|"; +$TerrainImportGui::OpacityMapFilter = "Opacity Map Files (*.png, *.bmp, *.jpg, *.gif)|*.png;*.bmp;*.jpg;*.gif|All Files (*.*)|*.*|"; + +function TerrainImportGui::browseForHeightfield( %this ) +{ + %this.doOpenDialog( $TerrainImportGui::HeightFieldFilter, "TerrainImportGui_SetHeightfield" ); +} + +function TerrainImportGuiAddOpacityMap( %name ) +{ + // TODO: Need to actually look at + // the file here and figure + // out how many channels it has. + + %txt = makeRelativePath( %name, getWorkingDirectory() ); + + // Will need to do this stuff + // once per channel in the file + // currently it works with just grayscale. + %channelsTxt = "R" TAB "G" TAB "B" TAB "A"; + %bitmapInfo = getBitmapinfo( %name ); + + %channelCount = getWord( %bitmapInfo, 2 ); + + %opacityList = TerrainImportGui-->OpacityLayerTextList; + + for ( %i = 0; %i < %channelCount; %i++ ) + { + TerrainImportGui.namesArray.push_back( %txt, %name ); + TerrainImportGui.channelsArray.push_back( %txt, getWord( %channelsTxt, %i ) TAB %channelCount ); + + //TerrainImportGui.namesArray.echo(); + + %count = %opacityList.rowCount(); + %opacityList.addRow( %count, %txt TAB getWord( %channelsTxt, %i ) ); + } + + //OpacityMapListBox.addItem( %name ); +} + +function TerrainImportGui::browseForOpacityMap( %this ) +{ + TerrainImportGui.doOpenDialog( $TerrainImportGui::OpacityMapFilter, "TerrainImportGuiAddOpacityMap" ); +} + +function TerrainImportGui::removeOpacitymap( %this ) +{ + %opacityList = %this-->OpacityLayerTextList; + + //%itemIdx = OpacityMapListBox.getSelectedItem(); + %itemIdx = %opacityList.getSelectedId(); + if ( %itemIdx < 0 ) // -1 is no item selected + return; + + %this.namesArray.erase( %itemIdx ); + %this.channelsArray.erase( %itemIdx ); + + //%this.namesArray.echo(); + + %opacityList.removeRowById( %itemIdx ); + + //OpacityMapListBox.deleteItem( %itemIdx ); +} + +function TerrainImportGui::onOpacityListDblClick( %this ) +{ + %opacityList = %this-->OpacityLayerTextList; + + //echo( "Double clicked the opacity list control!" ); + %itemIdx = %opacityList.getSelectedId(); + if ( %itemIdx < 0 ) + return; + + %this.activeIdx = %itemIdx; + + %rowTxt = %opacityList.getRowTextById( %itemIdx ); + %matTxt = getField( %rowTxt, 2 ); + %matId = getField( %rowTxt, 3 ); + + TerrainMaterialDlg.showByObjectId( %matId, TerrainImportGui_TerrainMaterialApplyCallback ); +} + +function TerrainImportGui_TerrainMaterialApplyCallback( %mat, %matIndex ) +{ + // Skip over a bad selection. + if ( !isObject( %mat ) ) + return; + + %opacityList = TerrainImportGui-->OpacityLayerTextList; + + %itemIdx = TerrainImportGui.activeIdx; + + if ( %itemIdx < 0 || %itemIdx $= "" ) + return; + + %rowTxt = %opacityList.getRowTextById( %itemIdx ); + + %columntTxtCount = getFieldCount( %rowTxt ); + if ( %columntTxtCount > 2 ) + %rowTxt = getFields( %rowTxt, 0, 1 ); + + %opacityList.setRowById( %itemIdx, %rowTxt TAB %mat.internalName TAB %mat ); +} diff --git a/Templates/Empty/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui new file mode 100644 index 000000000..f3c3942c9 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui @@ -0,0 +1,1065 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(TerrainMaterialDlg, EditorGuiGroup) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "221 151"; + Extent = "394 322"; + MinExtent = "358 298"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "None"; + Margin = "4 4 4 4"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "TerrainMaterialDlg.dialogCancel();"; + EdgeSnap = "0"; + text = "Terrain Materials Editor"; + new GuiContainer(){ //Node Properties + isContainer = "1"; + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "6 25"; + Extent = "189 64"; + + new GuiTextCtrl(){ + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 0"; + Extent = "91 18"; + text = "Terrain Materials"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + position = "160 2"; + Extent = "15 15"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg.newMat();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "core/art/gui/images/new"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + position = "173 2"; + Extent = "15 15"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg.deleteMat();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + }; + new GuiContainer() { + canSaveDynamicFields = "0"; + internalName = "matSettingsParent"; + isContainer = "1"; + Profile = "inspectorStyleRolloutProfile"; + HorizSizing = "left"; + VertSizing = "height"; + position = "202 26"; + Extent = "185 263"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 0"; + Extent = "183 2"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = "core/art/gui/images/separator-v"; + wrap = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 22"; + Extent = "44 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiDefaultProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Name"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + internalName = "matNameCtrl"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "39 21"; + Extent = "143 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + altCommand = "TerrainMaterialDlg.setMaterialName( $ThisControl.getText() );"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "InspectorTitleTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 0"; + Extent = "117 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Material Properties"; + maxLength = "1024"; + }; + new GuiContainer() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "6 43"; + Extent = "185 75"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + + new GuiCheckBoxCtrl() { + internalName = "sideProjectionCtrl"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "55 54"; + Extent = "119 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = " Use Side Projection"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiBitmapCtrl() { + internalName = "baseTexCtrl"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "47 47"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = "tools/materialeditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg.changeBase();"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Change the Active Diffuse Map for this layer"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -3"; + Extent = "39 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Diffuse"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "56 16"; + Extent = "116 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "116 0"; + Extent = "40 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg.changeBase();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Edit"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "159 0"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg-->baseTexCtrl.setBitmap(\"tools/materialeditor/gui/unknownImage\");"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "132 35"; + Extent = "39 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + text = "Size"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + internalName = "baseSizeCtrl"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "94 34"; + Extent = "34 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + }; + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "6 116"; + Extent = "175 2"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = "core/art/gui/images/separator-v"; + wrap = "0"; + }; + new GuiContainer() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "6 206"; + Extent = "185 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + + new GuiBitmapCtrl() { + internalName = "normTexCtrl"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "47 47"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = "tools/materialeditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -3"; + Extent = "39 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Normal"; + maxLength = "1024"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg.changeNormal();"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Change the active Normal Map for this layer."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "56 15"; + Extent = "116 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "116 0"; + Extent = "40 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg.changeNormal();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Edit"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "159 0"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg-->normTexCtrl.setBitmap(\"tools/materialeditor/gui/unknownImage\");"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "92 34"; + Extent = "77 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Parallax Scale"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + internalName = "parallaxScaleCtrl"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "55 33"; + Extent = "34 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + text = "0.00"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + }; + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "6 200"; + Extent = "175 2"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = "core/art/gui/images/separator-v"; + wrap = "0"; + }; + new GuiContainer() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "6 122"; + Extent = "185 72"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + + new GuiBitmapCtrl() { + internalName = "detailTexCtrl"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "47 47"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + bitmap = "tools/materialeditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg.changeDetail();"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Change the active Detail Map for this layer."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -3"; + Extent = "30 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Detail"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "56 16"; + Extent = "116 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "116 0"; + Extent = "40 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg.changeDetail();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Edit"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "159 0"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg-->detailTexCtrl.setBitmap(\"tools/materialeditor/gui/unknownImage\");"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "132 33"; + Extent = "39 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + text = "Size"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + internalName = "detSizeCtrl"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "94 32"; + Extent = "34 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "39 54"; + Extent = "46 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + text = "Strength"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + internalName = "detStrengthCtrl"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 53"; + Extent = "34 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "132 54"; + Extent = "45 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + text = "Distance"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + internalName = "detDistanceCtrl"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "94 53"; + Extent = "34 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + }; + }; + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "6 42"; + Extent = "189 273"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "189 274"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "false"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiTreeViewCtrl() { + internalName = "matLibTree"; + canSaveDynamicFields = "0"; + class = "TerrainMaterialTreeCtrl"; + className = "TerrainMaterialTreeCtrl"; + isContainer = "1"; + Profile = "GuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "125 84"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "0"; + DragToItemAllowed = "0"; + ClearAllOnSingleSelection = "1"; + showRoot = "0"; + internalNamesOnly = "1"; + objectNamesOnly = "0"; + }; + }; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + position = "202 294"; + Extent = "98 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg.dialogApply();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Apply&Select"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + position = "307 294"; + Extent = "80 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg.dialogCancel();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapCtrl() { // inactive overlay + internalName = "inactiveOverlay"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "height"; + position = "199 23"; + Extent = "190 267"; + isContainer = true; + Visible = false; + bitmap = "core/art/gui/images/inactive-overlay"; + + new GuiTextCtrl(){ + internalName = "inactiveOverlayDlg"; + Profile = "GuiTextCenterProfile"; + HorizSizing = "width"; + VertSizing = "center"; + position = "0 104"; + Extent = "190 64"; + text = "Inactive"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/worldEditor/gui/guiWorldEditorCreatorWindow.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/guiWorldEditorCreatorWindow.ed.gui new file mode 100644 index 000000000..013ad4d2f --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/guiWorldEditorCreatorWindow.ed.gui @@ -0,0 +1,286 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(WorldEditorCreatorWindowContainer) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCtrl(EWCreatorWindow) { + canSaveDynamicFields = "0"; + internalName = "CreatorWindow"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "38 36"; + Extent = "354 276"; + MinExtent = "354 207"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "30 30"; + EdgeSnap = "0"; + text = "Creator"; + + new GuiContainer() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "2 80"; + Extent = "348 195"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "4 4 4 4"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "EditorLightScrollProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 4"; + Extent = "340 187"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "alwaysOff"; + lockHorizScroll = "false"; + lockVertScroll = "true"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiDynamicCtrlArrayControl(CreatorIconArray) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "2 2"; + Extent = "335 183"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + colCount = "9"; + colSize = "64"; + rowCount = "0"; + RowSize = "64"; + rowSpacing = "4"; + colSpacing = "4"; + frozen = "0"; + autoCellSize = "1"; + fillRowFirst = "0"; + dynamicSize = "1"; + }; + }; + }; + new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 24"; + Extent = "348 55"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl(CreatorNavUpButton) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "319 33"; + Extent = "20 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "EWCreatorWindow.navigateUp();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + + Bitmap = "tools/gui/images/folderUp.png"; + autoSize = "0"; + }; + new GuiPopUpMenuCtrl(CreatorPopupMenu) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 33"; + Extent = "308 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Interiors"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + new GuiTabBookCtrl(CreatorTabBook) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 4"; + Extent = "342 21"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "None"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + TabPosition = "Top"; + TabMargin = "7"; + MinTabWidth = "64"; + + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTabPageProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "0 0"; + MinExtent = "0 0"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Shapes"; + maxLength = "1024"; + }; + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTabPageProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "0 0"; + MinExtent = "0 0"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Geometry"; + maxLength = "1024"; + }; + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTabPageProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "0 0"; + MinExtent = "0 0"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "MissionObjects"; + maxLength = "1024"; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/worldEditor/gui/guiWorldEditorMissionInspector.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/guiWorldEditorMissionInspector.ed.gui new file mode 100644 index 000000000..9b07554b5 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/guiWorldEditorMissionInspector.ed.gui @@ -0,0 +1,299 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(WorldEditorMissionInspector,EditorGuiGroup) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl(EWInspectorWindow) { + canSaveDynamicFields = "0"; + internalName = "InspectorWindow"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "333 26"; + Extent = "304 448"; + MinExtent = "304 448"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + text = "Mission Inspector"; + maxLength = "1024"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "EWInspectorFrame.parentGroup.setVisible(false);"; + + new GuiFrameSetCtrl(EWInspectorFrame) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiFrameSetProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "8 32"; + Extent = "288 408"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + columns = "0"; + rows = "0 206"; + borderWidth = "0"; + borderColor = "84 12 136 1"; + borderEnable = "dynamic"; + borderMovable = "dynamic"; + autoBalance = "0"; + fudgeFactor = "0"; + + new GuiControl(EWTreePane) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "EditorDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "288 202"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "288 202"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiTreeViewCtrl(EditorTree) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "2 2"; + Extent = "226 21"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "1"; + MultipleSelections = "1"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "1"; + }; + }; + }; + new GuiControl(EWCreatorInspectorPane) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "EditorDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 206"; + Extent = "288 202"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiScrollCtrl(EWCreatorPane) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "288 202"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = true; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiTreeViewCtrl(Creator) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "2 2"; + Extent = "131 84"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "1"; + MultipleSelections = "1"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "1"; + }; + }; + new GuiControl(EWInspectorPane) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "EditorDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "288 202"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiSolidDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "288 24"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "2 2"; + Extent = "40 20"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "EWorldEditor.isDirty = true;EWorldEditor.makeFirstResponder(true);"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Don\'t forget to hit Apply after making changes!"; + hovertime = "1000"; + text = "Apply"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiInspectorFieldProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "52 4"; + Extent = "42 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Name:"; + maxLength = "1024"; + }; + new GuiTextEditCtrl(InspectorNameEdit) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiInspectorBackgroundProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "97 4"; + Extent = "758 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "EWorldEditor.isDirty = true;"; + hovertime = "1000"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + }; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 24"; + Extent = "288 178"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = true; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiInspector(Inspector) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiInspectorBackgroundProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "2 2"; + Extent = "266 8"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + }; + }; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/Empty/game/tools/worldEditor/gui/objectBuilderGui.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/objectBuilderGui.ed.gui new file mode 100644 index 000000000..aefc6dbef --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/objectBuilderGui.ed.gui @@ -0,0 +1,1126 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ObjectBuilderGui, EditorGuiGroup) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "800 600"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + + new GuiWindowCtrl(OBTargetWindow) { + profile = "GuiWindowProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "384 205"; + extent = "256 282"; + minExtent = "256 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + text = "Create Object"; + + new GuiTextCtrl() { + profile = "GuiCenterTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "9 26"; + extent = "84 16"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + text = "Object Name:"; + }; + new GuiTextEditCtrl(OBObjectName) { + class = ObjectBuilderGuiTextEditCtrl; + profile = "GuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "78 26"; + extent = "172 18"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + historySize = "0"; + }; + new GuiBitmapBorderCtrl(OBContentWindow) { + profile = "GuiGroupBorderProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "7 51"; + extent = "243 193"; + minExtent = "0 0"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + }; + new GuiButtonCtrl(OBOKButton) { + profile = "GuiButtonProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "7 250"; + extent = "156 24"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + command = "ObjectBuilderGui.onOK();"; + helpTag = "0"; + text = "Create New"; + Accelerator = "return"; + }; + new GuiButtonCtrl(OBCancelButton) { + profile = "GuiButtonProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "170 250"; + extent = "80 24"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + command = "ObjectBuilderGui.onCancel();"; + helpTag = "0"; + text = "Cancel"; + Accelerator = "escape"; + }; + }; +}; +//--- OBJECT WRITE END --- + +function ObjectBuilderGui::init(%this) +{ + %this.baseOffsetX = 5; + %this.baseOffsetY = 5; + %this.defaultObjectName = ""; + %this.defaultFieldStep = 22; + %this.columnOffset = 110; + + %this.fieldNameExtent = "105 18"; + %this.textEditExtent = "122 18"; + %this.checkBoxExtent = "13 18"; + %this.popupMenuExtent = "122 18"; + %this.fileButtonExtent = "122 18"; + %this.matButtonExtent = "17 18"; + + // + %this.numControls = 0; + + %this.lastPath = ""; + + %this.reset(); +} + +function ObjectBuilderGui::reset(%this) +{ + %this.objectGroup = ""; + %this.curXPos = %this.baseOffsetX; + %this.curYPos = %this.baseOffsetY; + %this.createFunction = ""; + %this.createCallback = ""; + %this.currentControl = 0; + + // + OBObjectName.setValue(%this.defaultObjectName); + + // + %this.newObject = 0; + %this.objectClassName = ""; + %this.numFields = 0; + + // + for(%i = 0; %i < %this.numControls; %i++) + { + %this.textControls[%i].delete(); + %this.controls[%i].delete(); + } + %this.numControls = 0; +} + +//------------------------------------------------------------------------------ + +function ObjectBuilderGui::createFileType(%this, %index) +{ + if(%index >= %this.numFields || %this.field[%index, name] $= "") + { + error("ObjectBuilderGui::createFileType: invalid field"); + return; + } + + // + if(%this.field[%index, text] $= "") + %name = %this.field[%index, name]; + else + %name = %this.field[%index, text]; + + // + %this.textControls[%this.numControls] = new GuiTextCtrl() { + profile = "GuiTextRightProfile"; + text = %name; + extent = %this.fieldNameExtent; + position = %this.curXPos @ " " @ %this.curYPos; + modal = "1"; + }; + + // + %this.controls[%this.numControls] = new GuiButtonCtrl() { + HorizSizing = "width"; + profile = "GuiButtonProfile"; + extent = %this.fileButtonExtent; + position = %this.curXPos + %this.columnOffset @ " " @ %this.curYPos; + modal = "1"; + command = %this @ ".getFileName(" @ %index @ ");"; + }; + + %val = %this.field[%index, value]; + %this.controls[%this.numControls].setValue(fileBase(%val) @ fileExt(%val)); + + %this.numControls++; + %this.curYPos += %this.defaultFieldStep; +} + +function ObjectBuilderGui::getFileName(%this, %index) +{ + if(%index >= %this.numFields || %this.field[%index, name] $= "") + { + error("ObjectBuilderGui::getFileName: invalid field"); + return; + } + + %val = %this.field[%index, ext]; + + //%path = filePath(%val); + //%ext = fileExt(%val); + + %this.currentControl = %index; + getLoadFilename( %val @ "|" @ %val, %this @ ".gotFileName", %this.lastPath ); +} + +function ObjectBuilderGui::gotFileName(%this, %name) +{ + %index = %this.currentControl; + + %name = makeRelativePath(%name,getWorkingDirectory()); + + %this.field[%index, value] = %name; + %this.controls[%this.currentControl].setText(fileBase(%name) @ fileExt(%name)); + + %this.lastPath = %name; + + // This doesn't work for button controls as getValue returns their state! + //%this.controls[%this.currentControl].setValue(%name); +} + +//------------------------------------------------------------------------------ + +function ObjectBuilderGui::createMaterialNameType(%this, %index) +{ + if(%index >= %this.numFields || %this.field[%index, name] $= "") + { + error("ObjectBuilderGui::createMaterialNameType: invalid field"); + return; + } + + // + if(%this.field[%index, text] $= "") + %name = %this.field[%index, name]; + else + %name = %this.field[%index, text]; + + // + %this.textControls[%this.numControls] = new GuiTextCtrl() { + profile = "GuiTextRightProfile"; + text = %name; + extent = %this.fieldNameExtent; + position = %this.curXPos @ " " @ %this.curYPos; + modal = "1"; + }; + + // + %this.controls[%this.numControls] = new GuiControl() { + HorizSizing = "width"; + profile = "GuiDefaultProfile"; + extent = %this.textEditExtent; + position = %this.curXPos + %this.columnOffset @ " " @ %this.curYPos; + modal = "1"; + }; + + %text = new GuiTextEditCtrl() { + class = ObjectBuilderGuiTextEditCtrl; + internalName = "MatText"; + HorizSizing = "width"; + profile = "GuiTextEditProfile"; + extent = getWord(%this.textEditExtent,0) - getWord(%this.matButtonExtent,0) - 2 @ " " @ getWord(%this.textEditExtent,1); + text = %this.field[%index, value]; + position = "0 0"; + modal = "1"; + }; + %this.controls[%this.numControls].addGuiControl(%text); + + %button = new GuiBitmapButtonCtrl() { + internalName = "MatButton"; + HorizSizing = "left"; + profile = "GuiButtonProfile"; + extent = %this.matButtonExtent; + position = getWord(%this.textEditExtent,0) - getWord(%this.matButtonExtent,0) @ " 0"; + modal = "1"; + command = %this @ ".getMaterialName(" @ %index @ ");"; + }; + %button.setBitmap("tools/materialEditor/gui/change-material-btn"); + %this.controls[%this.numControls].addGuiControl(%button); + + //%val = %this.field[%index, value]; + //%this.controls[%this.numControls].setValue(%val); + //%this.controls[%this.numControls].setBitmap("tools/materialEditor/gui/change-material-btn"); + + %this.numControls++; + %this.curYPos += %this.defaultFieldStep; +} + +function ObjectBuilderGui::getMaterialName(%this, %index) +{ + if(%index >= %this.numFields || %this.field[%index, name] $= "") + { + error("ObjectBuilderGui::getMaterialName: invalid field"); + return; + } + + %this.currentControl = %index; + materialSelector.showDialog(%this @ ".gotMaterialName", "name"); +} + +function ObjectBuilderGui::gotMaterialName(%this, %name) +{ + %index = %this.currentControl; + + %this.field[%index, value] = %name; + %this.controls[%index]-->MatText.setText(%name); +} + +//------------------------------------------------------------------------------ + +function ObjectBuilderGui::createDataBlockType(%this, %index) +{ + if(%index >= %this.numFields || %this.field[%index, name] $= "") + { + error("ObjectBuilderGui::createDataBlockType: invalid field"); + return; + } + + // + if(%this.field[%index, text] $= "") + %name = %this.field[%index, name]; + else + %name = %this.field[%index, text]; + + // + %this.textControls[%this.numControls] = new GuiTextCtrl() { + profile = "GuiTextRightProfile"; + text = %name; + extent = %this.fieldNameExtent; + position = %this.curXPos @ " " @ %this.curYPos; + modal = "1"; + }; + + // + %this.controls[%this.numControls] = new GuiPopupMenuCtrl() { + HorizSizing = "width"; + profile = "GuiPopUpMenuProfile"; + extent = %this.popupMenuExtent; + position = %this.curXPos + %this.columnOffset @ " " @ %this.curYPos; + modal = "1"; + maxPopupHeight = "200"; + }; + + %classname = getWord(%this.field[%index, value], 0); + %classname_alt = getWord(%this.field[%index, value], 1); + + %this.controls[%this.numControls].add("", -1); + + // add the datablocks + for(%i = 0; %i < DataBlockGroup.getCount(); %i++) + { + %obj = DataBlockGroup.getObject(%i); + if( isMemberOfClass( %obj.getClassName(), %classname ) || isMemberOfClass ( %obj.getClassName(), %classname_alt ) ) + %this.controls[%this.numControls].add(%obj.getName(), %i); + } + + %this.controls[%this.numControls].setValue(getWord(%this.field[%index, value], 1)); + + %this.numControls++; + %this.curYPos += %this.defaultFieldStep; +} + +function ObjectBuilderGui::createBoolType(%this, %index) +{ + if(%index >= %this.numFields || %this.field[%index, name] $= "") + { + error("ObjectBuilderGui::createBoolType: invalid field"); + return; + } + + // + if(%this.field[%index, value] $= "") + %value = 0; + else + %value = %this.field[%index, value]; + + // + if(%this.field[%index, text] $= "") + %name = %this.field[%index, name]; + else + %name = %this.field[%index, text]; + + // + %this.textControls[%this.numControls] = new GuiTextCtrl() { + profile = "GuiTextRightProfile"; + text = %name; + extent = %this.fieldNameExtent; + position = %this.curXPos @ " " @ %this.curYPos; + modal = "1"; + }; + + // + %this.controls[%this.numControls] = new GuiCheckBoxCtrl() { + profile = "GuiCheckBoxProfile"; + extent = %this.checkBoxExtent; + position = %this.curXPos + %this.columnOffset @ " " @ %this.curYPos; + modal = "1"; + }; + + %this.controls[%this.numControls].setValue(%value); + + %this.numControls++; + %this.curYPos += %this.defaultFieldStep; +} + +function ObjectBuilderGuiTextEditCtrl::onGainFirstResponder(%this) +{ + %this.selectAllText(); +} + +function ObjectBuilderGui::createStringType(%this, %index) +{ + if(%index >= %this.numFields || %this.field[%index, name] $= "") + { + error("ObjectBuilderGui::createStringType: invalid field"); + return; + } + + // + if(%this.field[%index, text] $= "") + %name = %this.field[%index, name]; + else + %name = %this.field[%index, text]; + + // + %this.textControls[%this.numControls] = new GuiTextCtrl() { + profile = "GuiTextRightProfile"; + text = %name; + extent = %this.fieldNameExtent; + position = %this.curXPos @ " " @ %this.curYPos; + modal = "1"; + }; + + // + %this.controls[%this.numControls] = new GuiTextEditCtrl() { + class = ObjectBuilderGuiTextEditCtrl; + HorizSizing = "width"; + profile = "GuiTextEditProfile"; + extent = %this.textEditExtent; + text = %this.field[%index, value]; + position = %this.curXPos + %this.columnOffset @ " " @ %this.curYPos; + modal = "1"; + }; + + %this.numControls++; + %this.curYPos += %this.defaultFieldStep; +} + +//------------------------------------------------------------------------------ + +function ObjectBuilderGui::adjustSizes(%this) +{ + if(%this.numControls == 0) + %this.curYPos = 0; + + OBTargetWindow.extent = getWord(OBTargetWindow.extent, 0) SPC %this.curYPos + 88; + OBContentWindow.extent = getWord(OBContentWindow.extent, 0) SPC %this.curYPos; + OBOKButton.position = getWord(OBOKButton.position, 0) SPC %this.curYPos + 57; + OBCancelButton.position = getWord(OBCancelButton.position, 0) SPC %this.curYPos + 57; +} + +function ObjectBuilderGui::process(%this) +{ + if(%this.objectClassName $= "") + { + error("ObjectBuilderGui::process: classname is not specified"); + return; + } + + OBTargetWindow.text = "Create Object: " @ %this.objectClassName; + + // + for(%i = 0; %i < %this.numFields; %i++) + { + switch$(%this.field[%i, type]) + { + case "TypeBool": + %this.createBoolType(%i); + + case "TypeDataBlock": + %this.createDataBlockType(%i); + + case "TypeFile": + %this.createFileType(%i); + + case "TypeMaterialName": + %this.createMaterialNameType(%i); + + default: + %this.createStringType(%i); + } + } + + // add the controls + for(%i = 0; %i < %this.numControls; %i++) + { + OBContentWindow.add(%this.textControls[%i]); + OBContentWindow.add(%this.controls[%i]); + } + + // + %this.adjustSizes(); + + // + Canvas.pushDialog(%this); +} + +function ObjectBuilderGui::processNewObject(%this, %obj) +{ + if ( %this.createCallback !$= "" ) + eval( %this.createCallback ); + + // Skip out if nothing was created. + if ( !isObject( %obj ) ) + return; + + // Add the object to the group. + if( %this.objectGroup !$= "" ) + %this.objectGroup.add( %obj ); + else + EWCreatorWindow.objectGroup.add( %obj ); + + // If we were given a callback to call after the + // object has been created, do so now. Also clear + // the callback to make sure it's valid only for + // a single invocation. + + %callback = %this.newObjectCallback; + %this.newObjectCallback = ""; + + if( %callback !$= "" ) + eval( %callback @ "( " @ %obj @ " );" ); +} + +function ObjectBuilderGui::onOK(%this) +{ + // Error out if the given object name is not valid or not unique. + %objectName = OBObjectName.getValue(); + if( !Editor::validateObjectName( %objectName, false )) + return; + + // get current values + for(%i = 0; %i < %this.numControls; %i++) + { + // uses button type where getValue returns button state! + if (%this.field[%i, type] $= "TypeFile") + { + if (strchr(%this.field[%i, value],"*") !$= "") + %this.field[%i, value] = ""; + + continue; + } + if (%this.field[%i, type] $= "TypeMaterialName") + { + %this.field[%i, value] = %this.controls[%i]-->MatText.getValue(); + continue; + } + %this.field[%i, value] = %this.controls[%i].getValue(); + } + + // If we have a special creation function then + // let it do the construction. + if ( %this.createFunction !$= "" ) + eval( %this.createFunction ); + + else + { + // Else we use the memento. + %memento = %this.buildMemento(); + eval( %memento ); + } + + if(%this.newObject != 0) + %this.processNewObject(%this.newObject); + + %this.reset(); + Canvas.popDialog(%this); +} + +function ObjectBuilderGui::onCancel(%this) +{ + %this.reset(); + Canvas.popDialog(%this); +} + +function ObjectBuilderGui::addField(%this, %name, %type, %text, %value, %ext) +{ + %this.field[%this.numFields, name] = %name; + %this.field[%this.numFields, type] = %type; + %this.field[%this.numFields, text] = %text; + %this.field[%this.numFields, value] = %value; + %this.field[%this.numFields, ext] = %ext; + + %this.numFields++; +} + +function ObjectBuilderGui::buildMemento(%this) +{ + // Build the object into a string. + %this.memento = %this @ ".newObject = new " @ %this.objectClassName @ "(" @ OBObjectName.getValue() @ ") { "; + for( %i = 0; %i < %this.numFields; %i++ ) + %this.memento = %this.memento @ %this.field[%i, name] @ " = \"" @ %this.field[%i, value] @ "\"; "; + %this.memento = %this.memento @ "};"; + + return %this.memento; +} + +//------------------------------------------------------------------------------ +// This function is used for objects that don't require any special +// fields/functionality when being built +//------------------------------------------------------------------------------ +function ObjectBuilderGui::buildObject(%this, %className) +{ + %this.objectClassName = %className; + %this.process(); +} + +//------------------------------------------------------------------------------ +// Environment +//------------------------------------------------------------------------------ + +function ObjectBuilderGui::buildScatterSky( %this, %dontWarnAboutSun ) +{ + if( !%dontWarnAboutSun ) + { + // Check for sun object already in the level. If there is one, + // warn the user. + + initContainerTypeSearch( $TypeMasks::EnvironmentObjectType ); + while( 1 ) + { + %object = containerSearchNext(); + if( !%object ) + break; + + if( %object.isMemberOfClass( "Sun" ) ) + { + MessageBoxYesNo( "Warning", + "A ScatterSky object will conflict with the Sun object that is already in the level." SPC + "Do you still want to create a ScatterSky object?", + %this @ ".buildScatterSky( true );" ); + return; + } + } + } + + %this.objectClassName = "ScatterSky"; + + %this.addField("rayleighScattering", "TypeFloat", "Rayleigh Scattering", "0.0035"); + %this.addField("mieScattering", "TypeFloat", "Mie Scattering", "0.0045"); + %this.addField("skyBrightness", "TypeFloat", "Sky Brightness", "25"); + + %this.process(); + + // This is a trick... any fields added after process won't show + // up as controls, but will be applied to the created object. + %this.addField( "flareType", "TypeLightFlareDataPtr", "Flare", "ScatterSkyFlareExample" ); + %this.addField( "moonMat", "TypeMaterialName", "Moon Material", "Moon_Glow_Mat" ); + %this.addField( "nightCubemap", "TypeCubemapName", "Night Cubemap", "NightCubemap" ); + %this.addField( "useNightCubemap", "TypeBool", "Use Night Cubemap", "true" ); + +} + +function ObjectBuilderGui::buildCloudLayer(%this) +{ + OBObjectName.setValue( "" ); + %this.objectClassName = "CloudLayer"; + %this.addField( "texture", "TypeImageFilename", "Texture", "core/art/skies/clouds/clouds_normal_displacement" ); + %this.process(); +} + +function ObjectBuilderGui::buildBasicClouds(%this) +{ + OBObjectName.setValue( "" ); + %this.objectClassName = "BasicClouds"; + %this.process(); + + // This is a trick... any fields added after process won't show + // up as controls, but will be applied to the created object. + %this.addField( "texture[0]", "TypeImageFilename", "Texture", "core/art/skies/clouds/cloud1" ); + %this.addField( "texture[1]", "TypeImageFilename", "Texture", "core/art/skies/clouds/cloud2" ); + %this.addField( "texture[2]", "TypeImageFilename", "Texture", "core/art/skies/clouds/cloud3" ); +} + +function ObjectBuilderGui::checkExists( %this, %classname ) +{ + for ( %i = 0; %i < EWCreatorWindow.objectGroup.getCount(); %i++ ) + { + %obj = EWCreatorWindow.objectGroup.getObject( %i ); + if ( %obj.getClassName() $= %classname ) + return true; + } + + return false; +} + +function ObjectBuilderGui::buildsgMissionLightingFilter(%this) +{ + %this.objectClassName = "sgMissionLightingFilter"; + %this.addField("dataBlock", "TypeDataBlock", "sgMissionLightingFilter Data", "sgMissionFilterData"); + %this.process(); +} + +function ObjectBuilderGui::buildsgDecalProjector(%this) +{ + %this.objectClassName = "sgDecalProjector"; + %this.addField("dataBlock", "TypeDataBlock", "DecalData Data", "DecalData"); + %this.process(); +} + +function ObjectBuilderGui::buildsgLightObject(%this) +{ + %this.objectClassName = "sgLightObject"; + %this.addField("dataBlock", "TypeDataBlock", "LightObject Data", "sgLightObjectData"); + %this.process(); +} + +function ObjectBuilderGui::buildSun( %this, %dontWarnAboutScatterSky ) +{ + if( !%dontWarnAboutScatterSky ) + { + // Check for scattersky object already in the level. If there is one, + // warn the user. + + initContainerTypeSearch( $TypeMasks::EnvironmentObjectType ); + while( 1 ) + { + %object = containerSearchNext(); + if( !%object ) + break; + + if( %object.isMemberOfClass( "ScatterSky" ) ) + { + MessageBoxYesNo( "Warning", + "A Sun object will conflict with the ScatterSky object that is already in the level." SPC + "Do you still want to create a Sun object?", + %this @ ".buildSun( true );" ); + return; + } + } + } + + %this.objectClassName = "Sun"; + + %this.addField("direction", "TypeVector", "Direction", "1 1 -1"); + %this.addField("color", "TypeColor", "Sun color", "0.8 0.8 0.8"); + %this.addField("ambient", "TypeColor", "Ambient color", "0.2 0.2 0.2"); + + %this.process(); + + // This is a trick... any fields added after process won't show + // up as controls, but will be applied to the created object. + %this.addField( "coronaMaterial", "TypeMaterialName", "Corona Material", "Corona_Mat" ); + %this.addField( "flareType", "TypeLightFlareDataPtr", "Flare", "SunFlareExample" ); +} + +function ObjectBuilderGui::buildLightning(%this) +{ + %this.objectClassName = "Lightning"; + + %this.addField("dataBlock", "TypeDataBlock", "Data block", "LightningData DefaultStorm"); + + %this.process(); +} + +function ObjectBuilderGui::addWaterObjectFields(%this) +{ + %this.addField("rippleDir[0]", "TypePoint2", "Ripple Direction", "0.000000 1.000000"); + %this.addField("rippleDir[1]", "TypePoint2", "Ripple Direction", "0.707000 0.707000"); + %this.addField("rippleDir[2]", "TypePoint2", "Ripple Direction", "0.500000 0.860000"); + %this.addField("rippleTexScale[0]", "TypePoint2", "Ripple Texture Scale", "7.140000 7.140000"); + %this.addField("rippleTexScale[1]", "TypePoint2", "Ripple Texture Scale", "6.250000 12.500000"); + %this.addField("rippleTexScale[2]", "TypePoint2", "Ripple Texture Scale", "50.000000 50.000000"); + %this.addField("rippleSpeed[0]", "TypeFloat", "Ripple Speed", "0.065"); + %this.addField("rippleSpeed[1]", "TypeFloat", "Ripple Speed", "0.09"); + %this.addField("rippleSpeed[2]", "TypeFloat", "Ripple Speed", "0.04"); + %this.addField("rippleMagnitude[0]", "TypeFloat", "Ripple Magnitude", "1.0"); + %this.addField("rippleMagnitude[1]", "TypeFloat", "Ripple Magnitude", "1.0"); + %this.addField("rippleMagnitude[2]", "TypeFloat", "Ripple Magnitude", "0.3"); + %this.addField("overallRippleMagnitude", "TypeFloat", "Overall Ripple Magnitude", "1.0"); + + %this.addField("waveDir[0]", "TypePoint2", "Wave Direction", "0.000000 1.000000"); + %this.addField("waveDir[1]", "TypePoint2", "Wave Direction", "0.707000 0.707000"); + %this.addField("waveDir[2]", "TypePoint2", "Wave Direction", "0.500000 0.860000"); + %this.addField("waveMagnitude[0]", "TypePoint2", "Wave Magnitude", "0.2"); + %this.addField("waveMagnitude[1]", "TypePoint2", "Wave Magnitude", "0.2"); + %this.addField("waveMagnitude[2]", "TypePoint2", "Wave Magnitude", "0.2"); + %this.addField("waveSpeed[0]", "TypeFloat", "Wave Speed", "1"); + %this.addField("waveSpeed[1]", "TypeFloat", "Wave Speed", "1"); + %this.addField("waveSpeed[2]", "TypeFloat", "Wave Speed", "1"); + %this.addField("overallWaveMagnitude", "TypeFloat", "Overall Wave Magnitude", "1.0"); + + %this.addField("rippleTex", "TypeImageFilename", "Ripple Texture", "core/art/water/ripple" ); + %this.addField("depthGradientTex", "TypeImageFilename", "Depth Gradient Texture", "core/art/water/depthcolor_ramp" ); + %this.addField("foamTex", "TypeImageFilename", "Foam Texture", "core/art/water/foam" ); + %this.addField("cubemap", "TypeRealString", "Cubemap", "DefaultSkyCubemap" ); +} + +function ObjectBuilderGui::buildWaterBlock(%this) +{ + %this.objectClassName = "WaterBlock"; + %this.addField( "baseColor", "TypeColorI", "Base Color", "45 108 171 255" ); + %this.process(); + + // This is a trick... any fields added after process won't show + // up as controls, but will be applied to the created object. + %this.addWaterObjectFields(); +} + +function ObjectBuilderGui::buildWaterPlane(%this) +{ + %this.objectClassName = "WaterPlane"; + %this.addField( "baseColor", "TypeColorI", "Base Color", "45 108 171 255" ); + %this.process(); + + // This is a trick... any fields added after process won't show + // up as controls, but will be applied to the created object. + %this.addWaterObjectFields(); +} + +function ObjectBuilderGui::buildTerrainBlock(%this) +{ + %this.objectClassName = "TerrainBlock"; + %this.createCallback = "ETerrainEditor.attachTerrain();"; + + %this.addField("terrainFile", "TypeFile", "Terrain file", "", "*.ter"); + %this.addField("squareSize", "TypeInt", "Square size", "8"); + + %this.process(); +} + +function ObjectBuilderGui::buildGroundCover( %this ) +{ + %this.objectClassName = "GroundCover"; + %this.addField( "material", "TypeMaterialName", "Material Name", "" ); + %this.addField( "shapeFilename[0]", "TypeFile", "Shape File [Optional]", "", "*.*"); + %this.process(); + + // This is a trick... any fields added after process won't show + // up as controls, but will be applied to the created object. + %this.addField( "probability[0]", "TypeFloat", "Probability", "1" ); +} + +function ObjectBuilderGui::buildPrecipitation(%this) +{ + %this.objectClassName = "Precipitation"; + %this.addField("dataBlock", "TypeDataBlock", "Precipitation data", "PrecipitationData"); + %this.process(); +} + +function ObjectBuilderGui::buildParticleEmitterNode(%this) +{ + %this.objectClassName = "ParticleEmitterNode"; + %this.addField("dataBlock", "TypeDataBlock", "datablock", "ParticleEmitterNodeData"); + %this.addField("emitter", "TypeDataBlock", "Particle data", "ParticleEmitterData"); + %this.process(); +} + +function ObjectBuilderGui::buildParticleSimulation(%this) +{ + %this.objectClassName = "ParticleSimulation"; + %this.addField("datablock", "TypeDataBlock", "datablock", "ParticleSimulationData"); + %this.process(); +} + +//------------------------------------------------------------------------------ +// Mission +//------------------------------------------------------------------------------ + +function ObjectBuilderGui::buildTrigger(%this) +{ + %this.objectClassName = "Trigger"; + %this.addField("dataBlock", "TypeDataBlock", "Data Block", "TriggerData defaultTrigger"); + %this.addField("polyhedron", "TypeTriggerPolyhedron", "Polyhedron", "-0.5 0.5 0.0 1.0 0.0 0.0 0.0 -1.0 0.0 0.0 0.0 1.0"); + %this.process(); +} + +function ObjectBuilderGui::buildPhysicalZone(%this) +{ + %this.objectClassName = "PhysicalZone"; + %this.addField("polyhedron", "TypeTriggerPolyhedron", "Polyhedron", "-0.5 0.5 0.0 1.0 0.0 0.0 0.0 -1.0 0.0 0.0 0.0 1.0"); + %this.process(); +} + +function ObjectBuilderGui::buildCamera(%this) +{ + %this.objectClassName = "Camera"; + + %this.addField("position", "TypePoint3", "Position", "0 0 0"); + %this.addField("rotation", "TypePoint4", "Rotation", "1 0 0 0"); + %this.addField("dataBlock", "TypeDataBlock", "Data block", "CameraData Observer"); + %this.addField("team", "TypeInt", "Team", "0"); + + %this.process(); +} + +function ObjectBuilderGui::buildLevelInfo(%this) +{ + if ( %this.checkExists( "LevelInfo" ) ) + { + GenericPromptDialog-->GenericPromptWindow.text = "Warning"; + GenericPromptDialog-->GenericPromptText.text = "There is already an existing LevelInfo in the scene."; + Canvas.pushDialog( GenericPromptDialog ); + return; + } + + OBObjectName.setValue( "theLevelInfo" ); + %this.objectClassName = "LevelInfo"; + %this.process(); +} + +function ObjectBuilderGui::buildTimeOfDay(%this) +{ + if ( %this.checkExists( "TimeOfDay" ) ) + { + GenericPromptDialog-->GenericPromptWindow.text = "Warning"; + GenericPromptDialog-->GenericPromptText.text = "There is already an existing TimeOfDay in the scene."; + Canvas.pushDialog( GenericPromptDialog ); + return; + } + + %this.objectClassName = "TimeOfDay"; + %this.process(); +} + +function ObjectBuilderGui::buildPlayerDropPoint(%this) +{ + %this.objectClassName = "SpawnSphere"; + %this.addField("dataBlock", "TypeDataBlock", "dataBlock", "MissionMarkerData SpawnSphereMarker"); + %this.addField("radius", "TypeFloat", "Radius", 1); + %this.addField("sphereWeight", "TypeFloat", "Sphere Weight", 1); + + %this.addField("spawnClass", "TypeString", "Spawn Class", "Player"); + %this.addField("spawnDatablock", "TypeDataBlock", "Spawn Data", "PlayerData DefaultPlayerData"); + + if( EWCreatorWindow.objectGroup.getID() == MissionGroup.getID() ) + { + if( !isObject("PlayerDropPoints") ) + MissionGroup.add( new SimGroup("PlayerDropPoints") ); + %this.objectGroup = "PlayerDropPoints"; + } + + %this.process(); +} + +function ObjectBuilderGui::buildObserverDropPoint(%this) +{ + %this.objectClassName = "SpawnSphere"; + %this.addField("dataBlock", "TypeDataBlock", "dataBlock", "MissionMarkerData SpawnSphereMarker"); + %this.addField("radius", "TypeFloat", "Radius", 1); + %this.addField("sphereWeight", "TypeFloat", "Sphere Weight", 1); + + %this.addField("spawnClass", "TypeString", "Spawn Class", "Camera"); + %this.addField("spawnDatablock", "TypeDataBlock", "Spawn Data", "CameraData Observer"); + + if( EWCreatorWindow.objectGroup.getID() == MissionGroup.getID() ) + { + if( !isObject("ObserverDropPoints") ) + MissionGroup.add( new SimGroup("ObserverDropPoints") ); + %this.objectGroup = "ObserverDropPoints"; + } + + %this.process(); +} + +//------------------------------------------------------------------------------ +// System +//------------------------------------------------------------------------------ + +function ObjectBuilderGui::buildPhysicsEntity(%this) +{ + %this.objectClassName = "PhysicsEntity"; + %this.addField("dataBlock", "TypeDataBlock", "Data block", "PhysicsEntityData"); + %this.process(); +} + +//------------------------------------------------------------------------------ +// Functions to allow scripted/datablock objects to be instantiated +//------------------------------------------------------------------------------ + +function PhysicsEntityData::create(%data) +{ + %obj = new PhysicsEntity() { + dataBlock = %data; + parentGroup = EWCreatorWindow.objectGroup; + }; + return %obj; +} + +function StaticShapeData::create(%data) +{ + %obj = new StaticShape() { + dataBlock = %data; + parentGroup = EWCreatorWindow.objectGroup; + }; + return %obj; +} + +function MissionMarkerData::create(%block) +{ + switch$(%block) + { + case "WayPointMarker": + %obj = new WayPoint() { + dataBlock = %block; + parentGroup = EWCreatorWindow.objectGroup; + }; + return(%obj); + case "SpawnSphereMarker": + %obj = new SpawnSphere() { + datablock = %block; + parentGroup = EWCreatorWindow.objectGroup; + }; + return(%obj); + } + + return(-1); +} + +function ItemData::create(%data) +{ + %obj = new Item() + { + dataBlock = %data; + parentGroup = EWCreatorWindow.objectGroup; + static = true; + rotate = true; + }; + return %obj; +} + +function TurretShapeData::create(%block) +{ + %obj = new TurretShape() { + dataBlock = %block; + static = true; + respawn = true; + parentGroup = EWCreatorWindow.objectGroup; + }; + return %obj; +} + +function AITurretShapeData::create(%block) +{ + %obj = new AITurretShape() { + dataBlock = %block; + static = true; + respawn = true; + parentGroup = EWCreatorWindow.objectGroup; + }; + return %obj; +} + +function WheeledVehicleData::create(%block) +{ + %obj = new WheeledVehicle() { + dataBlock = %block; + parentGroup = EWCreatorWindow.objectGroup; + }; + return %obj; +} + +function FlyingVehicleData::create(%block) +{ + %obj = new FlyingVehicle() + { + dataBlock = %block; + parentGroup = EWCreatorWindow.objectGroup; + }; + return(%obj); +} + +function HoverVehicleData::create(%block) +{ + %obj = new HoverVehicle() + { + dataBlock = %block; + parentGroup = EWCreatorWindow.objectGroup; + }; + return(%obj); +} + +function RigidShapeData::create(%data) +{ + %obj = new RigidShape() { + dataBlock = %data; + parentGroup = EWCreatorWindow.objectGroup; + }; + return %obj; +} + +function PhysicsShapeData::create( %datablock ) +{ + %obj = new PhysicsShape() + { + dataBlock = %datablock; + parentGroup = EWCreatorWindow.objectGroup; + + invulnerable = false; + damageRadius = 0; + areaImpulse = 0; + radiusDamage = 0; + minDamageAmount = 0; + }; + + return %obj; +} + +function ProximityMineData::create( %datablock ) +{ + %obj = new ProximityMine() + { + dataBlock = %dataBlock; + parentGroup = EWCreatorWindow.objectGroup; + static = true; // mines created by the editor are static, and armed immediately + }; + + return %obj; +} diff --git a/Templates/Empty/game/tools/worldEditor/gui/profiles.ed.cs b/Templates/Empty/game/tools/worldEditor/gui/profiles.ed.cs new file mode 100644 index 000000000..777a749fb --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/gui/profiles.ed.cs @@ -0,0 +1,126 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +singleton GuiControlProfile (EditorDefaultProfile) +{ + opaque = true; + category = "Editor"; +}; + +singleton GuiControlProfile (EditorToolButtonProfile) +{ + opaque = true; + border = 2; + category = "Editor"; +}; + +singleton GuiControlProfile (EditorTextProfile) +{ + fontType = "Arial Bold"; + fontColor = "0 0 0"; + autoSizeWidth = true; + autoSizeHeight = true; + category = "Editor"; +}; + +singleton GuiControlProfile (EditorTextProfileWhite) +{ + fontType = "Arial Bold"; + fontColor = "255 255 255"; + autoSizeWidth = true; + autoSizeHeight = true; + category = "Editor"; +}; + +singleton GuiControlProfile (WorldEditorProfile) +{ + canKeyFocus = true; + category = "Editor"; +}; + +singleton GuiControlProfile (EditorScrollProfile) +{ + opaque = true; + fillColor = "192 192 192 192"; + border = 3; + borderThickness = 2; + borderColor = "0 0 0"; + bitmap = "core/art/gui/images/scrollBar"; + hasBitmapArray = true; + category = "Editor"; +}; + +singleton GuiControlProfile (GuiEditorClassProfile) +{ + opaque = true; + fillColor = "232 232 232"; + border = true; + borderColor = "0 0 0"; + borderColorHL = "127 127 127"; + fontColor = "0 0 0"; + fontColorHL = "50 50 50"; + fixedExtent = true; + justify = "center"; + bitmap = "core/art/gui/images/scrollBar"; + hasBitmapArray = true; + category = "Editor"; +}; + +singleton GuiControlProfile( EPainterBitmapProfile ) +{ + opaque = false; + border = false; + borderColor ="243 242 241"; + Color ="230 230 230"; + category = "Editor"; +}; + +singleton GuiControlProfile( EPainterBorderButtonProfile : GuiDefaultProfile ) +{ + border = true; + borderColor = "0 0 0"; + borderThickness = 2; + + fontColorHL = "255 0 0"; + fontColorSEL = "0 0 255"; + category = "Editor"; +}; + +singleton GuiControlProfile( EPainterDragDropProfile ) +{ + justify = "center"; + fontColor = "0 0 0"; + border = 0; + textOffset = "0 0"; + opaque = true; + fillColor = "221 221 221 150"; + category = "Editor"; +}; + +singleton GizmoProfile( GlobalGizmoProfile ) +{ + // This isnt a GuiControlProfile but fits in well here. + // Don't really have to initialize this now because that will be done later + // based on the saved editor prefs. + screenLength = 100; + category = "Editor"; +}; diff --git a/Templates/Empty/game/tools/worldEditor/images/CUR_3darrow.png b/Templates/Empty/game/tools/worldEditor/images/CUR_3darrow.png new file mode 100644 index 000000000..1e06287e3 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/CUR_3darrow.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/CUR_3ddiagleft.png b/Templates/Empty/game/tools/worldEditor/images/CUR_3ddiagleft.png new file mode 100644 index 000000000..93e2af4d1 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/CUR_3ddiagleft.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/CUR_3ddiagright.png b/Templates/Empty/game/tools/worldEditor/images/CUR_3ddiagright.png new file mode 100644 index 000000000..59c09bcac Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/CUR_3ddiagright.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/CUR_3dleftright.png b/Templates/Empty/game/tools/worldEditor/images/CUR_3dleftright.png new file mode 100644 index 000000000..63c20e16a Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/CUR_3dleftright.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/CUR_3dupdown.png b/Templates/Empty/game/tools/worldEditor/images/CUR_3dupdown.png new file mode 100644 index 000000000..c0897e896 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/CUR_3dupdown.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/CUR_grab.png b/Templates/Empty/game/tools/worldEditor/images/CUR_grab.png new file mode 100644 index 000000000..7bab05a38 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/CUR_grab.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/CUR_hand.png b/Templates/Empty/game/tools/worldEditor/images/CUR_hand.png new file mode 100644 index 000000000..5e1073644 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/CUR_hand.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/CUR_rotate.png b/Templates/Empty/game/tools/worldEditor/images/CUR_rotate.png new file mode 100644 index 000000000..24c91b854 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/CUR_rotate.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/DefaultHandle.png b/Templates/Empty/game/tools/worldEditor/images/DefaultHandle.png new file mode 100644 index 000000000..c32ed3fb8 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/DefaultHandle.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/LockedHandle.png b/Templates/Empty/game/tools/worldEditor/images/LockedHandle.png new file mode 100644 index 000000000..37f2ddec4 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/LockedHandle.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/SelectHandle.png b/Templates/Empty/game/tools/worldEditor/images/SelectHandle.png new file mode 100644 index 000000000..941fcd9c8 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/SelectHandle.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/boxBrush_d.PNG b/Templates/Empty/game/tools/worldEditor/images/boxBrush_d.PNG new file mode 100644 index 000000000..8cb9baff5 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/boxBrush_d.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/boxBrush_h.PNG b/Templates/Empty/game/tools/worldEditor/images/boxBrush_h.PNG new file mode 100644 index 000000000..b380cf4a6 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/boxBrush_h.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/boxBrush_n.PNG b/Templates/Empty/game/tools/worldEditor/images/boxBrush_n.PNG new file mode 100644 index 000000000..fee5a9cf3 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/boxBrush_n.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/brushAdjustHeight_d.PNG b/Templates/Empty/game/tools/worldEditor/images/brushAdjustHeight_d.PNG new file mode 100644 index 000000000..056bae49e Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/brushAdjustHeight_d.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/brushAdjustHeight_h.PNG b/Templates/Empty/game/tools/worldEditor/images/brushAdjustHeight_h.PNG new file mode 100644 index 000000000..8b8f181e2 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/brushAdjustHeight_h.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/brushAdjustHeight_n.png b/Templates/Empty/game/tools/worldEditor/images/brushAdjustHeight_n.png new file mode 100644 index 000000000..d0d03edb5 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/brushAdjustHeight_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/brushPaintNoise_d.png b/Templates/Empty/game/tools/worldEditor/images/brushPaintNoise_d.png new file mode 100644 index 000000000..66a10bc37 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/brushPaintNoise_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/brushPaintNoise_h.png b/Templates/Empty/game/tools/worldEditor/images/brushPaintNoise_h.png new file mode 100644 index 000000000..921e03bc7 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/brushPaintNoise_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/brushPaintNoise_n.png b/Templates/Empty/game/tools/worldEditor/images/brushPaintNoise_n.png new file mode 100644 index 000000000..7d14ea43d Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/brushPaintNoise_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/brushThermalErosion.png b/Templates/Empty/game/tools/worldEditor/images/brushThermalErosion.png new file mode 100644 index 000000000..339ad47e8 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/brushThermalErosion.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/brushThermalErosion_d.png b/Templates/Empty/game/tools/worldEditor/images/brushThermalErosion_d.png new file mode 100644 index 000000000..89aaea06c Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/brushThermalErosion_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/brushThermalErosion_h.png b/Templates/Empty/game/tools/worldEditor/images/brushThermalErosion_h.png new file mode 100644 index 000000000..8d3dc826e Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/brushThermalErosion_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/circleBrush_d.PNG b/Templates/Empty/game/tools/worldEditor/images/circleBrush_d.PNG new file mode 100644 index 000000000..1c4d37bf5 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/circleBrush_d.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/circleBrush_h.PNG b/Templates/Empty/game/tools/worldEditor/images/circleBrush_h.PNG new file mode 100644 index 000000000..cfea7736f Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/circleBrush_h.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/circleBrush_n.PNG b/Templates/Empty/game/tools/worldEditor/images/circleBrush_n.PNG new file mode 100644 index 000000000..82a47b748 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/circleBrush_n.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/clearEmpty_d.PNG b/Templates/Empty/game/tools/worldEditor/images/clearEmpty_d.PNG new file mode 100644 index 000000000..cdbe87769 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/clearEmpty_d.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/clearEmpty_h.PNG b/Templates/Empty/game/tools/worldEditor/images/clearEmpty_h.PNG new file mode 100644 index 000000000..9b24adf90 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/clearEmpty_h.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/clearEmpty_n.PNG b/Templates/Empty/game/tools/worldEditor/images/clearEmpty_n.PNG new file mode 100644 index 000000000..6aed6c702 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/clearEmpty_n.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/flattenHeight_d.PNG b/Templates/Empty/game/tools/worldEditor/images/flattenHeight_d.PNG new file mode 100644 index 000000000..963c1d320 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/flattenHeight_d.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/flattenHeight_h.PNG b/Templates/Empty/game/tools/worldEditor/images/flattenHeight_h.PNG new file mode 100644 index 000000000..c9ce739da Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/flattenHeight_h.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/flattenHeight_n.PNG b/Templates/Empty/game/tools/worldEditor/images/flattenHeight_n.PNG new file mode 100644 index 000000000..d8d1931ad Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/flattenHeight_n.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/lowerHeight_d.PNG b/Templates/Empty/game/tools/worldEditor/images/lowerHeight_d.PNG new file mode 100644 index 000000000..79d2384d7 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/lowerHeight_d.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/lowerHeight_h.PNG b/Templates/Empty/game/tools/worldEditor/images/lowerHeight_h.PNG new file mode 100644 index 000000000..07e3dd25a Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/lowerHeight_h.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/lowerHeight_n.PNG b/Templates/Empty/game/tools/worldEditor/images/lowerHeight_n.PNG new file mode 100644 index 000000000..048615dcf Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/lowerHeight_n.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/maskBrush_d.PNG b/Templates/Empty/game/tools/worldEditor/images/maskBrush_d.PNG new file mode 100644 index 000000000..007650c79 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/maskBrush_d.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/maskBrush_h.PNG b/Templates/Empty/game/tools/worldEditor/images/maskBrush_h.PNG new file mode 100644 index 000000000..a7764100a Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/maskBrush_h.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/maskBrush_n.PNG b/Templates/Empty/game/tools/worldEditor/images/maskBrush_n.PNG new file mode 100644 index 000000000..99bafbcb4 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/maskBrush_n.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/raiseHeight_d.PNG b/Templates/Empty/game/tools/worldEditor/images/raiseHeight_d.PNG new file mode 100644 index 000000000..870db9d38 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/raiseHeight_d.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/raiseHeight_h.PNG b/Templates/Empty/game/tools/worldEditor/images/raiseHeight_h.PNG new file mode 100644 index 000000000..6c95d4f7f Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/raiseHeight_h.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/raiseHeight_n.PNG b/Templates/Empty/game/tools/worldEditor/images/raiseHeight_n.PNG new file mode 100644 index 000000000..e110a5247 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/raiseHeight_n.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/add-mesh-road_d.png b/Templates/Empty/game/tools/worldEditor/images/road-river/add-mesh-road_d.png new file mode 100644 index 000000000..e97d7edc9 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/add-mesh-road_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/add-mesh-road_h.png b/Templates/Empty/game/tools/worldEditor/images/road-river/add-mesh-road_h.png new file mode 100644 index 000000000..1dc2a5663 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/add-mesh-road_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/add-mesh-road_n.png b/Templates/Empty/game/tools/worldEditor/images/road-river/add-mesh-road_n.png new file mode 100644 index 000000000..717e60356 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/add-mesh-road_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/add-point_d.png b/Templates/Empty/game/tools/worldEditor/images/road-river/add-point_d.png new file mode 100644 index 000000000..4d3dfa759 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/add-point_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/add-point_h.png b/Templates/Empty/game/tools/worldEditor/images/road-river/add-point_h.png new file mode 100644 index 000000000..fbdac0f6e Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/add-point_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/add-point_n.png b/Templates/Empty/game/tools/worldEditor/images/road-river/add-point_n.png new file mode 100644 index 000000000..6e6dff3d7 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/add-point_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/add-river_d.png b/Templates/Empty/game/tools/worldEditor/images/road-river/add-river_d.png new file mode 100644 index 000000000..112d5dba6 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/add-river_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/add-river_h.png b/Templates/Empty/game/tools/worldEditor/images/road-river/add-river_h.png new file mode 100644 index 000000000..7c0261f25 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/add-river_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/add-river_n.png b/Templates/Empty/game/tools/worldEditor/images/road-river/add-river_n.png new file mode 100644 index 000000000..a283365dc Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/add-river_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/add-road-path_d.png b/Templates/Empty/game/tools/worldEditor/images/road-river/add-road-path_d.png new file mode 100644 index 000000000..96ecb99f0 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/add-road-path_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/add-road-path_h.png b/Templates/Empty/game/tools/worldEditor/images/road-river/add-road-path_h.png new file mode 100644 index 000000000..0e7556879 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/add-road-path_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/add-road-path_n.png b/Templates/Empty/game/tools/worldEditor/images/road-river/add-road-path_n.png new file mode 100644 index 000000000..6cecf08e0 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/add-road-path_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-spline_d.png b/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-spline_d.png new file mode 100644 index 000000000..87e93b120 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-spline_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-spline_h.png b/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-spline_h.png new file mode 100644 index 000000000..80baf68ba Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-spline_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-spline_n.png b/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-spline_n.png new file mode 100644 index 000000000..81a0180b9 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-spline_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-texture_d.png b/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-texture_d.png new file mode 100644 index 000000000..03fee8c42 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-texture_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-texture_h.png b/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-texture_h.png new file mode 100644 index 000000000..92bac44dc Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-texture_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-texture_n.png b/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-texture_n.png new file mode 100644 index 000000000..31601728f Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-texture_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-wireframe_d.png b/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-wireframe_d.png new file mode 100644 index 000000000..c32ca6b94 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-wireframe_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-wireframe_h.png b/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-wireframe_h.png new file mode 100644 index 000000000..bd8e7acba Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-wireframe_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-wireframe_n.png b/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-wireframe_n.png new file mode 100644 index 000000000..099a142a8 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/menubar/show-wireframe_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/move-point_d.png b/Templates/Empty/game/tools/worldEditor/images/road-river/move-point_d.png new file mode 100644 index 000000000..dc89c1d98 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/move-point_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/move-point_h.png b/Templates/Empty/game/tools/worldEditor/images/road-river/move-point_h.png new file mode 100644 index 000000000..f863eafc8 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/move-point_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/move-point_n.png b/Templates/Empty/game/tools/worldEditor/images/road-river/move-point_n.png new file mode 100644 index 000000000..f3cadb7a1 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/move-point_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/rotate-point_d.png b/Templates/Empty/game/tools/worldEditor/images/road-river/rotate-point_d.png new file mode 100644 index 000000000..18297741a Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/rotate-point_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/rotate-point_h.png b/Templates/Empty/game/tools/worldEditor/images/road-river/rotate-point_h.png new file mode 100644 index 000000000..5e17a9c46 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/rotate-point_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/rotate-point_n.png b/Templates/Empty/game/tools/worldEditor/images/road-river/rotate-point_n.png new file mode 100644 index 000000000..9cdb0b3df Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/rotate-point_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/scale-point_d.png b/Templates/Empty/game/tools/worldEditor/images/road-river/scale-point_d.png new file mode 100644 index 000000000..4700cd3b3 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/scale-point_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/scale-point_h.png b/Templates/Empty/game/tools/worldEditor/images/road-river/scale-point_h.png new file mode 100644 index 000000000..5ac38959f Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/scale-point_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/scale-point_n.png b/Templates/Empty/game/tools/worldEditor/images/road-river/scale-point_n.png new file mode 100644 index 000000000..1206e08cb Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/scale-point_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/subtract-point_d.png b/Templates/Empty/game/tools/worldEditor/images/road-river/subtract-point_d.png new file mode 100644 index 000000000..9f0c31b5c Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/subtract-point_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/subtract-point_h.png b/Templates/Empty/game/tools/worldEditor/images/road-river/subtract-point_h.png new file mode 100644 index 000000000..b3cfb6aac Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/subtract-point_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/road-river/subtract-point_n.png b/Templates/Empty/game/tools/worldEditor/images/road-river/subtract-point_n.png new file mode 100644 index 000000000..3180edba4 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/road-river/subtract-point_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/setEmpty_d.PNG b/Templates/Empty/game/tools/worldEditor/images/setEmpty_d.PNG new file mode 100644 index 000000000..9a3194b24 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/setEmpty_d.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/setEmpty_h.PNG b/Templates/Empty/game/tools/worldEditor/images/setEmpty_h.PNG new file mode 100644 index 000000000..87118eea7 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/setEmpty_h.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/setEmpty_n.PNG b/Templates/Empty/game/tools/worldEditor/images/setEmpty_n.PNG new file mode 100644 index 000000000..7f1d4df67 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/setEmpty_n.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/setHeight_d.PNG b/Templates/Empty/game/tools/worldEditor/images/setHeight_d.PNG new file mode 100644 index 000000000..1422857fa Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/setHeight_d.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/setHeight_h.PNG b/Templates/Empty/game/tools/worldEditor/images/setHeight_h.PNG new file mode 100644 index 000000000..448612785 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/setHeight_h.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/setHeight_n.PNG b/Templates/Empty/game/tools/worldEditor/images/setHeight_n.PNG new file mode 100644 index 000000000..83196ea6e Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/setHeight_n.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/smoothHeight_d.PNG b/Templates/Empty/game/tools/worldEditor/images/smoothHeight_d.PNG new file mode 100644 index 000000000..05678ed31 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/smoothHeight_d.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/smoothHeight_h.PNG b/Templates/Empty/game/tools/worldEditor/images/smoothHeight_h.PNG new file mode 100644 index 000000000..bd5f71ec3 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/smoothHeight_h.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/smoothHeight_n.PNG b/Templates/Empty/game/tools/worldEditor/images/smoothHeight_n.PNG new file mode 100644 index 000000000..1bec2d18d Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/smoothHeight_n.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/softCurve_d.PNG b/Templates/Empty/game/tools/worldEditor/images/softCurve_d.PNG new file mode 100644 index 000000000..89679ff79 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/softCurve_d.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/softCurve_h.PNG b/Templates/Empty/game/tools/worldEditor/images/softCurve_h.PNG new file mode 100644 index 000000000..c04786d96 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/softCurve_h.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/softCurve_n.PNG b/Templates/Empty/game/tools/worldEditor/images/softCurve_n.PNG new file mode 100644 index 000000000..a1cf84d6a Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/softCurve_n.PNG differ diff --git a/Templates/Empty/game/tools/worldEditor/images/terrainpainter/new_layer_icon.png b/Templates/Empty/game/tools/worldEditor/images/terrainpainter/new_layer_icon.png new file mode 100644 index 000000000..3589b8d20 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/terrainpainter/new_layer_icon.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/terrainpainter/terrain-painter-border-large.png b/Templates/Empty/game/tools/worldEditor/images/terrainpainter/terrain-painter-border-large.png new file mode 100644 index 000000000..84bc9be6b Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/terrainpainter/terrain-painter-border-large.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/terrainpainter/terrain-painter-border-new_h.png b/Templates/Empty/game/tools/worldEditor/images/terrainpainter/terrain-painter-border-new_h.png new file mode 100644 index 000000000..a650fe2d9 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/terrainpainter/terrain-painter-border-new_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/terrainpainter/terrain-painter-border-new_n.png b/Templates/Empty/game/tools/worldEditor/images/terrainpainter/terrain-painter-border-new_n.png new file mode 100644 index 000000000..ef1fa85c9 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/terrainpainter/terrain-painter-border-new_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/terrainpainter/terrain-painter-border_d.png b/Templates/Empty/game/tools/worldEditor/images/terrainpainter/terrain-painter-border_d.png new file mode 100644 index 000000000..edb9b29cc Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/terrainpainter/terrain-painter-border_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/terrainpainter/terrain-painter-border_h.png b/Templates/Empty/game/tools/worldEditor/images/terrainpainter/terrain-painter-border_h.png new file mode 100644 index 000000000..cbe39f4da Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/terrainpainter/terrain-painter-border_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/terrainpainter/terrain-painter-border_n.png b/Templates/Empty/game/tools/worldEditor/images/terrainpainter/terrain-painter-border_n.png new file mode 100644 index 000000000..f80943fb2 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/terrainpainter/terrain-painter-border_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/3rd-person-camera_d.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/3rd-person-camera_d.png new file mode 100644 index 000000000..c63ab98cf Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/3rd-person-camera_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/3rd-person-camera_h.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/3rd-person-camera_h.png new file mode 100644 index 000000000..def996838 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/3rd-person-camera_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/3rd-person-camera_n.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/3rd-person-camera_n.png new file mode 100644 index 000000000..e45cc4244 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/3rd-person-camera_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/camera_d.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/camera_d.png new file mode 100644 index 000000000..6500b92c5 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/camera_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/camera_h.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/camera_h.png new file mode 100644 index 000000000..0451a0e9c Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/camera_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/camera_n.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/camera_n.png new file mode 100644 index 000000000..516c0c00e Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/camera_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/datablock-editor_d.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/datablock-editor_d.png new file mode 100644 index 000000000..8911e14d7 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/datablock-editor_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/datablock-editor_h.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/datablock-editor_h.png new file mode 100644 index 000000000..cd2cfec3d Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/datablock-editor_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/datablock-editor_n.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/datablock-editor_n.png new file mode 100644 index 000000000..44d08018a Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/datablock-editor_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/gui.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/gui.png new file mode 100644 index 000000000..9971dc150 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/gui.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/gui_d.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/gui_d.png new file mode 100644 index 000000000..376b3f9d0 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/gui_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/gui_h.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/gui_h.png new file mode 100644 index 000000000..96e58de3f Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/gui_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/matterial-editor_d.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/matterial-editor_d.png new file mode 100644 index 000000000..e850a5873 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/matterial-editor_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/matterial-editor_h.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/matterial-editor_h.png new file mode 100644 index 000000000..93df1f2ac Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/matterial-editor_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/matterial-editor_n.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/matterial-editor_n.png new file mode 100644 index 000000000..326589e1f Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/matterial-editor_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/mesh-road-editor_d.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/mesh-road-editor_d.png new file mode 100644 index 000000000..125308927 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/mesh-road-editor_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/mesh-road-editor_h.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/mesh-road-editor_h.png new file mode 100644 index 000000000..45eabc320 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/mesh-road-editor_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/mesh-road-editor_n.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/mesh-road-editor_n.png new file mode 100644 index 000000000..1cb88dc8e Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/mesh-road-editor_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/missionarea-editor_d.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/missionarea-editor_d.png new file mode 100644 index 000000000..72457d069 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/missionarea-editor_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/missionarea-editor_h.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/missionarea-editor_h.png new file mode 100644 index 000000000..7bff1444f Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/missionarea-editor_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/missionarea-editor_n.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/missionarea-editor_n.png new file mode 100644 index 000000000..6a8533f5a Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/missionarea-editor_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/paint-terrain_d.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/paint-terrain_d.png new file mode 100644 index 000000000..144099429 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/paint-terrain_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/paint-terrain_h.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/paint-terrain_h.png new file mode 100644 index 000000000..9ca94ff58 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/paint-terrain_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/paint-terrain_n.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/paint-terrain_n.png new file mode 100644 index 000000000..b2d156044 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/paint-terrain_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/particleeditor_d.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/particleeditor_d.png new file mode 100644 index 000000000..9867911ed Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/particleeditor_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/particleeditor_h.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/particleeditor_h.png new file mode 100644 index 000000000..e7fd0b0fc Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/particleeditor_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/particleeditor_n.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/particleeditor_n.png new file mode 100644 index 000000000..d8c6266af Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/particleeditor_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/playbutton_d.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/playbutton_d.png new file mode 100644 index 000000000..08b3b8641 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/playbutton_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/playbutton_h.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/playbutton_h.png new file mode 100644 index 000000000..2059a23fb Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/playbutton_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/playbutton_n.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/playbutton_n.png new file mode 100644 index 000000000..24840940b Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/playbutton_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/player_d.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/player_d.png new file mode 100644 index 000000000..ad03e6c93 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/player_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/player_h.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/player_h.png new file mode 100644 index 000000000..fae070bdf Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/player_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/player_n.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/player_n.png new file mode 100644 index 000000000..15e7e5504 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/player_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/river-editor_d.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/river-editor_d.png new file mode 100644 index 000000000..1e9abf699 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/river-editor_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/river-editor_h.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/river-editor_h.png new file mode 100644 index 000000000..2d57d4a10 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/river-editor_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/river-editor_n.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/river-editor_n.png new file mode 100644 index 000000000..e7cb27a09 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/river-editor_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/road-path-editor_d.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/road-path-editor_d.png new file mode 100644 index 000000000..a0e961fc9 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/road-path-editor_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/road-path-editor_h.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/road-path-editor_h.png new file mode 100644 index 000000000..25b47ae25 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/road-path-editor_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/road-path-editor_n.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/road-path-editor_n.png new file mode 100644 index 000000000..9435692d9 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/road-path-editor_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/sculpt-terrain_d.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/sculpt-terrain_d.png new file mode 100644 index 000000000..72457d069 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/sculpt-terrain_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/sculpt-terrain_h.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/sculpt-terrain_h.png new file mode 100644 index 000000000..7bff1444f Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/sculpt-terrain_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/sculpt-terrain_n.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/sculpt-terrain_n.png new file mode 100644 index 000000000..6a8533f5a Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/sculpt-terrain_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/shape-editor_d.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/shape-editor_d.png new file mode 100644 index 000000000..5e1bfff7f Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/shape-editor_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/shape-editor_h.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/shape-editor_h.png new file mode 100644 index 000000000..c512a6ae4 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/shape-editor_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/shape-editor_n.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/shape-editor_n.png new file mode 100644 index 000000000..e583f2549 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/shape-editor_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/transform-objects_d.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/transform-objects_d.png new file mode 100644 index 000000000..5ee2faf47 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/transform-objects_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/transform-objects_h.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/transform-objects_h.png new file mode 100644 index 000000000..68c21d9e4 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/transform-objects_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/transform-objects_n.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/transform-objects_n.png new file mode 100644 index 000000000..51f81427f Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/transform-objects_n.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/world.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/world.png new file mode 100644 index 000000000..e08a1b89d Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/world.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/world_d.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/world_d.png new file mode 100644 index 000000000..da4cb5856 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/world_d.png differ diff --git a/Templates/Empty/game/tools/worldEditor/images/toolbar/world_h.png b/Templates/Empty/game/tools/worldEditor/images/toolbar/world_h.png new file mode 100644 index 000000000..9f68f1bc0 Binary files /dev/null and b/Templates/Empty/game/tools/worldEditor/images/toolbar/world_h.png differ diff --git a/Templates/Empty/game/tools/worldEditor/main.cs b/Templates/Empty/game/tools/worldEditor/main.cs new file mode 100644 index 000000000..0f8228b82 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/main.cs @@ -0,0 +1,129 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function initializeWorldEditor() +{ + echo(" % - Initializing World Editor"); + + // Load GUI + exec("./gui/profiles.ed.cs"); + exec("./scripts/cursors.ed.cs"); + + exec("./gui/guiCreateNewTerrainGui.gui" ); + exec("./gui/genericPromptDialog.ed.gui" ); + exec("./gui/guiTerrainImportGui.gui" ); + exec("./gui/guiTerrainExportGui.gui" ); + exec("./gui/guiInteriorExportGui.gui" ); + exec("./gui/EditorGui.ed.gui"); + exec("./gui/objectBuilderGui.ed.gui"); + exec("./gui/TerrainEditorVSettingsGui.ed.gui"); + exec("./gui/EditorChooseLevelGui.ed.gui"); + exec("./gui/VisibilityLayerWindow.ed.gui"); + exec("./gui/ManageBookmarksWindow.ed.gui"); + exec("./gui/ManageSFXParametersWindow.ed.gui" ); + exec("./gui/TimeAdjustGui.ed.gui"); + exec("./gui/AddFMODProjectDlg.ed.gui"); + exec("./gui/SelectObjectsWindow.ed.gui"); + + // Load Scripts. + exec("./scripts/menus.ed.cs"); + exec("./scripts/menuHandlers.ed.cs"); + exec("./scripts/editor.ed.cs"); + exec("./scripts/editor.bind.ed.cs"); + exec("./scripts/undoManager.ed.cs"); + exec("./scripts/lighting.ed.cs"); + exec("./scripts/EditorGui.ed.cs"); + exec("./scripts/editorPrefs.ed.cs"); + exec("./scripts/editorRender.ed.cs"); + exec("./scripts/editorPlugin.ed.cs"); + exec("./scripts/EditorChooseLevelGui.ed.cs"); + exec("./scripts/visibilityLayer.ed.cs"); + exec("./scripts/cameraBookmarks.ed.cs"); + exec("./scripts/ManageSFXParametersWindow.ed.cs"); + exec("./scripts/AddFMODProjectDlg.ed.cs"); + exec("./scripts/SelectObjectsWindow.ed.cs"); + + // Load Custom Editors + loadDirectory(expandFilename("./scripts/editors")); + loadDirectory(expandFilename("./scripts/interfaces")); + + // Create the default editor plugins before calling buildMenus. + + new ScriptObject( WorldEditorPlugin ) + { + superClass = "EditorPlugin"; + editorGui = EWorldEditor; + }; + + // aka. The ObjectEditor. + new ScriptObject( WorldEditorInspectorPlugin ) + { + superClass = "WorldEditorPlugin"; + editorGui = EWorldEditor; + }; + + new ScriptObject( TerrainEditorPlugin ) + { + superClass = "EditorPlugin"; + editorGui = ETerrainEditor; + }; + + new ScriptObject( TerrainPainterPlugin ) + { + superClass = "EditorPlugin"; + editorGui = ETerrainEditor; + }; + + new ScriptObject( MaterialEditorPlugin ) + { + superClass = "WorldEditorPlugin"; + editorGui = EWorldEditor; + }; + + // Expose stock visibility/debug options. + EVisibility.addOption( "Render: Zones", "$Zone::isRenderable", "" ); + EVisibility.addOption( "Render: Portals", "$Portal::isRenderable", "" ); + EVisibility.addOption( "Render: Occlusion Volumes", "$OcclusionVolume::isRenderable", "" ); + EVisibility.addOption( "Render: Triggers", "$Trigger::renderTriggers", "" ); + EVisibility.addOption( "Render: PhysicalZones", "$PhysicalZone::renderZones", "" ); + EVisibility.addOption( "Render: Sound Emitters", "$SFXEmitter::renderEmitters", "" ); + EVisibility.addOption( "Render: Mission Area", "EWorldEditor.renderMissionArea", "" ); + EVisibility.addOption( "Render: Sound Spaces", "$SFXSpace::isRenderable", "" ); + EVisibility.addOption( "Wireframe Mode", "$gfx::wireframe", "" ); + EVisibility.addOption( "Debug Render: Player Collision", "$Player::renderCollision", "" ); + EVisibility.addOption( "Debug Render: Terrain", "TerrainBlock::debugRender", "" ); + EVisibility.addOption( "Debug Render: Decals", "$Decals::debugRender", "" ); + EVisibility.addOption( "Debug Render: Light Frustums", "$Light::renderLightFrustums", "" ); + EVisibility.addOption( "Debug Render: Bounding Boxes", "$Scene::renderBoundingBoxes", "" ); + EVisibility.addOption( "AL: Disable Shadows", "$Shadows::disable", "" ); + EVisibility.addOption( "AL: Light Color Viz", "$AL_LightColorVisualizeVar", "toggleLightColorViz" ); + EVisibility.addOption( "AL: Light Specular Viz", "$AL_LightSpecularVisualizeVar", "toggleLightSpecularViz" ); + EVisibility.addOption( "AL: Normals Viz", "$AL_NormalsVisualizeVar", "toggleNormalsViz" ); + EVisibility.addOption( "AL: Depth Viz", "$AL_DepthVisualizeVar", "toggleDepthViz" ); + EVisibility.addOption( "Frustum Lock", "$Scene::lockCull", "" ); + EVisibility.addOption( "Disable Zone Culling", "$Scene::disableZoneCulling", "" ); + EVisibility.addOption( "Disable Terrain Occlusion", "$Scene::disableTerrainOcclusion", "" ); +} + +function destroyWorldEditor() +{ +} diff --git a/Templates/Empty/game/tools/worldEditor/scripts/AddFMODProjectDlg.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/AddFMODProjectDlg.ed.cs new file mode 100644 index 000000000..a005ab4b3 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/AddFMODProjectDlg.ed.cs @@ -0,0 +1,253 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + + +//============================================================================= +// AddFMODProjectDlg. +//============================================================================= + +//----------------------------------------------------------------------------- + +function AddFMODProjectDlg::show( %this ) +{ + if( $platform $= "macos" ) + { + %fmodex = "libfmodex.dylib"; + %fmodevent = "libfmodevent.dylib"; + } + else + { + %fmodex = "fmodex.dll"; + %fmodevent = "fmod_event.dll"; + } + + // Make sure we have FMOD running. + + if( getField( sfxGetDeviceInfo(), $SFX::DEVICE_INFO_PROVIDER ) !$= "FMOD" ) + { + MessageBoxOK( "Error", + "You do not currently have FMOD selected as your sound system." NL + "" NL + "To install FMOD, place the FMOD DLLs (" @ %fmodex @ " and " @ %fmodevent @ ")" SPC + "in your game/ folder alongside your game executable" SPC + "and restart Torque." NL + "" NL + "To select FMOD as your sound system, choose it as the sound provider in" SPC + "the audio tab of the Game Options dialog." + ); + + return; + } + + // Make sure we have the FMOD Event DLL loaded. + + %deviceCaps = getField( sfxGetDeviceInfo(), $SFX::DEVICE_INFO_CAPS ); + if( !( %deviceCaps & $SFX::DEVICE_CAPS_FMODDESIGNER ) ) + { + MessageBoxOK( "Error", + "You do not have the requisite FMOD Event DLL in place." NL + "" NL + "Please copy " @ %fmodevent @ " into your game/ folder and restart Torque." + ); + return; + } + + // Show it. + + Canvas.pushDialog( %this, 0, true ); +} + +//----------------------------------------------------------------------------- + +function AddFMODProjectDlg::onWake( %this ) +{ + %this.persistenceMgr = new PersistenceManager(); +} + +//----------------------------------------------------------------------------- + +function AddFMODProjectDlg::onSleep( %this ) +{ + %this.persistenceMgr.delete(); +} + +//----------------------------------------------------------------------------- + +function AddFMODProjectDlg::onCancel( %this ) +{ + Canvas.popDialog( %this ); +} + +//----------------------------------------------------------------------------- + +function AddFMODProjectDlg::onOK( %this ) +{ + %objName = %this-->projectNameField.getText(); + %fileName = %this-->fileNameField.getText(); + %mediaPath = %this-->mediaPathField.getText(); + + // Make sure the object name is valid. + if( !Editor::validateObjectName( %objName, true )) + return; + + // Make sure the .fev file exists. + + if( %fileName $= "" ) + { + MessageBoxOK( "Error", + "Please enter a project file name." + ); + return; + } + if( !isFile( %fileName ) ) + { + MessageBoxOK( "Error", + "'" @ %fileName @ "' is not a valid file." + ); + return; + } + + // Make sure the media path exists. + + if( !isDirectory( %mediaPath ) ) + { + MessageBoxOK( "Error", + "'" @ %mediaPath @ "' is not a valid directory." + ); + return; + } + + // If an event script exists from a previous instantiation, + // delete it first. + + %eventFileName = %fileName @ ".cs"; + if( isFile( %eventFileName ) ) + fileDelete( %eventFileName ); + + // Create the FMOD project object. + + pushInstantGroup(); + eval( "new SFXFMODProject( " @ %objName @ ") {" NL + "fileName = \"" @ %fileName @ "\";" NL + "mediaPath = \"" @ %mediaPath @ "\";" NL + "};" ); + popInstantGroup(); + + if( !isObject( %objName ) ) + { + MessageBoxOK( "Error", + "Failed to create the object. Please take a look at the log for details." + ); + return; + } + else + { + // Save the object. + + %objName.setFileName( "scripts/client/audioData.cs" ); + %this.persistenceMgr.setDirty( %objName ); + %this.persistenceMgr.saveDirty(); + } + + Canvas.popDialog( %this ); + + // Trigger a reinit on the datablock editor, just in case. + + if( isObject( DatablockEditorPlugin ) ) + DatablockEditorPlugin.populateTrees(); +} + +//----------------------------------------------------------------------------- + +function AddFMODProjectDlg::onSelectFile( %this ) +{ + if( $pref::WorldEditor::AddFMODProjectDlg::lastPath $= "" ) + $pref::WorldEditor::AddFMODProjectDlg::lastPath = getMainDotCsDir(); + + %dlg = new OpenFileDialog() + { + Title = "Select Compiled FMOD Designer Event File..."; + Filters = "Compiled Event Files (*.fev)|*.fev|All Files (*.*)|*.*|"; + DefaultPath = $pref::WorldEditor::AddFMODProjectDlg::lastPath; + DefaultFile = fileName( %this-->fileNameField.getText() ); + MustExit = true; + ChangePath = false; + }; + + %ret = %dlg.execute(); + if( %ret ) + { + %file = %dlg.fileName; + $pref::WorldEditor::AddFMODProjectDlg::lastPath = filePath( %file ); + } + + %dlg.delete(); + + if( !%ret ) + return; + + %file = makeRelativePath( %file, getMainDotCsDir() ); + %this-->fileNameField.setText( %file ); + + if( %this-->projectNameField.getText() $= "" ) + { + %projectName = "fmod" @ fileBase( %file ); + if( isValidObjectName( %projectName ) ) + %this-->projectNameField.setText( %projectName ); + } +} + +//----------------------------------------------------------------------------- + +function AddFMODProjectDlg::onSelectMediaPath( %this ) +{ + %defaultPath = %this-->mediaPathField.getText(); + if( %defaultPath $= "" ) + { + %defaultPath = filePath( %this-->fileNameField.getText() ); + if( %defaultPath $= "" ) + %defaultPath = getMainDotCsDir(); + else + %defaultPath = makeFullPath( %defaultPath ); + } + + %dlg = new OpenFolderDialog() + { + Title = "Select Media Path..."; + DefaultPath = %defaultPath; + MustExit = true; + ChangePath = false; + }; + + %ret = %dlg.execute(); + if( %ret ) + %file = %dlg.fileName; + + %dlg.delete(); + + if( !%ret ) + return; + + %file = makeRelativePath( %file, getMainDotCsDir() ); + %this-->mediaPathField.setText( %file ); +} diff --git a/Templates/Empty/game/tools/worldEditor/scripts/EditorChooseLevelGui.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/EditorChooseLevelGui.ed.cs new file mode 100644 index 000000000..01c6d9fbe --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/EditorChooseLevelGui.ed.cs @@ -0,0 +1,155 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function EditorChooseLevelGui::onWake() +{ + // first check if we have a level file to load, then we'll bypass this + if ($levelToLoad !$= "") + { + // First try using the file path raw... it may already be good. + %file = findFirstFile( $levelToLoad ); + if ( %file $= "" ) + { + %levelFile = "levels/"; + %ext = getSubStr($levelToLoad, strlen($levelToLoad) - 3, 3); + if(%ext !$= "mis") + %levelFile = %levelFile @ $levelToLoad @ ".mis"; + else + %levelFile = %levelFile @ $levelToLoad; + + // let's make sure the file exists + %file = findFirstFile(%levelFile); + } + + // Clear out the $levelToLoad so we don't attempt to load the level again + // later on. + $levelToLoad = ""; + + if(%file !$= "") + { + WE_EditLevel(%file); + return; + } + } + + //If no valid name, then push the level chooser + Canvas.pushDialog(EditorChooseLevelContainer); +} + +function EditorChooseLevelContainer::onWake(%this) +{ + // Build the text lists + WE_LevelList.clear(); + WE_TemplateList.clear(); + + %leveltext = "<linkcolor:0000FF><linkcolorhl:FF0000>"; + %templatetext = "<linkcolor:0000FF><linkcolorhl:FF0000>"; + for(%file = findFirstFile($Server::MissionFileSpec); %file !$= ""; %file = findNextFile($Server::MissionFileSpec)) + { + %name = getLevelDisplayName(%file); + %n = strlwr(%name); + if(strstr(%n, "template") == -1) + { + %leveltext = %leveltext @ "<a:gamelink:" @ %file @ ">" @ %name @ "</a><br>"; + } + else + { + %templatetext = %templatetext @ "<a:gamelink:" @ %file @ ">" @ %name @ "</a><br>"; + } + } + + WE_LevelList.setText(%leveltext); + WE_LevelList.forceReflow(); + WE_LevelList.scrollToTop(); + + WE_TemplateList.setText(%templatetext); + WE_TemplateList.forceReflow(); + WE_TemplateList.scrollToTop(); +} + +function WE_EditLevel(%levelFile) +{ + EditorOpenMission( %levelFile ); +} + +function WE_ReturnToMainMenu() +{ + loadMainMenu(); +} + +function WE_LevelList::onURL(%this, %url) +{ + // Remove 'gamelink:' from front + %levelFile = getSubStr(%url, 9, 1024); + WE_EditLevel(%levelFile); +} + +function WE_TemplateList::onURL(%this, %url) +{ + // Remove 'gamelink:' from front + %levelFile = getSubStr(%url, 9, 1024); + WE_EditLevel(%levelFile); + EditorGui.saveAs = true; +} + +function getLevelDisplayName( %levelFile ) +{ + %file = new FileObject(); + + %MissionInfoObject = ""; + + if ( %file.openForRead( %levelFile ) ) { + %inInfoBlock = false; + + while ( !%file.isEOF() ) { + %line = %file.readLine(); + %line = trim( %line ); + + if( %line $= "new ScriptObject(MissionInfo) {" ) + %inInfoBlock = true; + else if( %line $= "new LevelInfo(theLevelInfo) {" ) + %inInfoBlock = true; + else if( %inInfoBlock && %line $= "};" ) { + %inInfoBlock = false; + %MissionInfoObject = %MissionInfoObject @ %line; + break; + } + + if( %inInfoBlock ) + %MissionInfoObject = %MissionInfoObject @ %line @ " "; + } + + %file.close(); + } + %MissionInfoObject = "%MissionInfoObject = " @ %MissionInfoObject; + eval( %MissionInfoObject ); + + %file.delete(); + if( %MissionInfoObject.levelName !$= "" ) + %name = %MissionInfoObject.levelName; + else + %name = fileBase(%levelFile); + + %MissionInfoObject.delete(); + + return %name; +} diff --git a/Templates/Empty/game/tools/worldEditor/scripts/EditorGui.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/EditorGui.ed.cs new file mode 100644 index 000000000..9ab5b3d1b --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/EditorGui.ed.cs @@ -0,0 +1,2636 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function EditorGui::init(%this) +{ + EWorldEditor.isDirty = false; + ETerrainEditor.isDirty = false; + ETerrainEditor.isMissionDirty = false; + + if( %this.isInitialized ) + return; + + %this.readWorldEditorSettings(); + + $SelectedOperation = -1; + $NextOperationId = 1; + $HeightfieldDirtyRow = -1; + + %this.buildMenus(); + + if( !isObject( %this-->ToolsPaletteWindow ) ) + { + // Load Creator/Inspector GUI + exec("~/worldEditor/gui/ToolsPaletteGroups/init.cs"); + exec("~/worldEditor/gui/ToolsPaletteWindow.ed.gui"); + + if( isObject( EWToolsPaletteWindow ) ) + { + %this.add( EWToolsPaletteWindow ); + EWToolsPaletteWindow.init(); + EWToolsPaletteWindow.setVisible( false ); + } + } + + if( !isObject( %this-->TreeWindow ) ) + { + // Load Creator/Inspector GUI + exec("~/worldEditor/gui/WorldEditorTreeWindow.ed.gui"); + if( isObject( EWTreeWindow ) ) + { + %this.add( EWTreeWindow ); + EWTreeWindow-->EditorTree.selectPage( 0 ); + EWTreeWindow.setVisible( false ); + } + } + + if( !isObject( %this-->InspectorWindow ) ) + { + // Load Creator/Inspector GUI + exec("~/worldEditor/gui/WorldEditorInspectorWindow.ed.gui"); + //EWInspectorWindow.resize(getWord(EWInspectorWindow.Position, 0), getWord(EWInspectorWindow.Position, 1), getWord(EWInspectorWindow.extent, 0), getWord(EWInspectorWindow.extent, 1)); + if( isObject( EWInspectorWindow ) ) + { + %this.add( EWInspectorWindow ); + EWInspectorWindow.setVisible( false ); + } + } + + if( !isObject( %this-->WorldEditorToolbar ) ) + { + // Load Creator/Inspector GUI + exec("~/worldEditor/gui/WorldEditorToolbar.ed.gui"); + if( isObject( EWorldEditorToolbar ) ) + { + %this.add( EWorldEditorToolbar ); + EWorldEditorToolbar.setVisible( false ); + } + } + + if ( !isObject( %this-->TerrainEditToolbar ) ) + { + // Load Terrain Edit GUI + exec("~/worldEditor/gui/TerrainEditToolbar.ed.gui"); + if( isObject( EWTerrainEditToolbar ) ) + { + %this.add( EWTerrainEditToolbar ); + EWTerrainEditToolbar.setVisible( false ); + } + } + + if( !isObject( %this-->TerrainPainter ) ) + { + // Load Terrain Painter GUI + exec("~/worldEditor/gui/TerrainPainterWindow.ed.gui"); + if( isObject( %guiContent ) ){ + %this.add( %guiContent->TerrainPainter ); + %this.add( %guiContent->TerrainPainterPreview ); + } + + exec("~/worldEditor/gui/guiTerrainMaterialDlg.ed.gui"); + exec("~/worldEditor/gui/TerrainBrushSoftnessCurveDlg.ed.gui"); + } + if ( !isObject( %this-->TerrainPainterToolbar) ) + { + // Load Terrain Edit GUI + exec("~/worldEditor/gui/TerrainPainterToolbar.ed.gui"); + if( isObject( EWTerrainPainterToolbar ) ) + { + %this.add( EWTerrainPainterToolbar ); + EWTerrainPainterToolbar.setVisible( false ); + } + } + + if( !isObject( %this-->ToolsToolbar ) ) + { + // Load Creator/Inspector GUI + exec("~/worldEditor/gui/ToolsToolbar.ed.gui"); + if( isObject( EWToolsToolbar ) ) + { + %this.add( EWToolsToolbar ); + EWToolsToolbar.setVisible( true ); + + } + } + + // Visibility Layer Window + if( !isObject( %this-->VisibilityLayerWindow ) ) + { + %this.add( EVisibility ); + EVisibility.setVisible(false); + EVisibilityTabBook.selectPage(0); + } + + // Editor Settings Window + if( !isObject( %this-->EditorSettingsWindow ) ) + { + exec("~/worldEditor/gui/EditorSettingsWindow.ed.gui"); + exec("~/worldEditor/scripts/editorSettingsWindow.ed.cs"); + %this.add( ESettingsWindow ); + ESettingsWindow.setVisible(false); + + // Start the standard settings tabs pages + exec( "~/worldEditor/gui/GeneralSettingsTab.ed.gui" ); + ESettingsWindow.addTabPage( EGeneralSettingsPage ); + exec("~/worldEditor/gui/ObjectEditorSettingsTab.ed.gui"); + ESettingsWindow.addTabPage( EObjectEditorSettingsPage ); + exec("~/worldEditor/gui/AxisGizmoSettingsTab.ed.gui"); + ESettingsWindow.addTabPage( EAxisGizmoSettingsPage ); + exec("~/worldEditor/gui/TerrainEditorSettingsTab.ed.gui"); + ESettingsWindow.addTabPage( ETerrainEditorSettingsPage ); + exec("~/worldEditor/gui/CameraSettingsTab.ed.gui"); + ESettingsWindow.addTabPage( ECameraSettingsPage ); + } + + // Object Snap Options Window + if( !isObject( %this-->SnapOptionsWindow ) ) + { + exec("~/worldEditor/gui/ObjectSnapOptionsWindow.ed.gui"); + exec("~/worldEditor/scripts/objectSnapOptions.ed.cs"); + %this.add( ESnapOptions ); + ESnapOptions.setVisible(false); + ESnapOptionsTabBook.selectPage(0); + } + + // Transform Selection Window + if( !isObject( %this-->TransformSelectionWindow ) ) + { + exec("~/worldEditor/gui/TransformSelectionWindow.ed.gui"); + exec("~/worldEditor/scripts/transformSelection.ed.cs"); + %this.add( ETransformSelection ); + ETransformSelection.setVisible(false); + } + + // Manage Bookmarks Window + if( !isObject( %this-->ManageBookmarksWindow ) ) + { + %this.add( EManageBookmarks ); + EManageBookmarks.setVisible(false); + } + + // Manage SFXParameters Window + if( !isObject( %this-->ManageSFXParametersWindow ) ) + { + %this.add( EManageSFXParameters ); + EManageSFXParameters.setVisible( false ); + } + + // Select Objects Window + if( !isObject( %this->SelectObjectsWindow ) ) + { + %this.add( ESelectObjectsWindow ); + ESelectObjectsWindow.setVisible( false ); + } + + EWorldEditor.init(); + ETerrainEditor.init(); + + //Creator.init(); + EWCreatorWindow.init(); + ObjectBuilderGui.init(); + + %this.setMenuDefaultState(); + + EWorldEditorToggleCamera.setBitmap("tools/worldEditor/images/toolbar/player"); + + /* + EWorldEditorCameraSpeed.clear(); + EWorldEditorCameraSpeed.add("Slowest - Camera 1",0); + EWorldEditorCameraSpeed.add("Slow - Camera 2",1); + EWorldEditorCameraSpeed.add("Slower - Camera 3",2); + EWorldEditorCameraSpeed.add("Normal - Camera 4",3); + EWorldEditorCameraSpeed.add("Faster - Camera 5",4); + EWorldEditorCameraSpeed.add("Fast - Camera 6",5); + EWorldEditorCameraSpeed.add("Fastest - Camera 7",6); + EWorldEditorCameraSpeed.setSelected(3); + */ + + EWorldEditorAlignPopup.clear(); + EWorldEditorAlignPopup.add("World",0); + EWorldEditorAlignPopup.add("Object",1); + EWorldEditorAlignPopup.setSelected(0); + + + // sync camera gui + EditorGui.syncCameraGui(); + + // this will brind CameraTypesDropdown to front so that it goes over the menubar + EditorGui.pushToBack(CameraTypesDropdown); + EditorGui.pushToBack(VisibilityDropdown); + + // dropdowns out so that they display correctly in editor gui + objectTransformDropdown.parentGroup = editorGui; + objectCenterDropdown.parentGroup = editorGui; + objectSnapDropdown.parentGroup = editorGui; + + // make sure to show the default world editor guis + EditorGui.bringToFront( EWorldEditor ); + EWorldEditor.setVisible( false ); + + // Call the startup callback on the editor plugins. + for ( %i = 0; %i < EditorPluginSet.getCount(); %i++ ) + { + %obj = EditorPluginSet.getObject( %i ); + %obj.onWorldEditorStartup(); + } + + // With everything loaded, start up the settings window + ESettingsWindow.startup(); + + // Start up initial editor plugin. + + %initialEditor = %this.currentEditor; // Read from prefs. + %this.currentEditor = ""; + + if( %initialEditor $= "" ) + %initialEditor = "WorldEditorInspectorPlugin"; + %this.setEditor( %initialEditor, true, true ); + + // Done. + + %this.isInitialized = true; +} + +//------------------------------------------------------------------------------ +// Editor Gui's interactions with Camera Settings + +function EditorGui::setupDefaultCameraSettings( %this ) +{ + EditorSettings.beginGroup( "LevelInformation/levels/" @ %this.levelName ); + + EditorSettings.setDefaultValue( "cameraSpeedMin", "5" ); + EditorSettings.setDefaultValue( "cameraSpeedMax", "200" ); + + EditorSettings.endGroup(); +} + +function EditorGui::readCameraSettings( %this, %levelName ) +{ + if( %levelName !$= %this.levelName ) + return; + + EditorCameraSpeedOptions.setupGuiControls(); +} + +function EditorGui::writeCameraSettings( %this ) +{ + EditorSettings.beginGroup( "LevelInformation/levels/" @ %this.levelName ); + + EditorSettings.setValue( "cameraSpeed", $Camera::movementSpeed ); + + EditorSettings.endGroup(); +} + +//------------------------------------------------------------------------------ + +function EditorGui::shutdown( %this ) +{ + // Store settings. + %this.writeWorldEditorSettings(); + + // Deactivate current editor. + %this.setEditor( "" ); + + // Call the shutdown callback on the editor plugins. + foreach( %plugin in EditorPluginSet ) + %plugin.onWorldEditorShutdown(); +} + +/// This is used to add an editor to the Editors menu which +/// will take over the default world editor window. +function EditorGui::addToEditorsMenu( %this, %displayName, %accel, %newPlugin ) +{ + %windowMenu = %this.findMenu( "Editors" ); + %count = %windowMenu.getItemCount(); + + + %alreadyExists = false; + for ( %i = 0; %i < %count; %i++ ) + { + %existingPlugins = getField(%windowMenu.Item[%i], 2); + + if(%newPlugin $= %existingPlugins) + %alreadyExists = true; + } + + if( %accel $= "" && %count < 9 ) + %accel = "F" @ %count + 1; + else + %accel = ""; + + if(!%alreadyExists) + %windowMenu.addItem( %count, %displayName TAB %accel TAB %newPlugin ); + + return %accel; +} + +function EditorGui::addToToolsToolbar( %this, %pluginName, %internalName, %bitmap, %tooltip ) +{ + %count = ToolsToolbarArray.getCount(); + + %alreadyExists = false; + for ( %i = 0; %i < %count; %i++ ) + { + %existingInternalName = ToolsToolbarArray.getObject(%i).getFieldValue("internalName"); + + if(%internalName $= %existingInternalName) + { + %alreadyExists = true; + break; + } + } + + if(!%alreadyExists) + { + %button = new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = %internalName; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "180 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "EditorGui.setEditor(" @ %pluginName @ ");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = %tooltip; + hovertime = "750"; + bitmap = %bitmap; + buttonType = "RadioButton"; + groupNum = "0"; + useMouseEvents = "0"; + }; + ToolsToolbarArray.add(%button); + } +} + +//----------------------------------------------------------------------------- + +function EditorGui::setDisplayType( %this, %type ) +{ + %gui = %this.currentEditor.editorGui; + if( !isObject( %gui ) ) + return; + + %this.viewTypeMenu.checkRadioItem( 0, 7, %type ); + + // Store the current camera rotation so we can restore it correctly when + // switching back to perspective view + if ( %gui.getDisplayType() == $EditTSCtrl::DisplayTypePerspective ) + %this.lastPerspectiveCamRotation = LocalClientConnection.camera.getRotation(); + + %gui.setDisplayType( %type ); + + if ( %gui.getDisplayType() == $EditTSCtrl::DisplayTypePerspective ) + LocalClientConnection.camera.setRotation( %this.lastPerspectiveCamRotation ); + + %this.currentDisplayType = %type; +} + +//----------------------------------------------------------------------------- + +function EditorGui::setEditor( %this, %newEditor, %dontActivate ) +{ + if ( isObject( %this.currentEditor ) ) + { + if( isObject( %newEditor ) && %this.currentEditor.getId() == %newEditor.getId() ) + return; + + if( %this.currentEditor.isActivated ) + %this.currentEditor.onDeactivated(); + + if( isObject( %this.currentEditor.editorGui ) ) + %this.currentOrthoFOV = %this.currentEditor.editorGui.getOrthoFOV(); + } + + if( !isObject( %newEditor ) ) + { + %this.currentEditor = ""; + return; + } + + // If we have a special set editor function, run that instead + if( %newEditor.isMethod( "setEditorFunction" ) ) + { + if( %newEditor.setEditorFunction() ) + { + %this.syncEditor( %newEditor ); + %this.currentEditor = %newEditor; + + if (!%dontActivate) + %this.currentEditor.onActivated(); + } + else + { + // if were falling back and were the same editor, why are we going to just shove ourself + // into the editor position again? opt for a fallback + if( !isObject( %this.currentEditor ) ) + %this.currentEditor = "WorldEditorInspectorPlugin"; + else if( %this.currentEditor.getId() == %newEditor.getId() ) + %this.currentEditor = "WorldEditorInspectorPlugin"; + + %this.syncEditor( %this.currentEditor, true ); + + if( !%dontActivate ) + %this.currentEditor.onActivated(); + } + } + else + { + %this.syncEditor( %newEditor ); + %this.currentEditor = %newEditor; + + if( !%dontActivate ) + %this.currentEditor.onActivated(); + } + + // Sync display type. + + %gui = %this.currentEditor.editorGui; + if( isObject( %gui ) ) + { + %gui.setDisplayType( %this.currentDisplayType ); + %gui.setOrthoFOV( %this.currentOrthoFOV ); + EditorGui.syncCameraGui(); + } +} + +function EditorGui::syncEditor( %this, %newEditor, %newEditorFailed ) +{ + // Sync with menu bar + %menu = %this.findMenu( "Editors" ); + %count = %menu.getItemCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %pluginObj = getField( %menu.item[%i], 2 ); + if ( %pluginObj $= %newEditor ) + { + %menu.checkRadioItem( 0, %count, %i ); + break; + } + } + + // In order to hook up a palette, the word Palette must be able to be + // switched out in order to read correctly, if not, no palette will be used + %paletteName = strreplace(%newEditor, "Plugin", "Palette"); + + // Sync with ToolsToolbar + for ( %i = 0; %i < ToolsToolbarArray.getCount(); %i++ ) + { + %toolbarButton = ToolsToolbarArray.getObject(%i).internalName; + if( %paletteName $= %toolbarButton ) + { + ToolsToolbarArray.getObject(%i).setStateOn(1); + break; + } + } + + // Handles quit game and gui editor changes in wierd scenarios + if( %newEditorFailed && EWToolsToolbar.isDynamic ) + { + if( EWToolsToolbar.isClosed ) + EWToolsToolbar.reset(); + EWToolsToolbar.toggleSize(); + } + + // Toggle the editor specific palette; we define special cases here + switch$ ( %paletteName ) + { + case "MaterialEditorPalette": + %paletteName = "WorldEditorInspectorPalette"; + case "DatablockEditorPalette": + %paletteName = "WorldEditorInspectorPalette"; + case "ParticleEditorPalette": + %paletteName = "WorldEditorInspectorPalette"; + } + + %this-->ToolsPaletteWindow.togglePalette(%paletteName); +} + +function EditorGui::onWake( %this ) +{ + EHWorldEditor.setStateOn( 1 ); + + // Notify the editor plugins that the editor has started. + + foreach( %plugin in EditorPluginSet ) + %plugin.onEditorWake(); + + // Push the ActionMaps in the order that we want to have them + // before activating an editor plugin, so that if the plugin + // installs an ActionMap, it will be highest on the stack. + + MoveMap.push(); + EditorMap.push(); + + // Active the current editor plugin. + + if( !%this.currentEditor.isActivated ) + %this.currentEditor.onActivated(); + + %slashPos = 0; + while( strpos( $Server::MissionFile, "/", %slashPos ) != -1 ) + { + %slashPos = strpos( $Server::MissionFile, "/", %slashPos ) + 1; + } + %levelName = getSubStr( $Server::MissionFile , %slashPos , 99 ); + + if( %levelName !$= %this.levelName ) + %this.onNewLevelLoaded( %levelName ); + + if (isObject(DemoEditorAlert) && DemoEditorAlert.helpTag<2) + Canvas.pushDialog(DemoEditorAlert); +} + +function EditorGui::onSleep( %this ) +{ + // Deactivate the current editor plugin. + + if( %this.currentEditor.isActivated ) + %this.currentEditor.onDeactivated(); + + // Remove the editor's ActionMaps. + + EditorMap.pop(); + MoveMap.pop(); + + // Notify the editor plugins that the editor will be closing. + + foreach( %plugin in EditorPluginSet ) + %plugin.onEditorSleep(); + + if(isObject($Server::CurrentScene)) + $Server::CurrentScene.open(); +} + +function EditorGui::onNewLevelLoaded( %this, %levelName ) +{ + %this.levelName = %levelName; + %this.setupDefaultCameraSettings(); + ECameraSettingsPage.init(); + EditorCameraSpeedOptions.setupDefaultState(); + + new ScriptObject( EditorMissionCleanup ) + { + parentGroup = "MissionCleanup"; + }; +} + +function EditorMissionCleanup::onRemove( %this ) +{ + EditorGui.levelName = ""; + foreach( %plugin in EditorPluginSet ) + %plugin.onExitMission(); +} + +//----------------------------------------------------------------------------- + +// Called when we have been set as the content and onWake has been called +function EditorGui::onSetContent(%this, %oldContent) +{ + %this.attachMenus(); +} + +// Called before onSleep when the canvas content is changed +function EditorGui::onUnsetContent(%this, %newContent) +{ + %this.detachMenus(); +} + +//------------------------------------------------------------------------------ + +function EditorGui::toggleSFXParametersWindow( %this ) +{ + %window = %this-->ManageSFXParametersWindow; + %window.setVisible( !%window.isVisible() ); +} + +//------------------------------------------------------------------------------ + +function EditorGui::addCameraBookmark( %this, %name ) +{ + %obj = new CameraBookmark() { + datablock = CameraBookmarkMarker; + internalName = %name; + }; + + // Place into correct group + if( !isObject(CameraBookmarks) ) + { + %grp = new SimGroup(CameraBookmarks); + MissionGroup.add(%grp); + } + CameraBookmarks.add( %obj ); + + %cam = LocalClientConnection.camera.getTransform(); + %obj.setTransform( %cam ); + + EWorldEditor.isDirty = true; + EditorTree.buildVisibleTree(true); +} + +function EditorGui::removeCameraBookmark( %this, %name ) +{ + if( !isObject(CameraBookmarks) ) + return; + + %mark = CameraBookmarks.findObjectByInternalName( %name, true ); + if( %mark == 0 ) + return; + + MEDeleteUndoAction::submit( %mark ); + EWorldEditor.isDirty = true; + EditorTree.buildVisibleTree(true); +} + +function EditorGui::removeCameraBookmarkIndex( %this, %index ) +{ + if( !isObject(CameraBookmarks) ) + return; + + if( %index < 0 || %index >= CameraBookmarks.getCount() ) + return; + + %obj = CameraBookmarks.getObject( %index ); + MEDeleteUndoAction::submit( %obj ); + EWorldEditor.isDirty = true; + EditorTree.buildVisibleTree(true); +} + +function EditorGui::jumpToBookmark( %this, %name ) +{ + if( !isObject(CameraBookmarks) ) + return; + + %mark = CameraBookmarks.findObjectByInternalName( %name, true ); + if( %mark == 0 ) + return; + + LocalClientConnection.camera.setTransform( %mark.getTransform() ); + return; +} + +function EditorGui::jumpToBookmarkIndex( %this, %index ) +{ + if( !isObject(CameraBookmarks) ) + return; + + if( %index < 0 || %index >= CameraBookmarks.getCount() ) + return; + + %trans = CameraBookmarks.getObject( %index ).getTransform(); + LocalClientConnection.camera.setTransform( %trans ); +} + +function EditorGui::addCameraBookmarkByGui( %this ) +{ + // look for a NewCamera name to grab + for(%i = 0; ; %i++){ + %name = "NewCamera_" @ %i; + if( !CameraBookmarks.findObjectByInternalName(%name) ){ + break; + } + } + EditorGui.addCameraBookmark( %name ); +} + +function EditorGui::toggleCameraBookmarkWindow( %this ) +{ + EManageBookmarks.ToggleVisibility(); +} + +function EditorGui::toggleObjectSelectionsWindow( %this ) +{ + ESelectObjectsWindow.toggleVisibility(); +} + +function EditorGui::toggleOrthoGrid( %this ) +{ + EWorldEditor.renderOrthoGrid = !EWorldEditor.renderOrthoGrid; +} + +//------------------------------------------------------------------------------ + +function EditorGui::syncCameraGui( %this ) +{ + if( !EditorIsActive() ) + return; + + // Sync projection type + %displayType = %this.currentEditor.editorGui.getDisplayType(); + %this.viewTypeMenu.checkRadioItem( 0, 7, %displayType ); + + // Set the camera object's mode and rotation so that it moves correctly + // based on the current editor mode + if( %displayType != $EditTSCtrl::DisplayTypePerspective ) + { + switch( %displayType ) + { + case $EditTSCtrl::DisplayTypeTop: %name = "Top View"; %camRot = "0 0 0"; + case $EditTSCtrl::DisplayTypeBottom: %name = "Bottom View"; %camRot = "3.14159 0 0"; + case $EditTSCtrl::DisplayTypeLeft: %name = "Left View"; %camRot = "-1.571 0 1.571"; + case $EditTSCtrl::DisplayTypeRight: %name = "Right View"; %camRot = "-1.571 0 -1.571"; + case $EditTSCtrl::DisplayTypeFront: %name = "Front View"; %camRot = "-1.571 0 3.14159"; + case $EditTSCtrl::DisplayTypeBack: %name = "Back View"; %camRot = "-1.571 0 0"; + case $EditTSCtrl::DisplayTypeIsometric: %name = "Isometric View"; %camRot = "0 0 0"; + } + + LocalClientConnection.camera.controlMode = "Fly"; + LocalClientConnection.camera.setRotation( %camRot ); + EditorGuiStatusBar.setCamera( %name ); + return; + } + + // Sync camera settings. + %flyModeRadioItem = -1; + if(LocalClientConnection.getControlObject() != LocalClientConnection.player) + { + %mode = LocalClientConnection.camera.getMode(); + + if(%mode $= "Fly" && LocalClientConnection.camera.newtonMode) + { + if(LocalClientConnection.camera.newtonRotation == true) + { + EditorGui-->NewtonianRotationCamera.setStateOn(true); + EWorldEditorToggleCamera.setBitmap("tools/gui/images/menubar/smooth-cam-rot"); + %flyModeRadioItem = 4; + EditorGuiStatusBar.setCamera("Smooth Rot Camera"); + } + else + { + EditorGui-->NewtonianCamera.setStateOn(true); + EWorldEditorToggleCamera.setBitmap("tools/gui/images/menubar/smooth-cam"); + %flyModeRadioItem = 3; + EditorGuiStatusBar.setCamera("Smooth Camera"); + } + } + else if(%mode $= "EditOrbit") + { + EditorGui-->OrbitCamera.setStateOn(true); + EWorldEditorToggleCamera.setBitmap("tools/gui/images/menubar/orbit-cam"); + %flyModeRadioItem = 1; + EditorGuiStatusBar.setCamera("Orbit Camera"); + } + else // default camera mode + { + EditorGui-->StandardCamera.setStateOn(true); + EWorldEditorToggleCamera.setBitmap("tools/worldEditor/images/toolbar/camera"); + %flyModeRadioItem = 0; + EditorGuiStatusBar.setCamera("Standard Camera"); + } + + //quick way select menu bar options + %this.findMenu( "Camera" ).checkRadioItem( 0, 1, 0 ); + EditorFreeCameraTypeOptions.checkRadioItem( 0, 4, %flyModeRadioItem); + EditorPlayerCameraTypeOptions.checkRadioItem( 0, 4, -1); + } + else if (!$isFirstPersonVar) // if 3rd person + { + EditorGui-->trdPersonCamera.setStateOn(true); + EWorldEditorToggleCamera.setBitmap("tools/worldEditor/images/toolbar/3rd-person-camera"); + %flyModeRadioItem = 1; + //quick way select menu bar options + %this.findMenu( "Camera" ).checkRadioItem( 0, 1, 1 ); + EditorPlayerCameraTypeOptions.checkRadioItem( 0, 2, %flyModeRadioItem); + EditorGuiStatusBar.setCamera("3rd Person Camera"); + } + else if ($isFirstPersonVar) // if 1st Person + { + EditorGui-->PlayerCamera.setStateOn(true); + EWorldEditorToggleCamera.setBitmap("tools/worldEditor/images/toolbar/player"); + %flyModeRadioItem = 0; + //quick way select menu bar options + %this.findMenu( "Camera" ).checkRadioItem( 0, 1, 1 ); + EditorPlayerCameraTypeOptions.checkRadioItem( 0, 2, %flyModeRadioItem); + EditorFreeCameraTypeOptions.checkRadioItem( 0, 4, -1); + EditorGuiStatusBar.setCamera("1st Person Camera"); + } + } + +/// @name EditorPlugin Methods +/// @{ + +//------------------------------------------------------------------------------ +// WorldEditorPlugin +//------------------------------------------------------------------------------ + +function WorldEditorPlugin::onActivated( %this ) +{ + EditorGui.bringToFront( EWorldEditor ); + EWorldEditor.setVisible(true); + EditorGui.menuBar.insert( EditorGui.worldMenu, EditorGui.menuBar.dynamicItemInsertPos ); + EWorldEditor.makeFirstResponder(true); + EditorTree.open(MissionGroup,true); + EWCreatorWindow.setNewObjectGroup(MissionGroup); + + EWorldEditor.syncGui(); + + EditorGuiStatusBar.setSelectionObjectsByCount(EWorldEditor.getSelectionSize()); + + // Should the Transform Selection window open? + if( EWorldEditor.ETransformSelectionDisplayed ) + { + ETransformSelection.setVisible(true); + } + + Parent::onActivated(%this); +} + +function WorldEditorPlugin::onDeactivated( %this ) +{ + // Hide the Transform Selection window from other editors + ETransformSelection.setVisible(false); + + EWorldEditor.setVisible( false ); + EditorGui.menuBar.remove( EditorGui.worldMenu ); + + Parent::onDeactivated(%this); +} + +//------------------------------------------------------------------------------ +// WorldEditorInspectorPlugin +//------------------------------------------------------------------------------ + +function WorldEditorInspectorPlugin::onWorldEditorStartup( %this ) +{ + Parent::onWorldEditorStartup( %this ); + + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Object Editor", "", WorldEditorInspectorPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "Object Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "WorldEditorInspectorPlugin", "WorldEditorInspectorPalette", expandFilename("tools/worldEditor/images/toolbar/transform-objects"), %tooltip ); + + //connect editor windows + GuiWindowCtrl::attach( EWInspectorWindow, EWTreeWindow); + + %map = new ActionMap(); + %map.bindCmd( keyboard, "1", "EWorldEditorNoneModeBtn.performClick();", "" ); // Select + %map.bindCmd( keyboard, "2", "EWorldEditorMoveModeBtn.performClick();", "" ); // Move + %map.bindCmd( keyboard, "3", "EWorldEditorRotateModeBtn.performClick();", "" ); // Rotate + %map.bindCmd( keyboard, "4", "EWorldEditorScaleModeBtn.performClick();", "" ); // Scale + %map.bindCmd( keyboard, "f", "FitToSelectionBtn.performClick();", "" );// Fit Camera to Selection + %map.bindCmd( keyboard, "z", "EditorGuiStatusBar.setCamera(\"Standard Camera\");", "" );// Free camera + %map.bindCmd( keyboard, "n", "ToggleNodeBar->renderHandleBtn.performClick();", "" );// Render Node + %map.bindCmd( keyboard, "shift n", "ToggleNodeBar->renderTextBtn.performClick();", "" );// Render Node Text + %map.bindCmd( keyboard, "g", "ESnapOptions-->GridSnapButton.performClick();" ); // Grid Snappping + %map.bindCmd( keyboard, "t", "SnapToBar->objectSnapDownBtn.performClick();", "" );// Terrain Snapping + %map.bindCmd( keyboard, "b", "SnapToBar-->objectSnapBtn.performClick();" ); // Soft Snappping + %map.bindCmd( keyboard, "v", "EWorldEditorToolbar->boundingBoxColBtn.performClick();", "" );// Bounds Selection + %map.bindCmd( keyboard, "o", "objectCenterDropdown->objectBoxBtn.performClick(); objectCenterDropdown.toggle();", "" );// Object Center + %map.bindCmd( keyboard, "p", "objectCenterDropdown->objectBoundsBtn.performClick(); objectCenterDropdown.toggle();", "" );// Bounds Center + %map.bindCmd( keyboard, "k", "objectTransformDropdown->objectTransformBtn.performClick(); objectTransformDropdown.toggle();", "" );// Object Transform + %map.bindCmd( keyboard, "l", "objectTransformDropdown->worldTransformBtn.performClick(); objectTransformDropdown.toggle();", "" );// World Transform + + WorldEditorInspectorPlugin.map = %map; +} + +function WorldEditorInspectorPlugin::onActivated( %this ) +{ + Parent::onActivated( %this ); + + EditorGui-->InspectorWindow.setVisible( true ); + EditorGui-->TreeWindow.setVisible( true ); + EditorGui-->WorldEditorToolbar.setVisible( true ); + %this.map.push(); +} + +function WorldEditorInspectorPlugin::onDeactivated( %this ) +{ + Parent::onDeactivated( %this ); + + EditorGui-->InspectorWindow.setVisible( false ); + EditorGui-->TreeWindow.setVisible( false ); + EditorGui-->WorldEditorToolbar.setVisible( false ); + %this.map.pop(); +} + +function WorldEditorInspectorPlugin::onEditMenuSelect( %this, %editMenu ) +{ + %canCutCopy = EWorldEditor.getSelectionSize() > 0; + %editMenu.enableItem( 3, %canCutCopy ); // Cut + %editMenu.enableItem( 4, %canCutCopy ); // Copy + %editMenu.enableItem( 5, EWorldEditor.canPasteSelection() ); // Paste + + %selSize = EWorldEditor.getSelectionSize(); + %lockCount = EWorldEditor.getSelectionLockCount(); + %hideCount = EWorldEditor.getSelectionHiddenCount(); + %editMenu.enableItem( 6, %selSize > 0 && %lockCount != %selSize ); // Delete Selection + + %editMenu.enableItem( 8, %canCutCopy ); // Deselect +} + +function WorldEditorInspectorPlugin::handleDelete( %this ) +{ + // The tree handles deletion and notifies the + // world editor to clear its selection. + // + // This is because non-SceneObject elements like + // SimGroups also need to be destroyed. + // + // See EditorTree::onObjectDeleteCompleted(). + %selSize = EWorldEditor.getSelectionSize(); + if( %selSize > 0 ) + EditorTree.deleteSelection(); +} + +function WorldEditorInspectorPlugin::handleDeselect() +{ + EWorldEditor.clearSelection(); +} + +function WorldEditorInspectorPlugin::handleCut() +{ + EWorldEditor.cutSelection(); +} + +function WorldEditorInspectorPlugin::handleCopy() +{ + EWorldEditor.copySelection(); +} + +function WorldEditorInspectorPlugin::handlePaste() +{ + EWorldEditor.pasteSelection(); +} + +//------------------------------------------------------------------------------ +// TerrainEditorPlugin +//------------------------------------------------------------------------------ + +function TerrainEditorPlugin::onWorldEditorStartup( %this ) +{ + Parent::onWorldEditorStartup( %this ); + + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Terrain Editor", "", TerrainEditorPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "Terrain Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "TerrainEditorPlugin", "TerrainEditorPalette", expandFilename("tools/worldEditor/images/toolbar/sculpt-terrain"), %tooltip ); + + %map = new ActionMap(); + %map.bindCmd( keyboard, "1", "ToolsPaletteArray->brushAdjustHeight.performClick();", "" ); //Grab Terrain + %map.bindCmd( keyboard, "2", "ToolsPaletteArray->raiseHeight.performClick();", "" ); // Raise Height + %map.bindCmd( keyboard, "3", "ToolsPaletteArray->lowerHeight.performClick();", "" ); // Lower Height + %map.bindCmd( keyboard, "4", "ToolsPaletteArray->smoothHeight.performClick();", "" ); // Smooth + %map.bindCmd( keyboard, "5", "ToolsPaletteArray->paintNoise.performClick();", "" ); // Noise + %map.bindCmd( keyboard, "6", "ToolsPaletteArray->flattenHeight.performClick();", "" ); // Flatten + %map.bindCmd( keyboard, "7", "ToolsPaletteArray->setHeight.performClick();", "" ); // Set Height + %map.bindCmd( keyboard, "8", "ToolsPaletteArray->setEmpty.performClick();", "" ); // Clear Terrain + %map.bindCmd( keyboard, "9", "ToolsPaletteArray->clearEmpty.performClick();", "" ); // Restore Terrain + %map.bindCmd( keyboard, "v", "EWTerrainEditToolbarBrushType->ellipse.performClick();", "" );// Circle Brush + %map.bindCmd( keyboard, "b", "EWTerrainEditToolbarBrushType->box.performClick();", "" );// Box Brush + %map.bindCmd( keyboard, "=", "TerrainEditorPlugin.keyboardModifyBrushSize(1);", "" );// +1 Brush Size + %map.bindCmd( keyboard, "+", "TerrainEditorPlugin.keyboardModifyBrushSize(1);", "" );// +1 Brush Size + %map.bindCmd( keyboard, "-", "TerrainEditorPlugin.keyboardModifyBrushSize(-1);", "" );// -1 Brush Size + %map.bindCmd( keyboard, "[", "TerrainEditorPlugin.keyboardModifyBrushSize(-5);", "" );// -5 Brush Size + %map.bindCmd( keyboard, "]", "TerrainEditorPlugin.keyboardModifyBrushSize(5);", "" );// +5 Brush Size + /*%map.bindCmd( keyboard, "]", "TerrainBrushPressureTextEditContainer->textEdit.text += 5", "" );// +5 Pressure + %map.bindCmd( keyboard, "[", "TerrainBrushPressureTextEditContainer->textEdit.text -= 5", "" );// -5 Pressure + %map.bindCmd( keyboard, "'", "TerrainBrushSoftnessTextEditContainer->textEdit.text += 5", "" );// +5 Softness + %map.bindCmd( keyboard, ";", "TerrainBrushSoftnessTextEditContainer->textEdit.text -= 5", "" );// -5 Softness*/ + + TerrainEditorPlugin.map = %map; + + %this.terrainMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + + barTitle = "Terrain"; + + item[0] = "Smooth Heightmap" TAB "" TAB "ETerrainEditor.onSmoothHeightmap();"; + }; +} + +function TerrainEditorPlugin::onActivated( %this ) +{ + Parent::onActivated( %this ); + + EditorGui.readTerrainEditorSettings(); + + %action = EditorSettings.value("TerrainEditor/currentAction"); + ETerrainEditor.switchAction( %action ); + ToolsPaletteArray.findObjectByInternalName( %action, true ).setStateOn( true ); + + EWTerrainEditToolbarBrushType->ellipse.performClick(); // Circle Brush + + EditorGui.menuBar.insert( %this.terrainMenu, EditorGui.menuBar.dynamicItemInsertPos ); + + EditorGui.bringToFront( ETerrainEditor ); + ETerrainEditor.setVisible( true ); + ETerrainEditor.attachTerrain(); + ETerrainEditor.makeFirstResponder( true ); + + EWTerrainEditToolbar.setVisible( true ); + ETerrainEditor.onBrushChanged(); + ETerrainEditor.setup(); + TerrainEditorPlugin.syncBrushInfo(); + + EditorGuiStatusBar.setSelection(""); + %this.map.push(); +} + +function TerrainEditorPlugin::onDeactivated( %this ) +{ + Parent::onDeactivated( %this ); + + endToolTime("TerrainEditor"); + EditorGui.writeTerrainEditorSettings(); + + EWTerrainEditToolbar.setVisible( false ); + ETerrainEditor.setVisible( false ); + + EditorGui.menuBar.remove( %this.terrainMenu ); + + %this.map.pop(); +} + +function TerrainEditorPlugin::syncBrushInfo( %this ) +{ + // Update gui brush info + TerrainBrushSizeTextEditContainer-->textEdit.text = getWord(ETerrainEditor.getBrushSize(), 0); + TerrainBrushPressureTextEditContainer-->textEdit.text = ETerrainEditor.getBrushPressure()*100; + TerrainBrushSoftnessTextEditContainer-->textEdit.text = ETerrainEditor.getBrushSoftness()*100; + TerrainSetHeightTextEditContainer-->textEdit.text = ETerrainEditor.setHeightVal; + + %brushType = ETerrainEditor.getBrushType(); + eval( "EWTerrainEditToolbar-->" @ %brushType @ ".setStateOn(1);" ); +} + +function TerrainEditorPlugin::validateBrushSize( %this ) +{ + %minBrushSize = 1; + %maxBrushSize = getWord(ETerrainEditor.maxBrushSize, 0); + + %val = $ThisControl.getText(); + if(%val < %minBrushSize) + $ThisControl.setValue(%minBrushSize); + else if(%val > %maxBrushSize) + $ThisControl.setValue(%maxBrushSize); +} + +function TerrainEditorPlugin::keyboardModifyBrushSize( %this, %amt) +{ + %val = TerrainBrushSizeTextEditContainer-->textEdit.getText(); + %val += %amt; + TerrainBrushSizeTextEditContainer-->textEdit.setValue(%val); + TerrainBrushSizeTextEditContainer-->textEdit.forceValidateText(); + ETerrainEditor.setBrushSize( TerrainBrushSizeTextEditContainer-->textEdit.getText() ); +} + +//------------------------------------------------------------------------------ +// TerrainTextureEditorTool +//------------------------------------------------------------------------------ + +function TerrainTextureEditorTool::onActivated( %this ) +{ + EditorGui.bringToFront( ETerrainEditor ); + ETerrainEditor.setVisible( true ); + ETerrainEditor.attachTerrain(); + ETerrainEditor.makeFirstResponder( true ); + + EditorGui-->TextureEditor.setVisible(true); + + EditorGuiStatusBar.setSelection(""); +} + +function TerrainTextureEditorTool::onDeactivated( %this ) +{ + EditorGui-->TextureEditor.setVisible(false); + + ETerrainEditor.setVisible( false ); +} + +//------------------------------------------------------------------------------ +// TerrainPainterPlugin +//------------------------------------------------------------------------------ + +function TerrainPainterPlugin::onWorldEditorStartup( %this ) +{ + Parent::onWorldEditorStartup( %this ); + + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Terrain Painter", "", TerrainPainterPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "Terrain Painter (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "TerrainPainterPlugin", "TerrainPainterPalette", expandFilename("tools/worldEditor/images/toolbar/paint-terrain"), %tooltip ); + + %map = new ActionMap(); + %map.bindCmd( keyboard, "v", "EWTerrainPainterToolbarBrushType->ellipse.performClick();", "" );// Circle Brush + %map.bindCmd( keyboard, "b", "EWTerrainPainterToolbarBrushType->box.performClick();", "" );// Box Brush + %map.bindCmd( keyboard, "=", "TerrainPainterPlugin.keyboardModifyBrushSize(1);", "" );// +1 Brush Size + %map.bindCmd( keyboard, "+", "TerrainPainterPlugin.keyboardModifyBrushSize(1);", "" );// +1 Brush Size + %map.bindCmd( keyboard, "-", "TerrainPainterPlugin.keyboardModifyBrushSize(-1);", "" );// -1 Brush Size + %map.bindCmd( keyboard, "[", "TerrainPainterPlugin.keyboardModifyBrushSize(-5);", "" );// -5 Brush Size + %map.bindCmd( keyboard, "]", "TerrainPainterPlugin.keyboardModifyBrushSize(5);", "" );// +5 Brush Size + /*%map.bindCmd( keyboard, "]", "PaintBrushSlopeControl->SlopeMinAngle.text += 5", "" );// +5 SlopeMinAngle + %map.bindCmd( keyboard, "[", "PaintBrushSlopeControl->SlopeMinAngle.text -= 5", "" );// -5 SlopeMinAngle + %map.bindCmd( keyboard, "'", "PaintBrushSlopeControl->SlopeMaxAngle.text += 5", "" );// +5 SlopeMaxAngle + %map.bindCmd( keyboard, ";", "PaintBrushSlopeControl->SlopeMaxAngle.text -= 5", "" );// -5 Softness*/ + + for(%i=1; %i<10; %i++) + { + %map.bindCmd( keyboard, %i, "TerrainPainterPlugin.keyboardSetMaterial(" @ (%i-1) @ ");", "" ); + } + %map.bindCmd( keyboard, 0, "TerrainPainterPlugin.keyboardSetMaterial(10);", "" ); + + TerrainPainterPlugin.map = %map; + GuiWindowCtrl::attach( EPainter, EPainterPreview); +} + +function TerrainPainterPlugin::onActivated( %this ) +{ + Parent::onActivated( %this ); + + EditorGui.readTerrainEditorSettings(); + + EWTerrainPainterToolbarBrushType->ellipse.performClick();// Circle Brush + %this.map.push(); + + EditorGui.bringToFront( ETerrainEditor ); + ETerrainEditor.setVisible( true ); + ETerrainEditor.attachTerrain(); + ETerrainEditor.makeFirstResponder( true ); + + EditorGui-->TerrainPainter.setVisible(true); + EditorGui-->TerrainPainterPreview.setVisible(true); + EWTerrainPainterToolbar.setVisible(true); + ETerrainEditor.onBrushChanged(); + EPainter.setup(); + TerrainPainterPlugin.syncBrushInfo(); + + EditorGuiStatusBar.setSelection(""); +} + +function TerrainPainterPlugin::onDeactivated( %this ) +{ + Parent::onDeactivated( %this ); + + EditorGui.writeTerrainEditorSettings(); + + %this.map.pop(); + EditorGui-->TerrainPainter.setVisible(false); + EditorGui-->TerrainPainterPreview.setVisible(false); + EWTerrainPainterToolbar.setVisible(false); + ETerrainEditor.setVisible( false ); +} + +function TerrainPainterPlugin::syncBrushInfo( %this ) +{ + // Update gui brush info + PaintBrushSizeTextEditContainer-->textEdit.text = getWord(ETerrainEditor.getBrushSize(), 0); + PaintBrushSlopeControl-->SlopeMinAngle.text = ETerrainEditor.getSlopeLimitMinAngle(); + PaintBrushSlopeControl-->SlopeMaxAngle.text = ETerrainEditor.getSlopeLimitMaxAngle(); + PaintBrushPressureTextEditContainer-->textEdit.text = ETerrainEditor.getBrushPressure()*100; + %brushType = ETerrainEditor.getBrushType(); + eval( "EWTerrainPainterToolbar-->" @ %brushType @ ".setStateOn(1);" ); +} + +function TerrainPainterPlugin::validateBrushSize( %this ) +{ + %minBrushSize = 1; + %maxBrushSize = getWord(ETerrainEditor.maxBrushSize, 0); + + %val = $ThisControl.getText(); + if(%val < %minBrushSize) + $ThisControl.setValue(%minBrushSize); + else if(%val > %maxBrushSize) + $ThisControl.setValue(%maxBrushSize); +} + +function TerrainPainterPlugin::validateSlopeMaxAngle( %this ) +{ + %maxval = ETerrainEditor.getSlopeLimitMaxAngle(); + PaintBrushSlopeControl-->SlopeMaxAngle.setText(%maxval); +} + +function TerrainPainterPlugin::validateSlopeMinAngle( %this ) +{ + %minval = ETerrainEditor.getSlopeLimitMinAngle(); + PaintBrushSlopeControl-->SlopeMinAngle.setText(%minval); +} + +function TerrainPainterPlugin::keyboardModifyBrushSize( %this, %amt) +{ + %val = PaintBrushSizeTextEditContainer-->textEdit.getText(); + %val += %amt; + PaintBrushSizeTextEditContainer-->textEdit.setValue(%val); + PaintBrushSizeTextEditContainer-->textEdit.forceValidateText(); + ETerrainEditor.setBrushSize( PaintBrushSizeTextEditContainer-->textEdit.getText() ); +} + +function TerrainPainterPlugin::keyboardSetMaterial( %this, %mat) +{ + %name = "EPainterMaterialButton" @ %mat; + %ctrl = EPainter.findObjectByInternalName(%name, true); + if(%ctrl) + { + %ctrl.performClick(); + } +} + +/// @} End of EditorPlugin Methods + + +function objectTransformDropdown::toggle() +{ + if ( objectTransformDropdown.visible ) + { + EWorldEditorToolbar-->objectTransform.setStateOn(false); + objectTransformDropdownDecoy.setVisible(false); + objectTransformDropdownDecoy.setActive(false); + objectTransformDropdown.setVisible(false); + } + else + { + EWorldEditorToolbar-->objectTransform.setStateOn(true); + objectTransformDropdown.setVisible(true); + objectTransformDropdownDecoy.setActive(true); + objectTransformDropdownDecoy.setVisible(true); + } +} + +function CameraTypesDropdownToggle() +{ + if ( CameraTypesDropdown.visible ) + { + EWorldEditorToggleCamera.setStateOn(0); + CameraTypesDropdownDecoy.setVisible(false); + CameraTypesDropdownDecoy.setActive(false); + CameraTypesDropdown.setVisible(false); + } + else + { + CameraTypesDropdown.setVisible(true); + CameraTypesDropdownDecoy.setVisible(true); + CameraTypesDropdownDecoy.setActive(true); + EWorldEditorToggleCamera.setStateOn(1); + } +} + +function VisibilityDropdownToggle() +{ + if ( EVisibility.visible ) + { + EVisibility.setVisible(false); + visibilityToggleBtn.setStateOn(0); + } + else + { + EVisibility.setVisible(true); + visibilityToggleBtn.setStateOn(1); + } +} + +function CameraTypesDropdownDecoy::onMouseLeave() +{ + CameraTypesDropdownToggle(); +} + +//----------------------------------------------------------------------------- + +function EWorldEditor::getGridSnap( %this ) +{ + return %this.gridSnap; +} + +function EWorldEditor::setGridSnap( %this, %value ) +{ + %this.gridSnap = %value; + GlobalGizmoProfile.snapToGrid = %value; + %this.syncGui(); +} + +function EWorldEditor::getGridSize( %this ) +{ + return %this.gridSize; +} + +function EWorldEditor::setGridSize( %this, %value ) +{ + GlobalGizmoProfile.gridSize = %value SPC %value SPC %value; + %this.gridSize = %value; + + %this.syncGui(); +} + +//----------------------------------------------------------------------------- + +function EWorldEditor::areAllSelectedObjectsOfType( %this, %className ) +{ + %activeSelection = %this.getActiveSelection(); + if( !isObject( %activeSelection ) ) + return false; + + %count = %activeSelection.getCount(); + for( %i = 0; %i < %count; %i ++ ) + { + %obj = %activeSelection.getObject( %i ); + if( !%obj.isMemberOfClass( %className ) ) + return false; + } + + return true; +} + +//----------------------------------------------------------------------------- +function EWorldEditorToggleCamera::toggleBitmap(%this) +{ + %currentImage = %this.bitmap; + + if ( %currentImage $= "tools/worldEditor/images/toolbar/player" ) + %image = "tools/worldEditor/images/toolbar/camera"; + else + %image = "tools/worldEditor/images/toolbar/player"; + + %this.setBitmap( %image ); +} + +function EWorldEditorCameraSpeed::updateMenuBar(%this, %editorBarCtrl) +{ + // Update Toolbar TextEdit + if( %editorBarCtrl.getId() == CameraSpeedDropdownCtrlContainer-->slider.getId() ) + { + %value = %editorBarCtrl.getValue(); + EWorldEditorCameraSpeed.setText( %value ); + $Camera::movementSpeed = %value; + } + + // Update Toolbar Slider + if( %editorBarCtrl.getId() == EWorldEditorCameraSpeed.getId() ) + { + %value = %editorBarCtrl.getText(); + if ( %value !$= "" ) + { + if ( %value <= 0 ) // camera speed must be >= 0 + { + %value = 1; + %editorBarCtrl.setText( %value ); + } + CameraSpeedDropdownCtrlContainer-->slider.setValue( %value ); + $Camera::movementSpeed = %value; + } + } + + // Update Editor + EditorCameraSpeedOptions.checkRadioItem(0, 6, -1); +} + +//----------------------------------------------------------------------------- + +function EWorldEditorAlignPopup::onSelect(%this, %id, %text) +{ + if ( GlobalGizmoProfile.mode $= "Scale" && %text $= "World" ) + { + EWorldEditorAlignPopup.setSelected(1); + return; + } + + GlobalGizmoProfile.alignment = %text; +} + +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- + +function EWorldEditorNoneModeBtn::onClick(%this) +{ + GlobalGizmoProfile.mode = "None"; + + EditorGuiStatusBar.setInfo("Selection arrow."); +} + +function EWorldEditorMoveModeBtn::onClick(%this) +{ + GlobalGizmoProfile.mode = "Move"; + + %cmdCtrl = "CTRL"; + if( $platform $= "macos" ) + %cmdCtrl = "CMD"; + + EditorGuiStatusBar.setInfo( "Move selection. SHIFT while dragging duplicates objects. " @ %cmdCtrl @ " to toggle soft snap. ALT to toggle grid snap." ); +} + +function EWorldEditorRotateModeBtn::onClick(%this) +{ + GlobalGizmoProfile.mode = "Rotate"; + + EditorGuiStatusBar.setInfo("Rotate selection."); +} + +function EWorldEditorScaleModeBtn::onClick(%this) +{ + GlobalGizmoProfile.mode = "Scale"; + + EditorGuiStatusBar.setInfo("Scale selection."); +} + +//----------------------------------------------------------------------------- + +function EditorTree::onDeleteSelection( %this ) +{ + %this.undoDeleteList = ""; +} + +function EditorTree::onDeleteObject( %this, %object ) +{ + // Don't delete locked objects + if( %object.locked ) + return true; + + if( %object == EWCreatorWindow.objectGroup ) + EWCreatorWindow.setNewObjectGroup( MissionGroup ); + + // Append it to our list. + %this.undoDeleteList = %this.undoDeleteList TAB %object; + + // We're gonna delete this ourselves in the + // completion callback. + return true; +} + +function EditorTree::onObjectDeleteCompleted( %this ) +{ + // This can be called when a deletion is attempted but nothing was + // actually deleted ( cannot delete the root of the tree ) so only submit + // the undo if we really deleted something. + if ( %this.undoDeleteList !$= "" ) + MEDeleteUndoAction::submit( %this.undoDeleteList ); + + // Let the world editor know to + // clear its selection. + EWorldEditor.clearSelection(); + EWorldEditor.isDirty = true; +} + +function EditorTree::onClearSelected(%this) +{ + WorldEditor.clearSelection(); +} + +function EditorTree::onInspect(%this, %obj) +{ + Inspector.inspect(%obj); +} + +function EditorTree::toggleLock( %this ) +{ + if( EWTreeWindow-->LockSelection.command $= "EWorldEditor.lockSelection(true); EditorTree.toggleLock();" ) + { + EWTreeWindow-->LockSelection.command = "EWorldEditor.lockSelection(false); EditorTree.toggleLock();"; + EWTreeWindow-->DeleteSelection.command = ""; + } + else + { + EWTreeWindow-->LockSelection.command = "EWorldEditor.lockSelection(true); EditorTree.toggleLock();"; + EWTreeWindow-->DeleteSelection.command = "EditorMenuEditDelete();"; + } +} + +function EditorTree::onAddSelection(%this, %obj, %isLastSelection) +{ + EWorldEditor.selectObject( %obj ); + + %selSize = EWorldEditor.getSelectionSize(); + %lockCount = EWorldEditor.getSelectionLockCount(); + + if( %lockCount < %selSize ) + { + EWTreeWindow-->LockSelection.setStateOn(0); + EWTreeWindow-->LockSelection.command = "EWorldEditor.lockSelection(true); EditorTree.toggleLock();"; + } + else if ( %lockCount > 0 ) + { + EWTreeWindow-->LockSelection.setStateOn(1); + EWTreeWindow-->LockSelection.command = "EWorldEditor.lockSelection(false); EditorTree.toggleLock();"; + } + + if( %selSize > 0 && %lockCount == 0 ) + EWTreeWindow-->DeleteSelection.command = "EditorMenuEditDelete();"; + else + EWTreeWindow-->DeleteSelection.command = ""; + + if( %isLastSelection ) + Inspector.addInspect( %obj ); + else + Inspector.addInspect( %obj, false ); + +} +function EditorTree::onRemoveSelection(%this, %obj) +{ + EWorldEditor.unselectObject(%obj); + Inspector.removeInspect( %obj ); +} +function EditorTree::onSelect(%this, %obj) +{ +} + +function EditorTree::onUnselect(%this, %obj) +{ + EWorldEditor.unselectObject(%obj); +} + +function EditorTree::onDragDropped(%this) +{ + EWorldEditor.isDirty = true; +} + +function EditorTree::onAddGroupSelected(%this, %group) +{ + EWCreatorWindow.setNewObjectGroup(%group); +} + +function EditorTree::onRightMouseUp( %this, %itemId, %mouse, %obj ) +{ + %haveObjectEntries = false; + %haveLockAndHideEntries = true; + + // Handle multi-selection. + if( %this.getSelectedItemsCount() > 1 ) + { + %popup = ETMultiSelectionContextPopup; + if( !isObject( %popup ) ) + %popup = new PopupMenu( ETMultiSelectionContextPopup ) + { + superClass = "MenuBuilder"; + isPopup = "1"; + + item[ 0 ] = "Delete" TAB "" TAB "EditorMenuEditDelete();"; + item[ 1 ] = "Group" TAB "" TAB "EWorldEditor.addSimGroup( true );"; + }; + } + + // Open context menu if this is a CameraBookmark + else if( %obj.isMemberOfClass( "CameraBookmark" ) ) + { + %popup = ETCameraBookmarkContextPopup; + if( !isObject( %popup ) ) + %popup = new PopupMenu( ETCameraBookmarkContextPopup ) + { + superClass = "MenuBuilder"; + isPopup = "1"; + + item[ 0 ] = "Go To Bookmark" TAB "" TAB "EditorGui.jumpToBookmark( %this.bookmark.getInternalName() );"; + + bookmark = -1; + }; + + ETCameraBookmarkContextPopup.bookmark = %obj; + } + + // Open context menu if this is set CameraBookmarks group. + else if( %obj.name $= "CameraBookmarks" ) + { + %popup = ETCameraBookmarksGroupContextPopup; + if( !isObject( %popup ) ) + %popup = new PopupMenu( ETCameraBookmarksGroupContextPopup ) + { + superClass = "MenuBuilder"; + isPopup = "1"; + + item[ 0 ] = "Add Camera Bookmark" TAB "" TAB "EditorGui.addCameraBookmarkByGui();"; + }; + } + + // Open context menu if this is a SimGroup + else if( %obj.isMemberOfClass( "SimGroup" ) ) + { + %popup = ETSimGroupContextPopup; + if( !isObject( %popup ) ) + %popup = new PopupMenu( ETSimGroupContextPopup ) + { + superClass = "MenuBuilder"; + isPopup = "1"; + + item[ 0 ] = "Rename" TAB "" TAB "EditorTree.showItemRenameCtrl( EditorTree.findItemByObjectId( %this.object ) );"; + item[ 1 ] = "Delete" TAB "" TAB "EWorldEditor.deleteMissionObject( %this.object );"; + item[ 2 ] = "Inspect" TAB "" TAB "inspectObject( %this.object );"; + item[ 3 ] = "-"; + item[ 4 ] = "Toggle Lock Children" TAB "" TAB "EWorldEditor.toggleLockChildren( %this.object );"; + item[ 5 ] = "Toggle Hide Children" TAB "" TAB "EWorldEditor.toggleHideChildren( %this.object );"; + item[ 6 ] = "-"; + item[ 7 ] = "Group" TAB "" TAB "EWorldEditor.addSimGroup( true );"; + item[ 8 ] = "-"; + item[ 9 ] = "Add New Objects Here" TAB "" TAB "EWCreatorWindow.setNewObjectGroup( %this.object );"; + item[ 10 ] = "Add Children to Selection" TAB "" TAB "EWorldEditor.selectAllObjectsInSet( %this.object, false );"; + item[ 11 ] = "Remove Children from Selection" TAB "" TAB "EWorldEditor.selectAllObjectsInSet( %this.object, true );"; + + object = -1; + }; + + %popup.object = %obj; + + %hasChildren = %obj.getCount() > 0; + %popup.enableItem( 10, %hasChildren ); + %popup.enableItem( 11, %hasChildren ); + + %haveObjectEntries = true; + %haveLockAndHideEntries = false; + } + + // Open generic context menu. + else + { + %popup = ETContextPopup; + if( !isObject( %popup ) ) + %popup = new PopupMenu( ETContextPopup ) + { + superClass = "MenuBuilder"; + isPopup = "1"; + + item[ 0 ] = "Rename" TAB "" TAB "EditorTree.showItemRenameCtrl( EditorTree.findItemByObjectId( %this.object ) );"; + item[ 1 ] = "Delete" TAB "" TAB "EWorldEditor.deleteMissionObject( %this.object );"; + item[ 2 ] = "Inspect" TAB "" TAB "inspectObject( %this.object );"; + item[ 3 ] = "-"; + item[ 4 ] = "Locked" TAB "" TAB "%this.object.setLocked( !%this.object.locked ); EWorldEditor.syncGui();"; + item[ 5 ] = "Hidden" TAB "" TAB "EWorldEditor.hideObject( %this.object, !%this.object.hidden ); EWorldEditor.syncGui();"; + item[ 6 ] = "-"; + item[ 7 ] = "Group" TAB "" TAB "EWorldEditor.addSimGroup( true );"; + + object = -1; + }; + + // Specialized version for ConvexShapes. + if( %obj.isMemberOfClass( "ConvexShape" ) ) + { + %popup = ETConvexShapeContextPopup; + if( !isObject( %popup ) ) + %popup = new PopupMenu( ETConvexShapeContextPopup : ETContextPopup ) + { + superClass = "MenuBuilder"; + isPopup = "1"; + + item[ 8 ] = "-"; + item[ 9 ] = "Convert to Zone" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"Zone\" );"; + item[ 10 ] = "Convert to Portal" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"Portal\" );"; + item[ 11 ] = "Convert to Occluder" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"OcclusionVolume\" );"; + item[ 12 ] = "Convert to Sound Space" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"SFXSpace\" );"; + }; + } + + // Specialized version for polyhedral objects. + else if( %obj.isMemberOfClass( "Zone" ) || + %obj.isMemberOfClass( "Portal" ) || + %obj.isMemberOfClass( "OcclusionVolume" ) || + %obj.isMemberOfClass( "SFXSpace" ) ) + { + %popup = ETPolyObjectContextPopup; + if( !isObject( %popup ) ) + %popup = new PopupMenu( ETPolyObjectContextPopup : ETContextPopup ) + { + superClass = "MenuBuilder"; + isPopup = "1"; + + item[ 8 ] = "-"; + item[ 9 ] = "Convert to ConvexShape" TAB "" TAB "EWorldEditor.convertSelectionToConvexShape();"; + }; + } + + %popup.object = %obj; + %haveObjectEntries = true; + } + + if( %haveObjectEntries ) + { + %popup.enableItem( 0, %obj.isNameChangeAllowed() && %obj.getName() !$= "MissionGroup" ); + %popup.enableItem( 1, %obj.getName() !$= "MissionGroup" ); + if( %haveLockAndHideEntries ) + { + %popup.checkItem( 4, %obj.locked ); + %popup.checkItem( 5, %obj.hidden ); + } + %popup.enableItem( 7, %this.isItemSelected( %itemId ) ); + } + + %popup.showPopup( Canvas ); +} + +function EditorTree::positionContextMenu( %this, %menu ) +{ + if( (getWord(%menu.position, 0) + getWord(%menu.extent, 0)) > getWord(EWorldEditor.extent, 0) ) + { + %posx = getWord(%menu.position, 0); + %offset = getWord(EWorldEditor.extent, 0) - (%posx + getWord(%menu.extent, 0)) - 5; + %posx += %offset; + %menu.position = %posx @ " " @ getWord(%menu.position, 1); + } +} + +function EditorTree::isValidDragTarget( %this, %id, %obj ) +{ + if( %obj.isMemberOfClass( "Path" ) ) + return EWorldEditor.areAllSelectedObjectsOfType( "Marker" ); + if( %obj.name $= "CameraBookmarks" ) + return EWorldEditor.areAllSelectedObjectsOfType( "CameraBookmark" ); + else + return ( %obj.getClassName() $= "SimGroup" ); +} + +function EditorTree::onBeginReparenting( %this ) +{ + if( isObject( %this.reparentUndoAction ) ) + %this.reparentUndoAction.delete(); + + %action = UndoActionReparentObjects::create( %this ); + + %this.reparentUndoAction = %action; +} + +function EditorTree::onReparent( %this, %obj, %oldParent, %newParent ) +{ + %this.reparentUndoAction.add( %obj, %oldParent, %newParent ); +} + +function EditorTree::onEndReparenting( %this ) +{ + %action = %this.reparentUndoAction; + %this.reparentUndoAction = ""; + + if( %action.numObjects > 0 ) + { + if( %action.numObjects == 1 ) + %action.actionName = "Reparent Object"; + else + %action.actionName = "Reparent Objects"; + + %action.addToManager( Editor.getUndoManager() ); + + EWorldEditor.syncGui(); + } + else + %action.delete(); +} + +function EditorTree::update( %this ) +{ + %this.buildVisibleTree( false ); +} + +//------------------------------------------------------------------------------ + +// Tooltip for TSStatic +function EditorTree::GetTooltipTSStatic( %this, %obj ) +{ + return "Shape: " @ %obj.shapeName; +} + +// Tooltip for ShapeBase +function EditorTree::GetTooltipShapeBase( %this, %obj ) +{ + return "Datablock: " @ %obj.dataBlock; +} + +// Tooltip for StaticShape +function EditorTree::GetTooltipStaticShape( %this, %obj ) +{ + return "Datablock: " @ %obj.dataBlock; +} + +// Tooltip for Item +function EditorTree::GetTooltipItem( %this, %obj ) +{ + return "Datablock: " @ %obj.dataBlock; +} + +// Tooltip for RigidShape +function EditorTree::GetTooltipRigidShape( %this, %obj ) +{ + return "Datablock: " @ %obj.dataBlock; +} + +// Tooltip for Prefab +function EditorTree::GetTooltipPrefab( %this, %obj ) +{ + return "File: " @ %obj.filename; +} + +// Tooltip for GroundCover +function EditorTree::GetTooltipGroundCover( %this, %obj ) +{ + %text = "Material: " @ %obj.material; + for(%i=0; %i<8; %i++) + { + if(%obj.probability[%i] > 0 && %obj.shapeFilename[%i] !$= "") + { + %text = %text NL "Shape " @ %i @ ": " @ %obj.shapeFilename[%i]; + } + } + return %text; +} + +// Tooltip for SFXEmitter +function EditorTree::GetTooltipSFXEmitter( %this, %obj ) +{ + if(%obj.fileName $= "") + return "Track: " @ %obj.track; + else + return "File: " @ %obj.fileName; +} + +// Tooltip for ParticleEmitterNode +function EditorTree::GetTooltipParticleEmitterNode( %this, %obj ) +{ + %text = "Datablock: " @ %obj.dataBlock; + %text = %text NL "Emitter: " @ %obj.emitter; + return %text; +} + +// Tooltip for InteriorInstance +function EditorTree::GetTooltipInteriorInstance( %this, %obj ) +{ + return "File: " @ %obj.interiorFile; +} + +// Tooltip for WorldEditorSelection +function EditorTree::GetTooltipWorldEditorSelection( %this, %obj ) +{ + %text = "Objects: " @ %obj.getCount(); + + if( !%obj.getCanSave() ) + %text = %text NL "Persistent: No"; + else + %text = %text NL "Persistent: Yes"; + + return %text; +} + +//------------------------------------------------------------------------------ + +function EditorTreeTabBook::onTabSelected( %this ) +{ + if( EditorTreeTabBook.getSelectedPage() == 0) + { + EWTreeWindow-->DeleteSelection.visible = true; + EWTreeWindow-->LockSelection.visible = true; + EWTreeWindow-->AddSimGroup.visible = true; + } + else + { + EWTreeWindow-->DeleteSelection.visible = false; + EWTreeWindow-->LockSelection.visible = false; + EWTreeWindow-->AddSimGroup.visible = false; + } +} + +//------------------------------------------------------------------------------ + +function Editor::open(%this) +{ + // prevent the mission editor from opening while the GuiEditor is open. + if(Canvas.getContent() == GuiEditorGui.getId()) + return; + + if( !EditorGui.isInitialized ) + EditorGui.init(); + + %this.editorEnabled(); + Canvas.setContent(EditorGui); + EditorGui.syncCameraGui(); +} + +function Editor::close(%this, %gui) +{ + %this.editorDisabled(); + Canvas.setContent(%gui); + if(isObject(MessageHud)) + MessageHud.close(); + EditorGui.writeCameraSettings(); +} + +$RelightCallback = ""; + +function EditorLightingComplete() +{ + $lightingMission = false; + RelightStatus.visible = false; + + if ($RelightCallback !$= "") + { + eval($RelightCallback); + } + + $RelightCallback = ""; +} + +function updateEditorLightingProgress() +{ + RelightProgress.setValue(($SceneLighting::lightingProgress)); + if ($lightingMission) + $lightingProgressThread = schedule(1, 0, "updateEditorLightingProgress"); +} + +function Editor::lightScene(%this, %callback, %forceAlways) +{ + if ($lightingMission) + return; + + $lightingMission = true; + $RelightCallback = %callback; + RelightStatus.visible = true; + RelightProgress.setValue(0); + Canvas.repaint(); + lightScene("EditorLightingComplete", %forceAlways); + updateEditorLightingProgress(); +} + +//------------------------------------------------------------------------------ + +function EditorGui::handleEscape( %this ) +{ + %result = false; + if ( isObject( %this.currentEditor ) ) + %result = %this.currentEditor.handleEscape(); + + if ( !%result ) + { + Editor.close("PlayGui"); + } +} + +function EditTSCtrl::updateGizmoMode( %this, %mode ) +{ + // Called when the gizmo mode is changed from C++ + + if ( %mode $= "None" ) + EditorGuiToolbar->NoneModeBtn.performClick(); + else if ( %mode $= "Move" ) + EditorGuiToolbar->MoveModeBtn.performClick(); + else if ( %mode $= "Rotate" ) + EditorGuiToolbar->RotateModeBtn.performClick(); + else if ( %mode $= "Scale" ) + EditorGuiToolbar->ScaleModeBtn.performClick(); +} + +//------------------------------------------------------------------------------ + +function EWorldEditor::syncGui( %this ) +{ + %this.syncToolPalette(); + + EditorTree.update(); + Editor.getUndoManager().updateUndoMenu( EditorGui.menuBar-->EditMenu ); + EditorGuiStatusBar.setSelectionObjectsByCount( %this.getSelectionSize() ); + + EWTreeWindow-->LockSelection.setStateOn( %this.getSelectionLockCount() > 0 ); + + EWorldEditorToolbar-->boundingBoxColBtn.setStateOn( EWorldEditor.boundingBoxCollision ); + + if( EWorldEditor.objectsUseBoxCenter ) + { + EWorldEditorToolbar-->centerObject.setBitmap("tools/gui/images/menubar/bounds-center"); + objectCenterDropdown-->objectBoundsBtn.setStateOn( 1 ); + } + else + { + EWorldEditorToolbar-->centerObject.setBitmap("tools/gui/images/menubar/object-center"); + objectCenterDropdown-->objectBoxBtn.setStateOn( 1 ); + } + + if( GlobalGizmoProfile.getFieldValue(alignment) $= "Object" ) + { + EWorldEditorToolbar-->objectTransform.setBitmap("tools/gui/images/menubar/object-transform"); + objectTransformDropdown-->objectTransformBtn.setStateOn( 1 ); + + } + else + { + EWorldEditorToolbar-->objectTransform.setBitmap("tools/gui/images/menubar/world-transform"); + objectTransformDropdown-->worldTransformBtn.setStateOn( 1 ); + } + + EWorldEditorToolbar-->renderHandleBtn.setStateOn( EWorldEditor.renderObjHandle ); + EWorldEditorToolbar-->renderTextBtn.setStateOn( EWorldEditor.renderObjText ); + + SnapToBar-->objectSnapBtn.setStateOn( EWorldEditor.getSoftSnap() ); + EWorldEditorToolbar-->softSnapSizeTextEdit.setText( EWorldEditor.getSoftSnapSize() ); + ESnapOptions-->SnapSize.setText( EWorldEditor.getSoftSnapSize() ); + ESnapOptions-->GridSize.setText( EWorldEditor.getGridSize() ); + + ESnapOptions-->GridSnapButton.setStateOn( %this.getGridSnap() ); + SnapToBar-->objectGridSnapBtn.setStateOn( %this.getGridSnap() ); + ESnapOptions-->NoSnapButton.setStateOn( !%this.stickToGround && !%this.getSoftSnap() && !%this.getGridSnap() ); +} + +function EWorldEditor::syncToolPalette( %this ) +{ + switch$ ( GlobalGizmoProfile.mode ) + { + case "None": + EWorldEditorNoneModeBtn.performClick(); + case "Move": + EWorldEditorMoveModeBtn.performClick(); + case "Rotate": + EWorldEditorRotateModeBtn.performClick(); + case "Scale": + EWorldEditorScaleModeBtn.performClick(); + } +} + +function EWorldEditor::addSimGroup( %this, %groupCurrentSelection ) +{ + %activeSelection = %this.getActiveSelection(); + if ( %activeSelection.getObjectIndex( MissionGroup ) != -1 ) + { + MessageBoxOK( "Error", "Cannot add MissionGroup to a new SimGroup" ); + return; + } + + // Find our parent. + + %parent = MissionGroup; + if( !%groupCurrentSelection && isObject( %activeSelection ) && %activeSelection.getCount() > 0 ) + { + %firstSelectedObject = %activeSelection.getObject( 0 ); + if( %firstSelectedObject.isMemberOfClass( "SimGroup" ) ) + %parent = %firstSelectedObject; + else if( %firstSelectedObject.getId() != MissionGroup.getId() ) + %parent = %firstSelectedObject.parentGroup; + } + + // If we are about to do a group-selected as well, + // starting recording an undo compound. + + if( %groupCurrentSelection ) + Editor.getUndoManager().pushCompound( "Group Selected" ); + + // Create the SimGroup. + + %object = new SimGroup() + { + parentGroup = %parent; + }; + MECreateUndoAction::submit( %object ); + + // Put selected objects into the group, if requested. + + if( %groupCurrentSelection && isObject( %activeSelection ) ) + { + %undo = UndoActionReparentObjects::create( EditorTree ); + + %numObjects = %activeSelection.getCount(); + for( %i = 0; %i < %numObjects; %i ++ ) + { + %sel = %activeSelection.getObject( %i ); + %undo.add( %sel, %sel.parentGroup, %object ); + %object.add( %sel ); + } + + %undo.addToManager( Editor.getUndoManager() ); + } + + // Stop recording for group-selected. + + if( %groupCurrentSelection ) + Editor.getUndoManager().popCompound(); + + // When not grouping selection, make the newly created SimGroup the + // current selection. + + if( !%groupCurrentSelection ) + { + EWorldEditor.clearSelection(); + EWorldEditor.selectObject( %object ); + } + + // Refresh the Gui. + + %this.syncGui(); +} + +function EWorldEditor::toggleLockChildren( %this, %simGroup ) +{ + foreach( %child in %simGroup ) + { + if( %child.isMemberOfClass( "SimGroup" ) ) + %this.toggleLockChildren( %child ); + else + %child.setLocked( !%child.locked ); + } + + EWorldEditor.syncGui(); +} + +function EWorldEditor::toggleHideChildren( %this, %simGroup ) +{ + foreach( %child in %simGroup ) + { + if( %child.isMemberOfClass( "SimGroup" ) ) + %this.toggleHideChildren( %child ); + else + %this.hideObject( %child, !%child.hidden ); + } + + EWorldEditor.syncGui(); +} + +function EWorldEditor::convertSelectionToPolyhedralObjects( %this, %className ) +{ + %group = %this.getNewObjectGroup(); + %undoManager = Editor.getUndoManager(); + + %activeSelection = %this.getActiveSelection(); + while( %activeSelection.getCount() != 0 ) + { + %oldObject = %activeSelection.getObject( 0 ); + %newObject = %this.createPolyhedralObject( %className, %oldObject ); + if( isObject( %newObject ) ) + { + %undoManager.pushCompound( "Convert ConvexShape to " @ %className ); + %newObject.parentGroup = %oldObject.parentGroup; + MECreateUndoAction::submit( %newObject ); + MEDeleteUndoAction::submit( %oldObject ); + %undoManager.popCompound(); + } + } +} + +function EWorldEditor::convertSelectionToConvexShape( %this ) +{ + %group = %this.getNewObjectGroup(); + %undoManager = Editor.getUndoManager(); + + %activeSelection = %this.getActiveSelection(); + while( %activeSelection.getCount() != 0 ) + { + %oldObject = %activeSelection.getObject( 0 ); + %newObject = %this.createConvexShapeFrom( %oldObject ); + if( isObject( %newObject ) ) + { + %undoManager.pushCompound( "Convert " @ %oldObject.getClassName() @ " to ConvexShape" ); + %newObject.parentGroup = %oldObject.parentGroup; + MECreateUndoAction::submit( %newObject ); + MEDeleteUndoAction::submit( %oldObject ); + %undoManager.popCompound(); + } + } +} + +function EWorldEditor::getNewObjectGroup( %this ) +{ + return EWCreatorWindow.getNewObjectGroup(); +} + +function EWorldEditor::deleteMissionObject( %this, %object ) +{ + // Unselect in editor tree. + + %id = EditorTree.findItemByObjectId( %object ); + EditorTree.selectItem( %id, false ); + + // Delete object. + + MEDeleteUndoAction::submit( %object ); + EWorldEditor.isDirty = true; + EditorTree.buildVisibleTree( true ); +} + +function EWorldEditor::selectAllObjectsInSet( %this, %set, %deselect ) +{ + if( !isObject( %set ) ) + return; + + foreach( %obj in %set ) + { + if( %deselect ) + %this.unselectObject( %obj ); + else + %this.selectObject( %obj ); + } +} + +function toggleSnappingOptions( %var ) +{ + if( SnapToBar->objectSnapDownBtn.getValue() && SnapToBar->objectSnapBtn.getValue() ) + { + if( %var $= "terrain" ) + { + EWorldEditor.stickToGround = 1; + EWorldEditor.setSoftSnap(false); + ESnapOptionsTabBook.selectPage(0); + SnapToBar->objectSnapBtn.setStateOn(0); + } + else + { + // soft snapping + EWorldEditor.stickToGround = 0; + EWorldEditor.setSoftSnap(true); + ESnapOptionsTabBook.selectPage(1); + SnapToBar->objectSnapDownBtn.setStateOn(0); + } + } + else if( %var $= "terrain" && EWorldEditor.stickToGround == 0 ) + { + // Terrain Snapping + EWorldEditor.stickToGround = 1; + EWorldEditor.setSoftSnap(false); + ESnapOptionsTabBook.selectPage(0); + SnapToBar->objectSnapDownBtn.setStateOn(1); + SnapToBar->objectSnapBtn.setStateOn(0); + + } + else if( %var $= "soft" && EWorldEditor.getSoftSnap() == false ) + { + // Object Snapping + EWorldEditor.stickToGround = 0; + EWorldEditor.setSoftSnap(true); + ESnapOptionsTabBook.selectPage(1); + SnapToBar->objectSnapBtn.setStateOn(1); + SnapToBar->objectSnapDownBtn.setStateOn(0); + + } + else if( %var $= "grid" ) + { + EWorldEditor.setGridSnap( !EWorldEditor.getGridSnap() ); + } + else + { + // No snapping. + + EWorldEditor.stickToGround = false; + EWorldEditor.setGridSnap( false ); + EWorldEditor.setSoftSnap( false ); + + SnapToBar->objectSnapDownBtn.setStateOn(0); + SnapToBar->objectSnapBtn.setStateOn(0); + } + + EWorldEditor.syncGui(); +} + +function objectCenterDropdown::toggle() +{ + if ( objectCenterDropdown.visible ) + { + EWorldEditorToolbar-->centerObject.setStateOn(false); + objectCenterDropdownDecoy.setVisible(false); + objectCenterDropdownDecoy.setActive(false); + objectCenterDropdown.setVisible(false); + } + else + { + EWorldEditorToolbar-->centerObject.setStateOn(true); + objectCenterDropdown.setVisible(true); + objectCenterDropdownDecoy.setActive(true); + objectCenterDropdownDecoy.setVisible(true); + } +} + +function objectTransformDropdown::toggle() +{ + if ( objectTransformDropdown.visible ) + { + EWorldEditorToolbar-->objectTransform.setStateOn(false); + objectTransformDropdownDecoy.setVisible(false); + objectTransformDropdownDecoy.setActive(false); + objectTransformDropdown.setVisible(false); + } + else + { + EWorldEditorToolbar-->objectTransform.setStateOn(true); + objectTransformDropdown.setVisible(true); + objectTransformDropdownDecoy.setActive(true); + objectTransformDropdownDecoy.setVisible(true); + } +} + +function objectSnapDropdownDecoy::onMouseLeave() +{ + objectSnapDropdown.toggle(); +} + +function objectCenterDropdownDecoy::onMouseLeave() +{ + objectCenterDropdown.toggle(); +} + +function objectTransformDropdownDecoy::onMouseLeave() +{ + objectTransformDropdown.toggle(); +} + +//------------------------------------------------------------------------------ + +function EWAddSimGroupButton::onDefaultClick( %this ) +{ + EWorldEditor.addSimGroup(); +} + +function EWAddSimGroupButton::onCtrlClick( %this ) +{ + EWorldEditor.addSimGroup( true ); +} + +//------------------------------------------------------------------------------ + +function EWToolsToolbar::reset( %this ) +{ + %count = ToolsToolbarArray.getCount(); + for( %i = 0 ; %i < %count; %i++ ) + ToolsToolbarArray.getObject(%i).setVisible(true); + + %this.setExtent((29 + 4) * %count + 12, 33); + %this.isClosed = 0; + EWToolsToolbar.isDynamic = 0; + + EWToolsToolbarDecoy.setVisible(false); + EWToolsToolbarDecoy.setExtent((29 + 4) * %count + 4, 31); + + %this-->resizeArrow.setBitmap( "core/art/gui/images/collapse-toolbar" ); +} + +function EWToolsToolbar::toggleSize( %this, %useDynamics ) +{ + // toggles the size of the tooltoolbar. also goes through + // and hides each control not currently selected. we hide the controls + // in a very neat, spiffy way + + if ( %this.isClosed == 0 ) + { + %image = "core/art/gui/images/expand-toolbar"; + + for( %i = 0 ; %i < ToolsToolbarArray.getCount(); %i++ ) + { + if( ToolsToolbarArray.getObject(%i).getValue() != 1 ) + ToolsToolbarArray.getObject(%i).setVisible(false); + } + + %this.setExtent(43, 33); + %this.isClosed = 1; + + if(!%useDynamics) + { + EWToolsToolbarDecoy.setVisible(true); + EWToolsToolbar.isDynamic = 1; + } + + EWToolsToolbarDecoy.setExtent(35, 31); + } + else + { + %image = "core/art/gui/images/collapse-toolbar"; + + %count = ToolsToolbarArray.getCount(); + for( %i = 0 ; %i < %count; %i++ ) + ToolsToolbarArray.getObject(%i).setVisible(true); + + %this.setExtent((29 + 4) * %count + 12, 33); + %this.isClosed = 0; + + if(!%useDynamics) + { + EWToolsToolbarDecoy.setVisible(false); + EWToolsToolbar.isDynamic = 0; + } + + EWToolsToolbarDecoy.setExtent((29 + 4) * %count + 4, 32); + } + + %this-->resizeArrow.setBitmap( %image ); + +} + +function EWToolsToolbarDecoy::onMouseEnter( %this ) +{ + EWToolsToolbar.toggleSize(true); +} + +function EWToolsToolbarDecoy::onMouseLeave( %this ) +{ + EWToolsToolbar.toggleSize(true); +} + +//------------------------------------------------------------------------------ + +function EditorGuiStatusBar::reset( %this ) +{ + EWorldEditorStatusBarInfo.clearInfo(); +} + +function EditorGuiStatusBar::getInfo( %this ) +{ + return EWorldEditorStatusBarInfo.getValue(); +} + +function EditorGuiStatusBar::setInfo( %this, %text ) +{ + EWorldEditorStatusBarInfo.setText(%text); +} + +function EditorGuiStatusBar::clearInfo( %this ) +{ + EWorldEditorStatusBarInfo.setText(""); +} + +function EditorGuiStatusBar::getSelection( %this ) +{ + return EWorldEditorStatusBarSelection.getValue(); +} + +function EditorGuiStatusBar::setSelection( %this, %text ) +{ + EWorldEditorStatusBarSelection.setText(%text); +} + +function EditorGuiStatusBar::setSelectionObjectsByCount( %this, %count ) +{ + %text = " objects selected"; + if(%count == 1) + %text = " object selected"; + + EWorldEditorStatusBarSelection.setText(%count @ %text); +} + +function EditorGuiStatusBar::clearSelection( %this ) +{ + EWorldEditorStatusBarSelection.setText(""); +} + +function EditorGuiStatusBar::getCamera( %this ) +{ + return EWorldEditorStatusBarCamera.getText(); +} + +function EditorGuiStatusBar::setCamera( %this, %text ) +{ + %id = EWorldEditorStatusBarCamera.findText( %text ); + if( %id != -1 ) + { + if ( EWorldEditorStatusBarCamera.getSelected() != %id ) + EWorldEditorStatusBarCamera.setSelected( %id, true ); + } +} + +function EWorldEditorStatusBarCamera::onWake( %this ) +{ + %this.add( "Standard Camera" ); + %this.add( "1st Person Camera" ); + %this.add( "3rd Person Camera" ); + %this.add( "Orbit Camera" ); + %this.add( "Top View" ); + %this.add( "Bottom View" ); + %this.add( "Left View" ); + %this.add( "Right View" ); + %this.add( "Front View" ); + %this.add( "Back View" ); + %this.add( "Isometric View" ); + %this.add( "Smooth Camera" ); + %this.add( "Smooth Rot Camera" ); +} + +function EWorldEditorStatusBarCamera::onSelect( %this, %id, %text ) +{ + switch$( %text ) + { + case "Top View": + commandToServer( 'SetEditorCameraStandard' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypeTop ); + + case "Bottom View": + commandToServer( 'SetEditorCameraStandard' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypeBottom ); + + case "Left View": + commandToServer( 'SetEditorCameraStandard' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypeLeft ); + + case "Right View": + commandToServer( 'SetEditorCameraStandard' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypeRight ); + + case "Front View": + commandToServer( 'SetEditorCameraStandard' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypeFront ); + + case "Back View": + commandToServer( 'SetEditorCameraStandard' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypeBack ); + + case "Isometric View": + commandToServer( 'SetEditorCameraStandard' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypeIsometric ); + + case "Standard Camera": + commandToServer( 'SetEditorCameraStandard' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypePerspective ); + + case "1st Person Camera": + commandToServer( 'SetEditorCameraPlayer' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypePerspective ); + + case "3rd Person Camera": + commandToServer( 'SetEditorCameraPlayerThird' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypePerspective ); + + case "Orbit Camera": + commandToServer( 'SetEditorOrbitCamera' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypePerspective ); + + case "Smooth Camera": + commandToServer( 'SetEditorCameraNewton' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypePerspective ); + + case "Smooth Rot Camera": + commandToServer( 'SetEditorCameraNewtonDamped' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypePerspective ); + } +} + +//------------------------------------------------------------------------------------ +// Each a gui slider bar is pushed on the editor gui, it maps itself with value +// located in its connected text control +//------------------------------------------------------------------------------------ +function softSnapSizeSliderCtrlContainer::onWake(%this) +{ + %this-->slider.setValue(EWorldEditorToolbar-->softSnapSizeTextEdit.getValue()); +} +function softSnapSizeSliderCtrlContainer::onSliderChanged(%this) +{ + EWorldEditor.setSoftSnapSize( %this-->slider.value ); + EWorldEditor.syncGui(); +} +//------------------------------------------------------------------------------------ + +function PaintBrushSizeSliderCtrlContainer::onWake(%this) +{ + %this-->slider.range = "1" SPC getWord(ETerrainEditor.maxBrushSize, 0); + %this-->slider.setValue(PaintBrushSizeTextEditContainer-->textEdit.getValue()); +} + +function PaintBrushPressureSliderCtrlContainer::onWake(%this) +{ + %this-->slider.setValue(PaintBrushPressureTextEditContainer-->textEdit.getValue() / 100); +} + +function PaintBrushSoftnessSliderCtrlContainer::onWake(%this) +{ + %this-->slider.setValue(PaintBrushSoftnessTextEditContainer-->textEdit.getValue() / 100); +} + +//------------------------------------------------------------------------------------ + +function TerrainBrushSizeSliderCtrlContainer::onWake(%this) +{ + %this-->slider.range = "1" SPC getWord(ETerrainEditor.maxBrushSize, 0); + %this-->slider.setValue(TerrainBrushSizeTextEditContainer-->textEdit.getValue()); +} + +function TerrainBrushPressureSliderCtrlContainer::onWake(%this) +{ + %this-->slider.setValue(TerrainBrushPressureTextEditContainer-->textEdit.getValue() / 100.0); +} + +function TerrainBrushSoftnessSliderCtrlContainer::onWake(%this) +{ + %this-->slider.setValue(TerrainBrushSoftnessTextEditContainer-->textEdit.getValue() / 100.0); +} + +function TerrainSetHeightSliderCtrlContainer::onWake(%this) +{ + %this-->slider.setValue(TerrainSetHeightTextEditContainer-->textEdit.getValue()); +} +//------------------------------------------------------------------------------------ +function CameraSpeedDropdownCtrlContainer::onWake(%this) +{ + %this-->slider.setValue(CameraSpeedDropdownContainer-->textEdit.getText()); +} + +//------------------------------------------------------------------------------------ +// Callbacks to close the dropdown slider controls like the camera speed, +// that are marked with this class name. + +function EditorDropdownSliderContainer::onMouseDown(%this) +{ + Canvas.popDialog(%this); +} + +function EditorDropdownSliderContainer::onRightMouseDown(%this) +{ + Canvas.popDialog(%this); +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/worldEditor/scripts/ManageSFXParametersWindow.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/ManageSFXParametersWindow.ed.cs new file mode 100644 index 000000000..360aeb629 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/ManageSFXParametersWindow.ed.cs @@ -0,0 +1,847 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +//============================================================================= +// Constants. +//============================================================================= + +/// File to save newly created SFXParameters in by default. +$SFX_PARAMETER_FILE = "scripts/client/audioData.cs"; + +$SFX_PARAMETER_CHANNELS[ 0 ] = "Volume"; +$SFX_PARAMETER_CHANNELS[ 1 ] = "Pitch"; +$SFX_PARAMETER_CHANNELS[ 2 ] = "Priority"; +$SFX_PARAMETER_CHANNELS[ 3 ] = "MinDistance"; +$SFX_PARAMETER_CHANNELS[ 4 ] = "MaxDistance"; +$SFX_PARAMETER_CHANNELS[ 5 ] = "ConeInsideAngle"; +$SFX_PARAMETER_CHANNELS[ 6 ] = "ConeOutsideAngle"; +$SFX_PARAMETER_CHANNELS[ 7 ] = "ConeOutsideVolume"; +$SFX_PARAMETER_CHANNELS[ 8 ] = "PositionX"; +$SFX_PARAMETER_CHANNELS[ 9 ] = "PositionY"; +$SFX_PARAMETER_CHANNELS[ 10 ] = "PositionZ"; +$SFX_PARAMETER_CHANNELS[ 11 ] = "RotationX"; +$SFX_PARAMETER_CHANNELS[ 12 ] = "RotationY"; +$SFX_PARAMETER_CHANNELS[ 13 ] = "RotationZ"; +$SFX_PARAMETER_CHANNELS[ 14 ] = "VelocityX"; +$SFX_PARAMETER_CHANNELS[ 15 ] = "VelocityY"; +$SFX_PARAMETER_CHANNELS[ 16 ] = "VelocityZ"; +$SFX_PARAMETER_CHANNELS[ 17 ] = "Cursor"; +$SFX_PARAMETER_CHANNELS[ 18 ] = "User0"; +$SFX_PARAMETER_CHANNELS[ 19 ] = "User1"; +$SFX_PARAMETER_CHANNELS[ 20 ] = "User2"; +$SFX_PARAMETER_CHANNELS[ 21 ] = "User3"; + +$SFX_PARAMETER_CHANNELS_COUNT = 22; + +/// Interval (in milliseconds) between GUI updates. Each update +/// syncs the displayed values to the actual parameter states. +$SFX_PARAMETERS_UPDATE_INTERVAL = 50; + +//============================================================================= +// EManageSFXParameters. +//============================================================================= + +//----------------------------------------------------------------------------- + +function EManageSFXParameters::createNewParameter( %this, %name ) +{ + %parameter = new SFXParameter() + { + internalName = %name; + }; + + if( !isObject( %parameter ) ) + return; + + %parameter.setFilename( $SFX_PARAMETER_FILE ); + %this.persistenceMgr.setDirty( %parameter ); + %this.persistenceMgr.saveDirty(); + + %this.addParameter( %parameter ); +} + +//----------------------------------------------------------------------------- + +function EManageSFXParameters::showDeleteParameterDlg( %this, %parameter ) +{ + MessageBoxOkCancel( "Confirmation", + "Really delete '" @ %parameter.getInternalName() @ "'?" NL + "" NL + "The parameter will be removed from the file '" @ %parameter.getFileName() @ "'.", + %this @ ".deleteParameter( " @ %parameter @ " );" + ); +} + +//----------------------------------------------------------------------------- + +function EManageSFXParameters::deleteParameter( %this, %parameter ) +{ + %this.removeParameter( %parameter ); + if( %parameter.getFilename() !$= "" ) + %this.persistenceMgr.removeObjectFromFile( %parameter ); + + %parameter.delete(); +} + +//----------------------------------------------------------------------------- + +function EManageSFXParameters::saveParameter( %this, %parameter ) +{ + if( %parameter.getFilename() !$= "" ) + { + if( !%this.persistenceMgr.isDirty( %parameter ) ) + %this.persistenceMgr.setDirty( %parameter ); + + %this.persistenceMgr.saveDirty(); + } +} + +//----------------------------------------------------------------------------- + +function EManageSFXParameters::onWake( %this ) +{ + // If the parameter list is empty, add all SFXParameters in the + // SFXParameterGroup to the list. + + if( %this-->SFXParametersStack.getCount() == 0 ) + %this.initList(); + + if( !isObject( %this.persistenceMgr ) ) + %this.persistenceMgr = new PersistenceManager(); +} + +//----------------------------------------------------------------------------- + +function EManageSFXParameters::onVisible( %this, %value ) +{ + if( %value ) + { + // Schedule an update. + + %this.schedule( %SFX_PARAMETERS_UPDATE_INTERVAL, "update" ); + } +} + +//----------------------------------------------------------------------------- + +/// Populate the parameter list with the currently defined SFXParameters. +function EManageSFXParameters::initList( %this, %filter ) +{ + // Clear the current lists. + + %this-->SFXParametersStack.clear(); + + // Add each SFXParameter in SFXParameterGroup. + + foreach( %obj in SFXParameterGroup ) + { + if( !isMemberOfClass( %obj.getClassName(), "SFXParameter" ) ) + continue; + + // If we have a filter, search for it in the parameter's + // categories. + + %matchesFilter = true; + if( %filter !$= "" ) + { + %matchesFilter = false; + + for( %idx = 0; %obj.categories[ %idx ] !$= ""; %idx ++ ) + { + if( %obj.categories[ %idx ] $= %filter ) + { + %matchesFilter = true; + break; + } + } + } + + if( %matchesFilter ) + %this.addParameter( %obj ); + } + + // Init the filters. + + %this.initFilterList( %filter ); +} + +//----------------------------------------------------------------------------- + +function EManageSFXParameters::initFilterList( %this, %selectFilter ) +{ + %filterList = %this-->SFXParameterFilter; + %filterList.clear(); + %filterList.add( "", 0 ); + + foreach( %obj in SFXParameterGroup ) + { + if( !isMemberOfClass( %obj.getClassName(), "SFXParameter" ) ) + continue; + + for( %idx = 0; %obj.categories[ %idx ] !$= ""; %idx ++ ) + { + %category = %obj.categories[ %idx ]; + if( %filterList.findText( %category ) == -1 ) + %filterList.add( %category, %filterList.size() ); + } + } + + // Sort the filters. + + %filterList.sort(); + %filterList.setSelected( %filterList.findText( %selectFilter ), false ); +} + +//----------------------------------------------------------------------------- + +/// Parse the categories for the parameter from the given comma-separated list. +function EManageSFXParameters::updateParameterCategories( %this, %parameter, %list ) +{ + %this.persistenceMgr.setDirty( %parameter ); + + // Parse the list. + + %len = strlen( %list ); + %pos = 0; + + %idx = 0; + while( %pos < %len ) + { + %startPos = %pos; + %pos = strchrpos( %list, ",", %pos ); + if( %pos == -1 ) + %pos = %len; + + if( %pos > %startPos ) + { + %category = getSubStr( %list, %startPos, %pos - %startPos ); + %category = trim( %category ); + %parameter.categories[ %idx ] = %category; + %idx ++; + } + + %pos ++; + } + + // Clear out excess categories existing from before. + + while( %parameter.categories[ %idx ] !$= "" ) + { + %parameter.categories[ %idx ] = ""; + %this.persistenceMgr.removeField( %parameter, "categories" @ %idx ); + %idx ++; + } + + // Save the parameter. + + %this.saveParameter( %parameter ); + + // Re-initialize the filter list. + + %this.initFilterList( %this-->SFXParameterFilter.getText() ); +} + +//----------------------------------------------------------------------------- + +/// Add a new SFXParameter to the list. +function EManageSFXParameters::addParameter( %this, %parameter ) +{ + %ctrl = new GuiRolloutCtrl() { + Margin = "0 0 0 0"; + DefaultHeight = "40"; + Expanded = "1"; + ClickCollapse = "1"; + HideHeader = "0"; + isContainer = "1"; + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "421 114"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + caption = %parameter.getInternalName(); + + new GuiControl() { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 17"; + Extent = "421 94"; + MinExtent = "421 94"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Value"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiAutoSizeTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "7 4"; + Extent = "27 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Channel"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiAutoSizeTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "7 27"; + Extent = "45 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Comment"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiAutoSizeTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "7 50"; + Extent = "47 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Tags"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiAutoSizeTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "7 73"; + Extent = "25 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Min"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiAutoSizeTextProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "205 27"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Max"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiAutoSizeTextProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "271 27"; + Extent = "21 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Initial"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiAutoSizeTextProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "340 27"; + Extent = "24 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "0 1"; + ticks = "0"; + snap = "0"; + value = "0.5"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "65 5"; + Extent = "263 15"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "valueSlider"; + canSaveDynamicFields = "0"; + command = %parameter @ ".value = $thisControl.getValue();"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "336 4"; + Extent = "39 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "valueField"; + canSaveDynamicFields = "0"; + altCommand = %parameter @ ".value = $thisControl.getValue();"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/reset-icon"; + autoFit = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "381 4"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "resetButton"; + canSaveDynamicFields = "0"; + command = %parameter @ ".reset();"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + autoFit = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "398 4"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "deleteButton"; + canSaveDynamicFields = "0"; + command = "EManageSFXParameters.showDeleteParameterDlg( " @ %parameter @ ");"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "65 26"; + Extent = "135 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "channelDropdown"; + canSaveDynamicFields = "0"; + command = %parameter @ ".channel = $ThisControl.getText(); EManageSFXParameters.saveParameter( " @ %parameter @ ");"; //RDTODO: update range + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "65 50"; + Extent = "350 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "descriptionField"; + canSaveDynamicFields = "0"; + altCommand = %parameter @ ".description = $ThisControl.getText(); EManageSFXParameters.saveParameter( " @ %parameter @ ");"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "65 73"; + Extent = "230 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "tagsField"; + canSaveDynamicFields = "0"; + altCommand = "EManageSFXParameters.updateParameterCategories( " @ %parameter @ ", $ThisControl.getText() );"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "372 27"; + Extent = "43 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "defaultField"; + canSaveDynamicFields = "0"; + command = %parameter @ ".defaultValue = $ThisControl.getValue(); EManageSFXParameters.saveParameter( " @ %parameter @ ");"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "297 27"; + Extent = "39 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "rangeMaxField"; + canSaveDynamicFields = "0"; + altCommand = %parameter @ ".range = " @ %parameter @ ".range.x SPC $ThisControl.getValue(); $ThisControl.parentGroup-->valueSlider.range = " @ %parameter @ ".range; EManageSFXParameters.saveParameter( " @ %parameter @ ");"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "229 27"; + Extent = "39 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "rangeMinField"; + canSaveDynamicFields = "0"; + altCommand = %parameter @ ".range = $ThisControl.getValue() SPC " @ %parameter @ ".range.y; $ThisControl.parentGroup-->valueSlider.range = " @ %parameter @ ".range; EManageSFXParameters.saveParameter( " @ %parameter @ ");"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Local"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "302 73"; + Extent = "45 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "localCheckbox"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "349 73"; + Extent = "64 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "sourceDropdown"; + canSaveDynamicFields = "0"; + }; + }; + }; + + %ctrl.sfxParameter = %parameter; + + // Deactivate the per-source controls for now as these are not + // yet implemented in SFX. + + %ctrl-->localCheckbox.setActive( false ); + %ctrl-->sourceDropdown.setActive( false ); + + // Set the fields to reflect the parameter's current settings. + + %ctrl-->valueField.setValue( %paramter.value ); + %ctrl-->rangeMinField.setText( %parameter.range.x ); + %ctrl-->rangeMaxField.setText( %parameter.range.y ); + %ctrl-->defaultField.setValue( %parameter.defaultValue ); + %ctrl-->descriptionField.setText( %parameter.description ); + + %ctrl-->valueSlider.range = %parameter.range; + %ctrl-->valueSlider.setValue( %parameter.value ); + + // Set up the channels dropdown. + + %list = %ctrl-->channelDropdown; + for( %i = 0; %i < $SFX_PARAMETER_CHANNELS_COUNT; %i ++ ) + %list.add( $SFX_PARAMETER_CHANNELS[ %i ], %i ); + %list.sort(); + %list.setSelected( %list.findText( %parameter.channel ) ); + + %this-->SFXParametersStack.addGuiControl( %ctrl ); + + // Fill tagging field. + + %tags = ""; + %isFirst = true; + for( %i = 0; %parameter.categories[ %i ] !$= ""; %i ++ ) + { + if( !%isFirst ) + %tags = %tags @ ", "; + + %tags = %tags @ %parameter.categories[ %i ]; + + %isFirst = false; + } + + %ctrl-->tagsField.setText( %tags ); +} + +//----------------------------------------------------------------------------- + +function EManageSFXParameters::removeParameter( %this, %parameter ) +{ + foreach( %ctrl in %this-->SFXParametersStack ) + { + if( %ctrl.sfxParameter == %parameter ) + { + %ctrl.delete(); + break; + } + } +} + +//----------------------------------------------------------------------------- + +function EManageSFXParameters::update( %this ) +{ + foreach( %ctrl in %this-->SFXParametersStack ) + { + // If either the value field or the slider are currently being + // edited, don't update the value in order to not interfere with + // user editing. + + if( %ctrl-->valueField.isFirstResponder() || %ctrl-->valueSlider.isThumbBeingDragged() ) + continue; + + %parameter = %ctrl.sfxParameter; + + %ctrl-->valueField.setValue( %parameter.value ); + %ctrl-->valueSlider.setValue( %parameter.value ); + } + + // If the control is still awake, schedule another + // update. + + if( %this.isVisible() ) + %this.schedule( $SFX_PARAMETERS_UPDATE_INTERVAL, "update" ); +} diff --git a/Templates/Empty/game/tools/worldEditor/scripts/SelectObjectsWindow.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/SelectObjectsWindow.ed.cs new file mode 100644 index 000000000..2c436f74f --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/SelectObjectsWindow.ed.cs @@ -0,0 +1,178 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +singleton SimGroup( EWorldEditorSelectionFilters ); + + +//--------------------------------------------------------------------------------------------- + +function ESelectObjectsWindow::toggleVisibility( %this ) +{ + if( %this.isVisible() ) + %this.setVisible( false ); + else + %this.setVisible( true ); +} + +//--------------------------------------------------------------------------------------------- + +/// Function called by EObjectSelection::onSelectObjects to determine where +/// to start searching for objects. +function ESelectObjectsWindow::getRootGroup( %this ) +{ + return MissionGroup; +} + +//--------------------------------------------------------------------------------------------- + +/// Function called by EObjectSelection::initFilterList to retrieve the set of +/// filter objects. +function ESelectObjectsWindow::getFilterSet( %this ) +{ + return EWorldEditorSelectionFilters; +} + +//--------------------------------------------------------------------------------------------- + +/// Method called by EObjectSelection::initClassList to determine if the given +/// class should be included in the class list. +function ESelectObjectsWindow::includeClass( %this, %className ) +{ + if( isMemberOfClass( %className, "SceneObject" ) + || %className $= "SimGroup" + || %className $= "LevelInfo" ) // Derived directly from NetObject. + return true; + + return false; +} + +//--------------------------------------------------------------------------------------------- + +/// Method called by the EObjectSelection machinery when an object has been +/// matched against the given criteria. +function ESelectObjectsWindow::selectObject( %this, %object, %val ) +{ + if( %this.selectionSet ) + { + if( %val ) + %this.selectionSet.add( %object ); + else + %this.selectionSet.remove( %object ); + } + else + { + if( %val ) + EWorldEditor.selectObject( %object ); + else + EWorldEditor.unselectObject( %object ); + } +} + +//--------------------------------------------------------------------------------------------- + +function ESelectObjectsWindow::clearSelection( %this ) +{ + if( %this.selectionSet ) + %this.selectionSet.clear(); + else + EWorldEditor.clearSelection(); +} + +//============================================================================================= +// Events. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ESelectObjectsWindow::onWake( %this ) +{ + if( !%this.isInitialized ) + { + %this.init(); + %this.isInitialized = true; + } + + // Re-initialize the group list on each wake. + + %this.initGroupList(); +} + +//--------------------------------------------------------------------------------------------- + +function ESelectObjectsWindow::onSelectObjects( %this, %val, %reuseExistingSet ) +{ + // See if we should create an independent selection set. + + if( %this-->createSelectionSet.isStateOn() ) + { + %name = %this-->selectionSetName.getText(); + + // See if we should create or re-use a set. + + if( isObject( %name ) ) + { + if( !%name.isMemberOfClass( "WorldEditorSelection" ) ) + { + MessageBoxOk( "Error", + "An object called '" @ %name @ "' already exists and is not a selection." NL + "" NL + "Please choose a different name." ); + return; + } + else if( !%reuseExistingSet ) + { + MessageBoxYesNo( "Question", + "A selection called '" @ %name @ "' already exists. Modify the existing selection?", + %this @ ".onSelectObjects( " @ %val @ ", true );" ); + return; + } + else + %sel = %name; + } + else + { + // Make sure the name is valid. + if( !Editor::validateObjectName( %name, false ) ) + return; + + // Create a new selection set. + eval( "%sel = new WorldEditorSelection( " @ %name @ " ) { parentGroup = Selections; canSave = true; };" ); + if( !isObject( %sel ) ) + { + MessageBoxOk( "Error", + "Could not create the selection set. Please look at the console.log for details." ); + return; + } + } + + %this.selectionSet = %sel; + } + else + %this.selectionSet = ""; + + Parent::onSelectObjects( %this, %val ); + + // Refresh editor tree just in case. + + EditorTree.buildVisibleTree(); +} diff --git a/Templates/Empty/game/tools/worldEditor/scripts/cameraBookmarks.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/cameraBookmarks.ed.cs new file mode 100644 index 000000000..22c98b9bf --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/cameraBookmarks.ed.cs @@ -0,0 +1,360 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// CameraBookmark class methods. Located here so they won't fire without +// the tools in place. + +function CameraBookmark::onAdd( %this ) +{ +} + +function CameraBookmark::onRemove( %this ) +{ + if( isObject(EditorCameraBookmarks) ) + { + %pos = CameraBookmarks.getObjectIndex( %this ); + if( %pos != -1 ) + { + EditorCameraBookmarks.deleteItem( %pos ); + EManageBookmarks.deleteBookmark( %this, %pos ); + } + } +} + +function CameraBookmark::onGroupAdd( %this ) +{ + // If we're added to the CameraBookmarks group, then also add us + // to the menu and Manage Bookmarks window. + if( isObject(CameraBookmarks) ) + { + %pos = CameraBookmarks.getObjectIndex( %this ); + if( %pos != -1 ) + { + EditorCameraBookmarks.addItem( %pos, %this.internalName ); + EManageBookmarks.addBookmark( %this, %pos ); + } + } +} + +function CameraBookmark::onGroupRemove( %this ) +{ + // If we're part of the CameraBookmarks group, then also remove us from + // the menu and Manage Bookmarks window. + if( isObject(CameraBookmarks) ) + { + %pos = CameraBookmarks.getObjectIndex( %this ); + if( %pos != -1 ) + { + EditorCameraBookmarks.deleteItem( %pos ); + EManageBookmarks.deleteBookmark( %this, %pos ); + } + } +} + +function CameraBookmark::onInspectPostApply( %this ) +{ + EditorCameraBookmarks.rebuildBookmarks(); +} + +//----------------------------------------------------------------------------- + +function EditorCameraBookmarksMenu::onAdd( %this ) +{ + if(! isObject(%this.canvas)) + %this.canvas = Canvas; + + // Add any existing bookmarks + %this.rebuildBookmarks(); +} + +function EditorCameraBookmarksMenu::addItem( %this, %pos, %name ) +{ + if( %this.NoneItem == true ) + { + %this.NoneItem = false; + %this.removeItem( 0 ); + } + + %accel = ""; + %this.insertItem(%pos, %name !$= "-" ? %name : "", %accel); +} + +function EditorCameraBookmarksMenu::deleteItem( %this, %pos ) +{ + %this.removeItem( %pos ); + if( %this.getItemCount() == 0 && %this.NoneItem != true ) + { + %this.addItem( 0, "None" ); + %this.enableItem( 0, false ); + %this.NoneItem = true; + } +} + +function EditorCameraBookmarksMenu::onSelectItem( %this, %pos, %text ) +{ + if( %pos >= 0 && %pos < CameraBookmarks.getCount() ) + { + %mark = CameraBookmarks.getObject( %pos ); + EditorGui.jumpToBookmark( %mark.internalName ); + return true; + } + + return false; +} + +function EditorCameraBookmarksMenu::rebuildBookmarks( %this ) +{ + // Delete all current items + while( %this.getItemCount() > 0) + { + %this.removeItem( 0 ); + } + + // Add back in all of the bookmarks + if( isObject(CameraBookmarks) && CameraBookmarks.getCount() > 0 ) + { + for( %i=0; %i<CameraBookmarks.getCount(); %i++ ) + { + %mark = CameraBookmarks.getObject( %i ); + %this.addItem( %i, %mark.internalName ); + } + %this.NoneItem = false; + } + else + { + %this.addItem( 0, "None" ); + %this.enableItem( 0, false ); + %this.NoneItem = true; + } +} + +//----------------------------------------------------------------------------- + +function ManageBookmarksContainer::onOK( %this ) +{ + %name = EAddBookmarkWindowName.getText(); + EAddBookmarkWindowName.clearFirstResponder(); + + if( %name $= "" ) + { + // look for a NewCamera name to grab + for(%i = 0; ; %i++){ + %name = "NewCamera_" @ %i; + if( !CameraBookmarks.findObjectByInternalName(%name) ){ + break; + } + } + } + + // Check if the new bookmark name already exists + if( isObject(CameraBookmarks) && CameraBookmarks.findObjectByInternalName(%name) ) + { + %userName = %name; + for(%i = 0; ; %i++){ + %name = %userName @ "_" @ %i; + if( !CameraBookmarks.findObjectByInternalName(%name) ){ + break; + } + } + } + + EditorGui.addCameraBookmark( %name ); + EAddBookmarkWindowName.text = ""; + //%this.CloseWindow(); +} + +function EAddBookmarkWindowName::onReturn( %this ) +{ + // Same as clicking the Create Bookmark button + ManageBookmarksContainer.onOK(); +} + +//----------------------------------------------------------------------------- + +function EManageBookmarks::hideDialog( %this ) +{ + %this.setVisible(false); +} + +function EManageBookmarks::ToggleVisibility( %this ) +{ + if ( %this.visible ) + { + %this.setVisible(false); + EWorldEditor.EManageBookmarksDisplayed = false; + } + else + { + %this.setVisible(true); + %this.selectWindow(); + %this.setCollapseGroup(false); + EWorldEditor.EManageBookmarksDisplayed = true; + } +} + +function EManageBookmarks::addBookmark( %this, %mark, %index ) +{ + %gui = new GuiControl() { + internalName = %mark.getInternalName(); + Enabled = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "300 20"; + MinExtent = "78 20"; + Visible = "1"; + Bookmark = %mark; + + new GuiBitmapButtonCtrl() { + class = "EManageBookmarksGoToButton"; + bitmap = "tools/gui/images/camera-btn"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "2 2"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Go to bookmark"; + hovertime = "1000"; + internalName = "goToBookmark"; + canSaveDynamicFields = "0"; + }; + + new GuiTextEditCtrl() { + class = "EManageBookmarksTextEdit"; + internalName = "BookmarkName"; + profile="GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "22 2"; + Extent = "260 18"; + text = %mark.getInternalName(); + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiBitmapButtonCtrl() { + class = "EManageBookmarksDeleteButton"; + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "284 3"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Delete camera bookmark"; + hovertime = "1000"; + internalName = "deleteBookmark"; + canSaveDynamicFields = "0"; + }; + }; + + EManageBookmarks-->ManageBookmarksWindowStack.addGuiControl( %gui ); +} + +function EManageBookmarks::deleteBookmark( %this, %mark, %index ) +{ + %gui = EManageBookmarks-->ManageBookmarksWindowStack.findObjectByInternalName( %mark.getInternalName() ); + if( %gui != 0 ) + %gui.delete(); + else + warn("EManageBookmarks::deleteBookmark(): Could not find bookmark " @ %mark @ " at index " @ %index); +} + +function EManageBookmarksGoToButton::onClick( %this ) +{ + %mark = %this.getParent().Bookmark; + EditorGui.jumpToBookmark( %mark.getInternalName() ); +} + +function EManageBookmarksDeleteButton::onClick( %this ) +{ + %mark = %this.getParent().Bookmark; + EditorGui.schedule( 0, removeCameraBookmark, %mark.getInternalName() ); +} + +function EManageBookmarksTextEdit::onGainFirstResponder( %this ) +{ + if( %this.isActive() ) + { + %this.selectAllText(); + } +} + +function EManageBookmarksTextEdit::onReturn( %this ) +{ + %this.onValidate(); +} + +function EManageBookmarksTextEdit::onValidate( %this ) +{ + %mark = %this.getParent().Bookmark; + %oldname = %mark.getInternalName(); + %newname = %this.getText(); + + // If the new name is the same as the old, do nothing + if( %newname $= %oldname ) + return; + + // Make sure the new name doesn't conflict with a current bookmark + if( isObject(CameraBookmarks) && CameraBookmarks.findObjectByInternalName(%newname) ) + { + %id = %this.getId(); + %callback = %id @ ".setText(\"" @ %oldname @ "\"); " @ %id @ ".makeFirstResponder(true); " @ %id @ ".selectAllText();"; + MessageBoxOK("Create Bookmark", "You must provide a unique name for the new bookmark.", %callback); + return; + } + + // Rename the bookmark and update + %this.getParent().setInternalName( %newname ); + %mark.setInternalName( %newname ); + if( Inspector.getInspectObject() == %mark.getId() ) + { + Inspector.inspect( %mark ); + Inspector.apply(); + } + else + { + // User is not inspecting the bookmark, so manually + // update the menu. + %mark.onInspectPostApply(); + } + +} diff --git a/Templates/Empty/game/tools/worldEditor/scripts/cursors.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/cursors.ed.cs new file mode 100644 index 000000000..5669da9ce --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/cursors.ed.cs @@ -0,0 +1,79 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +// Editor Cursors +//------------------------------------------------------------------------------ + +new GuiCursor(EditorHandCursor) +{ + hotSpot = "7 0"; + bitmapName = "~/worldEditor/images/CUR_hand.png"; +}; + +new GuiCursor(EditorRotateCursor) +{ + hotSpot = "11 18"; + bitmapName = "~/worldEditor/images/CUR_rotate.png"; +}; + +new GuiCursor(EditorMoveCursor) +{ + hotSpot = "9 13"; + bitmapName = "~/worldEditor/images/CUR_grab.png"; +}; + +new GuiCursor(EditorArrowCursor) +{ + hotSpot = "0 0"; + bitmapName = "~/worldEditor/images/CUR_3darrow.png"; +}; + +new GuiCursor(EditorUpDownCursor) +{ + hotSpot = "5 10"; + bitmapName = "~/worldEditor/images/CUR_3dupdown"; +}; +new GuiCursor(EditorLeftRightCursor) +{ + hotSpot = "9 5"; + bitmapName = "~/worldEditor/images/CUR_3dleftright"; +}; + +new GuiCursor(EditorDiagRightCursor) +{ + hotSpot = "8 8"; + bitmapName = "~/worldEditor/images/CUR_3ddiagright"; +}; + +new GuiCursor(EditorDiagLeftCursor) +{ + hotSpot = "8 8"; + bitmapName = "~/worldEditor/images/CUR_3ddiagleft"; +}; + +new GuiControl(EmptyControl) +{ + profile = "GuiButtonProfile"; +}; + + diff --git a/Templates/Empty/game/tools/worldEditor/scripts/editor.bind.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/editor.bind.ed.cs new file mode 100644 index 000000000..0c5b78a73 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/editor.bind.ed.cs @@ -0,0 +1,84 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +// Mission Editor Manager +new ActionMap(EditorMap); + +function mouseWheelScroll( %val ) +{ + //$Camera::speedCurveTime += $Camera::scrollStepSize * ( (%val>0.0) ? 1 : -1 ); + //$Camera::speedCurveTime = mClamp( $Camera::speedCurveTime, 0.0, 1.0 ); + //calculateCameraSpeed(); + //EditorGui-->CameraSpeedSpinner.setText( $Camera::movementSpeed ); + + %rollAdj = getMouseAdjustAmount(%val); + %rollAdj = mClamp(%rollAdj, -mPi()+0.01, mPi()-0.01); + $mvRoll += %rollAdj; +} + +function editorYaw(%val) +{ + %yawAdj = getMouseAdjustAmount(%val); + + if(ServerConnection.isControlObjectRotDampedCamera() || EWorldEditor.isMiddleMouseDown()) + { + // Clamp and scale + %yawAdj = mClamp(%yawAdj, -m2Pi()+0.01, m2Pi()-0.01); + %yawAdj *= 0.5; + } + + if( EditorSettings.value( "Camera/invertXAxis" ) ) + %yawAdj *= -1; + + $mvYaw += %yawAdj; +} + +function editorPitch(%val) +{ + %pitchAdj = getMouseAdjustAmount(%val); + + if(ServerConnection.isControlObjectRotDampedCamera() || EWorldEditor.isMiddleMouseDown()) + { + // Clamp and scale + %pitchAdj = mClamp(%pitchAdj, -m2Pi()+0.01, m2Pi()-0.01); + %pitchAdj *= 0.5; + } + + if( EditorSettings.value( "Camera/invertYAxis" ) ) + %pitchAdj *= -1; + + $mvPitch += %pitchAdj; +} + +function editorWheelFadeScroll( %val ) +{ + EWorldEditor.fadeIconsDist += %val * 0.1; + if( EWorldEditor.fadeIconsDist < 0 ) + EWorldEditor.fadeIconsDist = 0; +} + +EditorMap.bind( mouse, xaxis, editorYaw ); +EditorMap.bind( mouse, yaxis, editorPitch ); +EditorMap.bind( mouse, zaxis, mouseWheelScroll ); + +EditorMap.bind( mouse, "alt zaxis", editorWheelFadeScroll ); diff --git a/Templates/Empty/game/tools/worldEditor/scripts/editor.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/editor.ed.cs new file mode 100644 index 000000000..21e3f522d --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/editor.ed.cs @@ -0,0 +1,222 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +//------------------------------------------------------------------------------ +// Hard coded images referenced from C++ code +//------------------------------------------------------------------------------ + +// editor/SelectHandle.png +// editor/DefaultHandle.png +// editor/LockedHandle.png + + +//------------------------------------------------------------------------------ +// Functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Mission Editor +//------------------------------------------------------------------------------ + +function Editor::create() +{ + // Not much to do here, build it and they will come... + // Only one thing... the editor is a gui control which + // expect the Canvas to exist, so it must be constructed + // before the editor. + new EditManager(Editor) + { + profile = "GuiContentProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + open = false; + }; +} + +function Editor::getUndoManager(%this) +{ + if ( !isObject( %this.undoManager ) ) + { + /// This is the global undo manager used by all + /// of the mission editor sub-editors. + %this.undoManager = new UndoManager( EUndoManager ) + { + numLevels = 200; + }; + } + return %this.undoManager; +} + +function Editor::setUndoManager(%this, %undoMgr) +{ + %this.undoManager = %undoMgr; +} + +function Editor::onAdd(%this) +{ + // Ignore Replicated fxStatic Instances. + EWorldEditor.ignoreObjClass("fxShapeReplicatedStatic"); +} + +function Editor::checkActiveLoadDone() +{ + if(isObject(EditorGui) && EditorGui.loadingMission) + { + Canvas.setContent(EditorGui); + EditorGui.loadingMission = false; + return true; + } + return false; +} + +//------------------------------------------------------------------------------ +function toggleEditor(%make) +{ + if (Canvas.isFullscreen()) + { + MessageBoxOK("Windowed Mode Required", "Please switch to windowed mode to access the Mission Editor."); + return; + } + + if (%make) + { + %timerId = startPrecisionTimer(); + + if( $InGuiEditor ) + GuiEdit(); + + if( !$missionRunning ) + { + // Flag saying, when level is chosen, launch it with the editor open. + ChooseLevelDlg.launchInEditor = true; + Canvas.pushDialog( ChooseLevelDlg ); + } + else + { + pushInstantGroup(); + + if ( !isObject( Editor ) ) + { + Editor::create(); + MissionCleanup.add( Editor ); + MissionCleanup.add( Editor.getUndoManager() ); + } + + if( EditorIsActive() ) + { + if (theLevelInfo.type $= "DemoScene") + { + commandToServer('dropPlayerAtCamera'); + Editor.close("SceneGui"); + } + else + { + Editor.close("PlayGui"); + } + } + else + { + if ( !$GuiEditorBtnPressed ) + { + canvas.pushDialog( EditorLoadingGui ); + canvas.repaint(); + } + else + { + $GuiEditorBtnPressed = false; + } + + Editor.open(); + + // Cancel the scheduled event to prevent + // the level from cycling after it's duration + // has elapsed. + cancel($Game::Schedule); + + if (theLevelInfo.type $= "DemoScene") + commandToServer('dropCameraAtPlayer', true); + + + canvas.popDialog(EditorLoadingGui); + } + + popInstantGroup(); + } + + %elapsed = stopPrecisionTimer( %timerId ); + warn( "Time spent in toggleEditor() : " @ %elapsed / 1000.0 @ " s" ); + } +} + +//------------------------------------------------------------------------------ +// The editor action maps are defined in editor.bind.cs +GlobalActionMap.bind(keyboard, "f11", toggleEditor); + + +// The scenario: +// The editor is open and the user closes the level by any way other than +// the file menu ( exit level ), eg. typing disconnect() in the console. +// +// The problem: +// Editor::close() is not called in this scenario which means onEditorDisable +// is not called on objects which hook into it and also gEditingMission will no +// longer be valid. +// +// The solution: +// Override the stock disconnect() function which is in game scripts from here +// in tools so we avoid putting our code in there. +// +// Disclaimer: +// If you think of a better way to do this feel free. The thing which could +// be dangerous about this is that no one will ever realize this code overriding +// a fairly standard and core game script from a somewhat random location. +// If it 'did' have unforscene sideeffects who would ever find it? + +package EditorDisconnectOverride +{ + function disconnect() + { + if ( isObject( Editor ) && Editor.isEditorEnabled() ) + { + if ( $UseUnifiedShell ) + { + if (isObject( UnifiedMainMenuGui )) + Editor.close("UnifiedMainMenuGui"); + else if (isObject( MainMenuGui )) + Editor.close("MainMenuGui"); + } + else if (isObject( MainMenuGui )) + Editor.close("MainMenuGui"); + } + + Parent::disconnect(); + } +}; +activatePackage( EditorDisconnectOverride ); diff --git a/Templates/Empty/game/tools/worldEditor/scripts/editorPlugin.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/editorPlugin.ed.cs new file mode 100644 index 000000000..663c6cc2b --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/editorPlugin.ed.cs @@ -0,0 +1,209 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +/// +/// This is used to register editor extensions and tools. +/// +/// There are various callbacks you can overload to hook in your +/// own functionality without changing the core editor code. +/// +/// At the moment this is primarily for the World/Mission +/// Editor and the callbacks mostly make sense in that context. +/// +/// Example: +/// +/// %obj = new ScriptObject() +/// { +/// superclass = "EditorPlugin"; +/// class = "RoadEditor"; +/// }; +/// +/// EditorPlugin::register( %obj ); +/// +/// For an a full example see: tools/roadEditor/main.cs +/// or: tools/riverEditor/main.cs +/// or: tools/decalEditor/main.cs +/// + +/// It is not intended for the user to overload this method. +/// If you do make sure you call the parent. +function EditorPlugin::onAdd( %this ) +{ + EditorPluginSet.add( %this ); +} + + +/// Callback when the world editor is first started. It +/// is a good place to insert menus and menu items as well as +/// preparing guis. +function EditorPlugin::onWorldEditorStartup( %this ) +{ +} + +/// Callback when the world editor is about to be totally deleted. +/// At the time of this writing this occurs when the engine is shut down +/// and the editor had been initialized. +function EditorPlugin::onWorldEditorShutdown( %this ) +{ +} + +/// Callback right before the editor is opened. +function EditorPlugin::onEditorWake( %this ) +{ +} + +/// Callback right before the editor is closed. +function EditorPlugin::onEditorSleep( %this ) +{ +} + +/// Callback when the tool is 'activated' by the WorldEditor +/// Push Gui's, stuff like that +function EditorPlugin::onActivated( %this ) +{ + if(isDemo()) + startToolTime(%this.getName()); + + %this.isActivated = true; +} + +/// Callback when the tool is 'deactivated' / closed by the WorldEditor +/// Pop Gui's, stuff like that +function EditorPlugin::onDeactivated( %this ) +{ + if(isDemo()) + endToolTime(%this.getName()); + + %this.isActivated = false; +} + +/// Callback when tab is pressed. +/// Used by the WorldEditor to toggle between inspector/creator, for example. +function EditorPlugin::onToggleToolWindows( %this ) +{ +} + +/// Callback when the edit menu is clicked or prior to handling an accelerator +/// key event mapped to an edit menu item. +/// It is up to the active editor to determine if these actions are +/// appropriate in the current state. +function EditorPlugin::onEditMenuSelect( %this, %editMenu ) +{ + %editMenu.enableItem( 3, false ); // Cut + %editMenu.enableItem( 4, false ); // Copy + %editMenu.enableItem( 5, false ); // Paste + %editMenu.enableItem( 6, false ); // Delete + %editMenu.enableItem( 8, false ); // Deselect +} + +/// If this tool keeps track of changes that necessitate resaving the mission +/// return true in that case. +function EditorPlugin::isDirty( %this ) +{ + return false; +} + +/// This gives tools a chance to clear whatever internal variables keep track of changes +/// since the last save. +function EditorPlugin::clearDirty( %this ) +{ +} + +/// This gives tools chance to save data out when the mission is being saved. +/// This will only be called if the tool says it is dirty. +function EditorPlugin::onSaveMission( %this, %missionFile ) +{ +} + +/// Called when during mission cleanup to notify plugins. +function EditorPlugin::onExitMission( %this ) +{ +} + +/// Called on the active plugin when a SceneObject is selected. +/// +/// @param object The object being selected. +function EditorPlugin::onObjectSelected( %this, %object ) +{ +} + +/// Called on the active plugin when a SceneObject is deselected. +/// +/// @param object The object being deselected. +function EditorPlugin::onObjectDeselected( %this, %object ) +{ +} + +/// Called on the active plugin when the selection of SceneObjects is cleared. +function EditorPlugin::onSelectionCleared( %this ) +{ +} + +/// Callback when the the delete item of the edit menu is selected or its +/// accelerator is pressed. +function EditorPlugin::handleDelete( %this ) +{ + warn( "EditorPlugin::handleDelete( " @ %this.getName() @ " )" NL + "Was not implemented in child namespace, yet menu item was enabled." ); +} + +/// Callback when the the deselect item of the edit menu is selected or its +/// accelerator is pressed. +function EditorPlugin::handleDeselect( %this ) +{ + warn( "EditorPlugin::handleDeselect( " @ %this.getName() @ " )" NL + "Was not implemented in child namespace, yet menu item was enabled." ); +} + +/// Callback when the the cut item of the edit menu is selected or its +/// accelerator is pressed. +function EditorPlugin::handleCut( %this ) +{ + warn( "EditorPlugin::handleCut( " @ %this.getName() @ " )" NL + "Was not implemented in child namespace, yet menu item was enabled." ); +} + +/// Callback when the the copy item of the edit menu is selected or its +/// accelerator is pressed. +function EditorPlugin::handleCopy( %this ) +{ + warn( "EditorPlugin::handleCopy( " @ %this.getName() @ " )" NL + "Was not implemented in child namespace, yet menu item was enabled." ); +} + +/// Callback when the the paste item of the edit menu is selected or its +/// accelerator is pressed. +function EditorPlugin::handlePaste( %this ) +{ + warn( "EditorPlugin::handlePaste( " @ %this.getName() @ " )" NL + "Was not implemented in child namespace, yet menu item was enabled." ); +} + +/// Callback when the escape key is pressed. +/// Return true if this tool has handled the key event in a custom way. +/// If false is returned the WorldEditor default behavior is to return +/// to the ObjectEditor. +function EditorPlugin::handleEscape( %this ) +{ + return false; +} diff --git a/Templates/Empty/game/tools/worldEditor/scripts/editorPrefs.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/editorPrefs.ed.cs new file mode 100644 index 000000000..0cc14bff0 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/editorPrefs.ed.cs @@ -0,0 +1,434 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Provide default values for all World Editor settings. These make use of +// the EditorSettings instance of the Settings class, as defined in the Tools +// package onStart(). + +EditorSettings.beginGroup( "WorldEditor", true ); +EditorSettings.setDefaultValue( "currentEditor", "WorldEditorInspectorPlugin" ); +EditorSettings.setDefaultValue( "dropType", "screenCenter" ); +EditorSettings.setDefaultValue( "undoLimit", "40" ); +EditorSettings.setDefaultValue( "forceLoadDAE", "0" ); +EditorSettings.setDefaultValue( "displayType", $EditTsCtrl::DisplayTypePerspective ); +EditorSettings.setDefaultValue( "orthoFOV", "50" ); +EditorSettings.setDefaultValue( "orthoShowGrid", "1" ); +EditorSettings.setDefaultValue( "currentEditor", "WorldEditorInspectorPlugin" ); +EditorSettings.setDefaultValue( "newLevelFile", "tools/levels/BlankRoom.mis" ); + +if( isFile( "C:/Program Files/Torsion/Torsion.exe" ) ) + EditorSettings.setDefaultValue( "torsionPath", "C:/Program Files/Torsion/Torsion.exe" ); +else if( isFile( "C:/Program Files (x86)/Torsion/Torsion.exe" ) ) + EditorSettings.setDefaultValue( "torsionPath", "C:/Program Files (x86)/Torsion/Torsion.exe" ); +else + EditorSettings.setDefaultValue( "torsionPath", "" ); + +EditorSettings.beginGroup( "ObjectIcons" ); +EditorSettings.setDefaultValue( "fadeIcons", "1" ); +EditorSettings.setDefaultValue( "fadeIconsStartDist", "8" ); +EditorSettings.setDefaultValue( "fadeIconsEndDist", "20" ); +EditorSettings.setDefaultValue( "fadeIconsStartAlpha", "255" ); +EditorSettings.setDefaultValue( "fadeIconsEndAlpha", "0" ); +EditorSettings.endGroup(); + +EditorSettings.beginGroup( "Grid" ); +EditorSettings.setDefaultValue( "gridSize", "1" ); +EditorSettings.setDefaultValue( "gridSnap", "0" ); +EditorSettings.setDefaultValue( "gridColor", "102 102 102 100" ); +EditorSettings.setDefaultValue( "gridOriginColor", "255 255 255 100" ); +EditorSettings.setDefaultValue( "gridMinorColor", "51 51 51 100" ); +EditorSettings.endGroup(); + +EditorSettings.beginGroup( "Tools" ); +EditorSettings.setDefaultValue( "snapGround", "0" ); +EditorSettings.setDefaultValue( "snapSoft", "0" ); +EditorSettings.setDefaultValue( "snapSoftSize", "2.0" ); +EditorSettings.setDefaultValue( "boundingBoxCollision", "0" ); +EditorSettings.setDefaultValue( "objectsUseBoxCenter", "1" ); +EditorSettings.setDefaultValue( "dropAtScreenCenterScalar","1.0" ); +EditorSettings.setDefaultValue( "dropAtScreenCenterMax", "100.0" ); +EditorSettings.endGroup(); + +EditorSettings.beginGroup( "Render" ); +EditorSettings.setDefaultValue( "renderObjHandle", "1" ); +EditorSettings.setDefaultValue( "renderObjText", "1" ); +EditorSettings.setDefaultValue( "renderPopupBackground", "1" ); +EditorSettings.setDefaultValue( "renderSelectionBox", "1" ); //<-- Does not currently render +EditorSettings.setDefaultValue( "showMousePopupInfo", "1" ); +//EditorSettings.setDefaultValue( "visibleDistanceScale", "1" ); +EditorSettings.endGroup(); + +EditorSettings.beginGroup( "Color" ); +EditorSettings.setDefaultValue( "dragRectColor", "255 255 0 255" ); +EditorSettings.setDefaultValue( "objectTextColor", "255 255 255 255" ); +EditorSettings.setDefaultValue( "objMouseOverColor", "0 255 0 255" ); //<-- Currently ignored by editor (always white) +EditorSettings.setDefaultValue( "objMouseOverSelectColor", "0 0 255 255" ); //<-- Currently ignored by editor (always white) +EditorSettings.setDefaultValue( "objSelectColor", "255 0 0 255" ); //<-- Currently ignored by editor (always white) +EditorSettings.setDefaultValue( "popupBackgroundColor", "100 100 100 255" ); +EditorSettings.setDefaultValue( "popupTextColor", "255 255 0 255" ); +EditorSettings.setDefaultValue( "raceSelectColor", "0 0 100 100" ); //<-- What is this used for? +EditorSettings.setDefaultValue( "selectionBoxColor", "255 255 0 255" ); //<-- Does not currently render +EditorSettings.setDefaultValue( "uvEditorHandleColor", "1" ); //<-- Index into color popup +EditorSettings.endGroup(); + +EditorSettings.beginGroup( "Images" ); +EditorSettings.setDefaultValue( "defaultHandle", "tools/worldEditor/images/DefaultHandle" ); +EditorSettings.setDefaultValue( "lockedHandle", "tools/worldEditor/images/LockedHandle" ); +EditorSettings.setDefaultValue( "selectHandle", "tools/worldEditor/images/SelectHandle" ); +EditorSettings.endGroup(); + +EditorSettings.beginGroup( "Docs" ); +EditorSettings.setDefaultValue( "documentationLocal", "../../../Documentation/Official Documentation.html" ); +EditorSettings.setDefaultValue( "documentationReference", "../../../Documentation/Torque 3D - Script Manual.chm"); +EditorSettings.setDefaultValue( "documentationURL", "http://www.garagegames.com/products/torque-3d/documentation/user" ); +EditorSettings.setDefaultValue( "forumURL", "http://www.garagegames.com/products/torque-3d/forums" ); +EditorSettings.endGroup(); + +EditorSettings.endGroup(); // WorldEditor + +//------------------------------------- + +// After setting up the default value, this field should be altered immediately +// after successfully using such functionality such as Open... or Save As... +EditorSettings.beginGroup( "LevelInformation" ); +EditorSettings.setDefaultValue( "levelsDirectory", "levels" ); +EditorSettings.endGroup(); + +//------------------------------------- + +EditorSettings.beginGroup( "AxisGizmo", true ); + +EditorSettings.setDefaultValue( "axisGizmoMaxScreenLen", "100" ); //<-- What is this used for? +EditorSettings.setDefaultValue( "rotationSnap", "15" ); //<-- Not currently used +EditorSettings.setDefaultValue( "snapRotations", "0" ); //<-- Not currently used +EditorSettings.setDefaultValue( "mouseRotateScalar", "0.8" ); +EditorSettings.setDefaultValue( "mouseScaleScalar", "0.8" ); +EditorSettings.setDefaultValue( "renderWhenUsed", "0" ); +EditorSettings.setDefaultValue( "renderInfoText", "1" ); + +EditorSettings.beginGroup( "Grid" ); +EditorSettings.setDefaultValue( "gridColor", "255 255 255 20" ); +EditorSettings.setDefaultValue( "gridSize", "10 10 10" ); +EditorSettings.setDefaultValue( "snapToGrid", "0" ); //<-- Not currently used +EditorSettings.setDefaultValue( "renderPlane", "0" ); +EditorSettings.setDefaultValue( "renderPlaneHashes", "0" ); +EditorSettings.setDefaultValue( "planeDim", "500" ); +EditorSettings.endGroup(); + +EditorSettings.endGroup(); + +//------------------------------------- + +EditorSettings.beginGroup( "TerrainEditor", true ); + +EditorSettings.setDefaultValue( "currentAction", "raiseHeight" ); + +EditorSettings.beginGroup( "Brush" ); +EditorSettings.setDefaultValue( "maxBrushSize", "40 40" ); +EditorSettings.setDefaultValue( "brushSize", "1 1" ); +EditorSettings.setDefaultValue( "brushType", "box" ); +EditorSettings.setDefaultValue( "brushPressure", "1" ); +EditorSettings.setDefaultValue( "brushSoftness", "1" ); +EditorSettings.endGroup(); + +EditorSettings.beginGroup( "ActionValues" ); +EditorSettings.setDefaultValue( "adjustHeightVal", "10" ); +EditorSettings.setDefaultValue( "setHeightVal", "100" ); +EditorSettings.setDefaultValue( "scaleVal", "1" ); //<-- Tool not currently implemented +EditorSettings.setDefaultValue( "smoothFactor", "0.1" ); +EditorSettings.setDefaultValue( "noiseFactor", "1.0" ); +EditorSettings.setDefaultValue( "softSelectRadius", "50" ); +EditorSettings.setDefaultValue( "softSelectFilter", "1.000000 0.833333 0.666667 0.500000 0.333333 0.166667 0.000000" ); +EditorSettings.setDefaultValue( "softSelectDefaultFilter", "1.000000 0.833333 0.666667 0.500000 0.333333 0.166667 0.000000" ); +EditorSettings.setDefaultValue( "slopeMinAngle", "0" ); +EditorSettings.setDefaultValue( "slopeMaxAngle", "90" ); +EditorSettings.endGroup(); + +EditorSettings.endGroup(); + +//------------------------------------- + +EditorSettings.beginGroup( "TerrainPainter", true ); +EditorSettings.endGroup(); + +//------------------------------------- + +//TODO: this doesn't belong here +function setDefault( %name, %value ) +{ + if( !isDefined( %name ) ) + eval( %name SPC "=" SPC "\"" @ %value @ "\";" ); +} + +setDefault( "$pref::WorldEditor::visibleDistanceScale", "1" ); // DAW: Keep this around for now as is used by EditTSCtrl + +// JCF: Couldn't some or all of these be exposed +// from WorldEditor::ConsoleInit via Con::AddVariable() +// and do away with this file? + +function EditorGui::readWorldEditorSettings(%this) +{ + EditorSettings.beginGroup( "WorldEditor", true ); + EWorldEditor.dropType = EditorSettings.value( "dropType" ); //$pref::WorldEditor::dropType; + EWorldEditor.undoLimit = EditorSettings.value( "undoLimit" ); //$pref::WorldEditor::undoLimit; + EWorldEditor.forceLoadDAE = EditorSettings.value( "forceLoadDAE" ); //$pref::WorldEditor::forceLoadDAE; + %this.currentDisplayType = EditorSettings.value( "displayType" ); + %this.currentOrthoFOV = EditorSettings.value( "orthoFOV" ); + EWorldEditor.renderOrthoGrid = EditorSettings.value( "orthoShowGrid" ); + %this.currentEditor = EditorSettings.value( "currentEditor" ); + %this.torsionPath = EditorSettings.value( "torsionPath" ); + + EditorSettings.beginGroup( "ObjectIcons" ); + EWorldEditor.fadeIcons = EditorSettings.value( "fadeIcons" ); + EWorldEditor.fadeIconsStartDist = EditorSettings.value( "fadeIconsStartDist" ); + EWorldEditor.fadeIconsEndDist = EditorSettings.value( "fadeIconsEndDist" ); + EWorldEditor.fadeIconsStartAlpha = EditorSettings.value( "fadeIconsStartAlpha" ); + EWorldEditor.fadeIconsEndAlpha = EditorSettings.value( "fadeIconsEndAlpha" ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Grid" ); + EWorldEditor.gridSize = EditorSettings.value( "gridSize" ); + EWorldEditor.gridSnap = EditorSettings.value( "gridSnap" ); + EWorldEditor.gridColor = EditorSettings.value( "gridColor" ); + EWorldEditor.gridOriginColor = EditorSettings.value( "gridOriginColor" ); + EWorldEditor.gridMinorColor = EditorSettings.value( "gridMinorColor" ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Tools" ); + EWorldEditor.stickToGround = EditorSettings.value("snapGround"); //$pref::WorldEditor::snapGround; + EWorldEditor.setSoftSnap( EditorSettings.value("snapSoft") ); //$pref::WorldEditor::snapSoft + EWorldEditor.setSoftSnapSize( EditorSettings.value("snapSoftSize") ); //$pref::WorldEditor::snapSoftSize + EWorldEditor.boundingBoxCollision = EditorSettings.value("boundingBoxCollision"); //$pref::WorldEditor::boundingBoxCollision; + EWorldEditor.objectsUseBoxCenter = EditorSettings.value("objectsUseBoxCenter"); //$pref::WorldEditor::objectsUseBoxCenter; + EWorldEditor.dropAtScreenCenterScalar = EditorSettings.value("dropAtScreenCenterScalar"); + EWorldEditor.dropAtScreenCenterMax = EditorSettings.value("dropAtScreenCenterMax"); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Render" ); + EWorldEditor.renderObjHandle = EditorSettings.value("renderObjHandle"); //$pref::WorldEditor::renderObjHandle; + EWorldEditor.renderObjText = EditorSettings.value("renderObjText"); //$pref::WorldEditor::renderObjText; + EWorldEditor.renderPopupBackground = EditorSettings.value("renderPopupBackground"); //$pref::WorldEditor::renderPopupBackground; + EWorldEditor.renderSelectionBox = EditorSettings.value("renderSelectionBox"); //$pref::WorldEditor::renderSelectionBox; + EWorldEditor.showMousePopupInfo = EditorSettings.value("showMousePopupInfo"); //$pref::WorldEditor::showMousePopupInfo; + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Color" ); + EWorldEditor.dragRectColor = EditorSettings.value("dragRectColor"); //$pref::WorldEditor::dragRectColor; + EWorldEditor.objectTextColor = EditorSettings.value("objectTextColor"); //$pref::WorldEditor::objectTextColor; + EWorldEditor.objMouseOverColor = EditorSettings.value("objMouseOverColor"); //$pref::WorldEditor::objMouseOverColor; + EWorldEditor.objMouseOverSelectColor = EditorSettings.value("objMouseOverSelectColor"); //$pref::WorldEditor::objMouseOverSelectColor; + EWorldEditor.objSelectColor = EditorSettings.value("objSelectColor"); //$pref::WorldEditor::objSelectColor; + EWorldEditor.popupBackgroundColor = EditorSettings.value("popupBackgroundColor"); //$pref::WorldEditor::popupBackgroundColor; + EWorldEditor.popupTextColor = EditorSettings.value("popupTextColor"); //$pref::WorldEditor::popupTextColor; + EWorldEditor.selectionBoxColor = EditorSettings.value("selectionBoxColor"); //$pref::WorldEditor::selectionBoxColor; + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Images" ); + EWorldEditor.defaultHandle = EditorSettings.value("defaultHandle"); //$pref::WorldEditor::defaultHandle; + EWorldEditor.lockedHandle = EditorSettings.value("lockedHandle"); //$pref::WorldEditor::lockedHandle; + EWorldEditor.selectHandle = EditorSettings.value("selectHandle"); //$pref::WorldEditor::selectHandle; + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Docs" ); + EWorldEditor.documentationLocal = EditorSettings.value( "documentationLocal" ); + EWorldEditor.documentationURL = EditorSettings.value( "documentationURL" ); + EWorldEditor.documentationReference = EditorSettings.value( "documentationReference" ); + EWorldEditor.forumURL = EditorSettings.value( "forumURL" ); + EditorSettings.endGroup(); + + //EWorldEditor.planarMovement = $pref::WorldEditor::planarMovement; //<-- What is this used for? + + EditorSettings.endGroup(); // WorldEditor + + EditorSettings.beginGroup( "AxisGizmo", true ); + GlobalGizmoProfile.screenLength = EditorSettings.value("axisGizmoMaxScreenLen"); //$pref::WorldEditor::axisGizmoMaxScreenLen; + GlobalGizmoProfile.rotationSnap = EditorSettings.value("rotationSnap"); //$pref::WorldEditor::rotationSnap; + GlobalGizmoProfile.snapRotations = EditorSettings.value("snapRotations"); //$pref::WorldEditor::snapRotations; + GlobalGizmoProfile.rotateScalar = EditorSettings.value("mouseRotateScalar"); //$pref::WorldEditor::mouseRotateScalar; + GlobalGizmoProfile.scaleScalar = EditorSettings.value("mouseScaleScalar"); //$pref::WorldEditor::mouseScaleScalar; + GlobalGizmoProfile.renderWhenUsed = EditorSettings.value("renderWhenUsed"); + GlobalGizmoProfile.renderInfoText = EditorSettings.value("renderInfoText"); + + EditorSettings.beginGroup( "Grid" ); + GlobalGizmoProfile.gridColor = EditorSettings.value("gridColor"); //$pref::WorldEditor::gridColor; + GlobalGizmoProfile.gridSize = EditorSettings.value("gridSize"); //$pref::WorldEditor::gridSize; + GlobalGizmoProfile.snapToGrid = EditorSettings.value("snapToGrid"); //$pref::WorldEditor::snapToGrid; + GlobalGizmoProfile.renderPlane = EditorSettings.value("renderPlane"); //$pref::WorldEditor::renderPlane; + GlobalGizmoProfile.renderPlaneHashes = EditorSettings.value("renderPlaneHashes"); //$pref::WorldEditor::renderPlaneHashes; + GlobalGizmoProfile.planeDim = EditorSettings.value("planeDim"); //$pref::WorldEditor::planeDim; + EditorSettings.endGroup(); + + EditorSettings.endGroup(); // AxisGizmo +} + +function EditorGui::writeWorldEditorSettings(%this) +{ + EditorSettings.beginGroup( "WorldEditor", true ); + EditorSettings.setValue( "dropType", EWorldEditor.dropType ); //$pref::WorldEditor::dropType + EditorSettings.setValue( "undoLimit", EWorldEditor.undoLimit ); //$pref::WorldEditor::undoLimit + EditorSettings.setValue( "forceLoadDAE", EWorldEditor.forceLoadDAE ); //$pref::WorldEditor::forceLoadDAE + EditorSettings.setValue( "displayType", %this.currentDisplayType ); + EditorSettings.setValue( "orthoFOV", %this.currentOrthoFOV ); + EditorSettings.setValue( "orthoShowGrid", EWorldEditor.renderOrthoGrid ); + EditorSettings.setValue( "currentEditor", %this.currentEditor ); + EditorSettings.setvalue( "torsionPath", %this.torsionPath ); + + EditorSettings.beginGroup( "ObjectIcons" ); + EditorSettings.setValue( "fadeIcons", EWorldEditor.fadeIcons ); + EditorSettings.setValue( "fadeIconsStartDist", EWorldEditor.fadeIconsStartDist ); + EditorSettings.setValue( "fadeIconsEndDist", EWorldEditor.fadeIconsEndDist ); + EditorSettings.setValue( "fadeIconsStartAlpha", EWorldEditor.fadeIconsStartAlpha ); + EditorSettings.setValue( "fadeIconsEndAlpha", EWorldEditor.fadeIconsEndAlpha ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Grid" ); + EditorSettings.setValue( "gridSize", EWorldEditor.gridSize ); + EditorSettings.setValue( "gridSnap", EWorldEditor.gridSnap ); + EditorSettings.setValue( "gridColor", EWorldEditor.gridColor ); + EditorSettings.setValue( "gridOriginColor", EWorldEditor.gridOriginColor ); + EditorSettings.setValue( "gridMinorColor", EWorldEditor.gridMinorColor ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Tools" ); + EditorSettings.setValue( "snapGround", EWorldEditor.stickToGround ); //$Pref::WorldEditor::snapGround + EditorSettings.setValue( "snapSoft", EWorldEditor.getSoftSnap() ); //$Pref::WorldEditor::snapSoft + EditorSettings.setValue( "snapSoftSize", EWorldEditor.getSoftSnapSize() ); //$Pref::WorldEditor::snapSoftSize + EditorSettings.setValue( "boundingBoxCollision", EWorldEditor.boundingBoxCollision ); //$Pref::WorldEditor::boundingBoxCollision + EditorSettings.setValue( "objectsUseBoxCenter", EWorldEditor.objectsUseBoxCenter ); //$Pref::WorldEditor::objectsUseBoxCenter + EditorSettings.setValue( "dropAtScreenCenterScalar", EWorldEditor.dropAtScreenCenterScalar ); + EditorSettings.setValue( "dropAtScreenCenterMax", EWorldEditor.dropAtScreenCenterMax ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Render" ); + EditorSettings.setValue( "renderObjHandle", EWorldEditor.renderObjHandle ); //$Pref::WorldEditor::renderObjHandle + EditorSettings.setValue( "renderObjText", EWorldEditor.renderObjText ); //$Pref::WorldEditor::renderObjText + EditorSettings.setValue( "renderPopupBackground", EWorldEditor.renderPopupBackground ); //$Pref::WorldEditor::renderPopupBackground + EditorSettings.setValue( "renderSelectionBox", EWorldEditor.renderSelectionBox ); //$Pref::WorldEditor::renderSelectionBox + EditorSettings.setValue( "showMousePopupInfo", EWorldEditor.showMousePopupInfo ); //$Pref::WorldEditor::showMousePopupInfo + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Color" ); + EditorSettings.setValue( "dragRectColor", EWorldEditor.dragRectColor ); //$Pref::WorldEditor::dragRectColor + EditorSettings.setValue( "objectTextColor", EWorldEditor.objectTextColor ); //$Pref::WorldEditor::objectTextColor + EditorSettings.setValue( "objMouseOverColor", EWorldEditor.objMouseOverColor ); //$Pref::WorldEditor::objMouseOverColor + EditorSettings.setValue( "objMouseOverSelectColor",EWorldEditor.objMouseOverSelectColor );//$Pref::WorldEditor::objMouseOverSelectColor + EditorSettings.setValue( "objSelectColor", EWorldEditor.objSelectColor ); //$Pref::WorldEditor::objSelectColor + EditorSettings.setValue( "popupBackgroundColor", EWorldEditor.popupBackgroundColor ); //$Pref::WorldEditor::popupBackgroundColor + EditorSettings.setValue( "selectionBoxColor", EWorldEditor.selectionBoxColor ); //$Pref::WorldEditor::selectionBoxColor + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Images" ); + EditorSettings.setValue( "defaultHandle", EWorldEditor.defaultHandle ); //$Pref::WorldEditor::defaultHandle + EditorSettings.setValue( "selectHandle", EWorldEditor.selectHandle ); //$Pref::WorldEditor::selectHandle + EditorSettings.setValue( "lockedHandle", EWorldEditor.lockedHandle ); //$Pref::WorldEditor::lockedHandle + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Docs" ); + EditorSettings.setValue( "documentationLocal", EWorldEditor.documentationLocal ); + EditorSettings.setValue( "documentationReference", EWorldEditor.documentationReference ); + EditorSettings.setValue( "documentationURL", EWorldEditor.documentationURL ); + EditorSettings.setValue( "forumURL", EWorldEditor.forumURL ); + EditorSettings.endGroup(); + + EditorSettings.endGroup(); // WorldEditor + + EditorSettings.beginGroup( "AxisGizmo", true ); + + EditorSettings.setValue( "axisGizmoMaxScreenLen", GlobalGizmoProfile.screenLength ); //$Pref::WorldEditor::axisGizmoMaxScreenLen + EditorSettings.setValue( "rotationSnap", GlobalGizmoProfile.rotationSnap ); //$Pref::WorldEditor::rotationSnap + EditorSettings.setValue( "snapRotations", GlobalGizmoProfile.snapRotations ); //$Pref::WorldEditor::snapRotations + EditorSettings.setValue( "mouseRotateScalar", GlobalGizmoProfile.rotateScalar ); //$Pref::WorldEditor::mouseRotateScalar + EditorSettings.setValue( "mouseScaleScalar", GlobalGizmoProfile.scaleScalar ); //$Pref::WorldEditor::mouseScaleScalar + EditorSettings.setValue( "renderWhenUsed", GlobalGizmoProfile.renderWhenUsed ); + EditorSettings.setValue( "renderInfoText", GlobalGizmoProfile.renderInfoText ); + + EditorSettings.beginGroup( "Grid" ); + EditorSettings.setValue( "gridColor", GlobalGizmoProfile.gridColor ); //$Pref::WorldEditor::gridColor + EditorSettings.setValue( "gridSize", GlobalGizmoProfile.gridSize ); //$Pref::WorldEditor::gridSize + EditorSettings.setValue( "snapToGrid", GlobalGizmoProfile.snapToGrid ); //$Pref::WorldEditor::snapToGrid + EditorSettings.setValue( "renderPlane", GlobalGizmoProfile.renderPlane ); //$Pref::WorldEditor::renderPlane + EditorSettings.setValue( "renderPlaneHashes", GlobalGizmoProfile.renderPlaneHashes );//$Pref::WorldEditor::renderPlaneHashes + EditorSettings.setValue( "planeDim", GlobalGizmoProfile.planeDim ); //$Pref::WorldEditor::planeDim + EditorSettings.endGroup(); + + EditorSettings.endGroup(); // AxisGizmo +} + +function EditorGui::readTerrainEditorSettings(%this) +{ + EditorSettings.beginGroup( "TerrainEditor", true ); + + ETerrainEditor.savedAction = EditorSettings.value("currentAction"); + + EditorSettings.beginGroup( "Brush" ); + ETerrainEditor.maxBrushSize = EditorSettings.value("maxBrushSize"); + ETerrainEditor.setBrushSize( EditorSettings.value("brushSize") ); + ETerrainEditor.setBrushType( EditorSettings.value("brushType") ); + ETerrainEditor.setBrushPressure( EditorSettings.value("brushPressure") ); + ETerrainEditor.setBrushSoftness( EditorSettings.value("brushSoftness") ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "ActionValues" ); + ETerrainEditor.adjustHeightVal = EditorSettings.value("adjustHeightVal"); + ETerrainEditor.setHeightVal = EditorSettings.value("setHeightVal"); + ETerrainEditor.scaleVal = EditorSettings.value("scaleVal"); + ETerrainEditor.smoothFactor = EditorSettings.value("smoothFactor"); + ETerrainEditor.noiseFactor = EditorSettings.value("noiseFactor"); + ETerrainEditor.softSelectRadius = EditorSettings.value("softSelectRadius"); + ETerrainEditor.softSelectFilter = EditorSettings.value("softSelectFilter"); + ETerrainEditor.softSelectDefaultFilter = EditorSettings.value("softSelectDefaultFilter"); + ETerrainEditor.setSlopeLimitMinAngle( EditorSettings.value("slopeMinAngle") ); + ETerrainEditor.setSlopeLimitMaxAngle( EditorSettings.value("slopeMaxAngle") ); + EditorSettings.endGroup(); + + EditorSettings.endGroup(); +} + +function EditorGui::writeTerrainEditorSettings(%this) +{ + EditorSettings.beginGroup( "TerrainEditor", true ); + + EditorSettings.setValue( "currentAction", ETerrainEditor.savedAction ); + + EditorSettings.beginGroup( "Brush" ); + EditorSettings.setValue( "maxBrushSize", ETerrainEditor.maxBrushSize ); + EditorSettings.setValue( "brushSize", ETerrainEditor.getBrushSize() ); + EditorSettings.setValue( "brushType", ETerrainEditor.getBrushType() ); + EditorSettings.setValue( "brushPressure", ETerrainEditor.getBrushPressure() ); + EditorSettings.setValue( "brushSoftness", ETerrainEditor.getBrushSoftness() ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "ActionValues" ); + EditorSettings.setValue( "adjustHeightVal", ETerrainEditor.adjustHeightVal ); + EditorSettings.setValue( "setHeightVal", ETerrainEditor.setHeightVal ); + EditorSettings.setValue( "scaleVal", ETerrainEditor.scaleVal ); + EditorSettings.setValue( "smoothFactor", ETerrainEditor.smoothFactor ); + EditorSettings.setValue( "noiseFactor", ETerrainEditor.noiseFactor ); + EditorSettings.setValue( "softSelectRadius", ETerrainEditor.softSelectRadius ); + EditorSettings.setValue( "softSelectFilter", ETerrainEditor.softSelectFilter ); + EditorSettings.setValue( "softSelectDefaultFilter",ETerrainEditor.softSelectDefaultFilter ); + EditorSettings.setValue( "slopeMinAngle", ETerrainEditor.getSlopeLimitMinAngle() ); + EditorSettings.setValue( "slopeMaxAngle", ETerrainEditor.getSlopeLimitMaxAngle() ); + EditorSettings.endGroup(); + + EditorSettings.endGroup(); +} diff --git a/Templates/Empty/game/tools/worldEditor/scripts/editorRender.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/editorRender.ed.cs new file mode 100644 index 000000000..4fae4d11c --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/editorRender.ed.cs @@ -0,0 +1,58 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +// Console onEditorRender functions: +//------------------------------------------------------------------------------ +// Functions: +// - renderSphere([pos], [radius], <sphereLevel>); +// - renderCircle([pos], [normal], [radius], <segments>); +// - renderTriangle([pnt], [pnt], [pnt]); +// - renderLine([start], [end], <thickness>); +// +// Variables: +// - consoleFrameColor - line prims are rendered with this +// - consoleFillColor +// - consoleSphereLevel - level of polyhedron subdivision +// - consoleCircleSegments +// - consoleLineWidth +//------------------------------------------------------------------------------ + +function SpawnSphere::onEditorRender(%this, %editor, %selected, %expanded) +{ + if(%selected $= "true") + { + %editor.consoleFrameColor = "255 0 0"; + %editor.consoleFillColor = "0 160 0 95"; + %editor.renderSphere(%this.getWorldBoxCenter(), %this.radius, 1); + } +} + +//function Item::onEditorRender(%this, %editor, %selected, %expanded) +//{ +// if(%this.getDataBlock().getName() $= "MineDeployed") +// { +// %editor.consoleFillColor = "0 0 0 0"; +// %editor.consoleFrameColor = "255 0 0"; +// %editor.renderSphere(%this.getWorldBoxCenter(), 6, 1); +// } +//} \ No newline at end of file diff --git a/Templates/Empty/game/tools/worldEditor/scripts/editorSettingsWindow.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/editorSettingsWindow.ed.cs new file mode 100644 index 000000000..3af447854 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/editorSettingsWindow.ed.cs @@ -0,0 +1,142 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function ESettingsWindow::startup( %this ) +{ + ESettingsWindowTabBook.selectPage( 0 ); + ESettingsWindowList.setSelectedById( 0 ); +} + +function ESettingsWindow::onWake( %this ) +{ +} + +function ESettingsWindow::hideDialog( %this ) +{ + %this.setVisible(false); +} + +function ESettingsWindow::ToggleVisibility() +{ + if ( ESettingsWindow.visible ) + { + ESettingsWindow.setVisible(false); + } + else + { + ESettingsWindow.setVisible(true); + ESettingsWindow.selectWindow(); + ESettingsWindow.setCollapseGroup(false); + } +} + +function ESettingsWindow::addTabPage( %this, %page ) +{ + ESettingsWindowTabBook.add( %page ); + ESettingsWindowList.addRow( ESettingsWindowTabBook.getSelectedPage(), %page.text ); + ESettingsWindowList.sort(0); +} + +//----------------------------------------------------------------------------- + +function ESettingsWindowList::onSelect( %this, %id, %text ) +{ + ESettingsWindowTabBook.selectPage( %id ); +} + +//----------------------------------------------------------------------------- +// Standard settings GUI classes. Editors may define their own methods of +// working with settings and are not required to use these. +//----------------------------------------------------------------------------- + +function ESettingsWindowCheckbox::onWake( %this ) +{ + %this.setStateOn( EditorSettings.value( %this.editorSettingsValue )); +} + +function ESettingsWindowCheckbox::onClick( %this ) +{ + EditorSettings.setValue( %this.editorSettingsValue, %this.getValue() ); + eval(%this.editorSettingsRead); +} + +//----------------------------------------------------------------------------- + +function ESettingsWindowTextEdit::onWake( %this ) +{ + %this.setText( EditorSettings.value( %this.editorSettingsValue )); +} + +function ESettingsWindowTextEdit::onValidate( %this ) +{ + EditorSettings.setValue( %this.editorSettingsValue, %this.getValue() ); + eval(%this.editorSettingsRead); +} + +function ESettingsWindowTextEdit::onGainFirstResponder( %this ) +{ + %this.selectAllText(); +} + +//----------------------------------------------------------------------------- + +function ESettingsWindowColor::apply( %this, %color ) +{ + EditorSettings.setValue( %this.editorSettingsValue, %color ); + eval(%this.editorSettingsRead); + + %this.findObjectByInternalName("ColorEdit", true).setText( %color); + %this.findObjectByInternalName("ColorButton", true).color = ColorIntToFloat( %color ); +} + +function ESettingsWindowColorEdit::onWake( %this ) +{ + %this.setText( EditorSettings.value( %this.getParent().editorSettingsValue )); +} + +function ESettingsWindowColorEdit::onValidate( %this ) +{ + %this.getParent().apply( %this.getValue() ); +} + +function ESettingsWindowColorEdit::onGainFirstResponder( %this ) +{ + %this.selectAllText(); +} + +function ESettingsWindowColorButton::onWake( %this ) +{ + %this.color = ColorIntToFloat( EditorSettings.value( %this.getParent().editorSettingsValue ) ); +} + +function ESettingsWindowColorButton::onClick( %this ) +{ + getColorI( ColorFloatToInt( %this.color ), %this.getId() @ ".apply", %this.getRoot() ); + //EditorSettings.setValue( %this.editorSettingsValue, %this.getValue() ); + //eval(%this.editorSettingsRead); +} + +function ESettingsWindowColorButton::apply( %this, %color ) +{ + %this.getParent().apply(%color); + echo("ESettingsWindowColorButton::apply(): " @ %color); +} diff --git a/Templates/Empty/game/tools/worldEditor/scripts/editors/creator.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/editors/creator.ed.cs new file mode 100644 index 000000000..3f2e45632 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/editors/creator.ed.cs @@ -0,0 +1,839 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +function EWCreatorWindow::init( %this ) +{ + // Just so we can recall this method for testing changes + // without restarting. + if ( isObject( %this.array ) ) + %this.array.delete(); + + %this.array = new ArrayObject(); + %this.array.caseSensitive = true; + %this.setListView( true ); + + %this.beginGroup( "Environment" ); + + // Removed Prefab as there doesn't really seem to be a point in creating a blank one + //%this.registerMissionObject( "Prefab", "Prefab" ); + %this.registerMissionObject( "SkyBox", "Sky Box" ); + %this.registerMissionObject( "CloudLayer", "Cloud Layer" ); + %this.registerMissionObject( "BasicClouds", "Basic Clouds" ); + %this.registerMissionObject( "ScatterSky", "Scatter Sky" ); + %this.registerMissionObject( "Sun", "Basic Sun" ); + %this.registerMissionObject( "Lightning" ); + %this.registerMissionObject( "WaterBlock", "Water Block" ); + %this.registerMissionObject( "SFXEmitter", "Sound Emitter" ); + %this.registerMissionObject( "Precipitation" ); + %this.registerMissionObject( "ParticleEmitterNode", "Particle Emitter" ); + + // Legacy features. Users should use Ground Cover and the Forest Editor. + //%this.registerMissionObject( "fxShapeReplicator", "Shape Replicator" ); + //%this.registerMissionObject( "fxFoliageReplicator", "Foliage Replicator" ); + + %this.registerMissionObject( "PointLight", "Point Light" ); + %this.registerMissionObject( "SpotLight", "Spot Light" ); + %this.registerMissionObject( "GroundCover", "Ground Cover" ); + %this.registerMissionObject( "TerrainBlock", "Terrain Block" ); + %this.registerMissionObject( "GroundPlane", "Ground Plane" ); + %this.registerMissionObject( "WaterPlane", "Water Plane" ); + %this.registerMissionObject( "PxCloth", "Cloth" ); + %this.registerMissionObject( "ForestWindEmitter", "Wind Emitter" ); + + %this.registerMissionObject( "DustEmitter", "Dust Emitter" ); + %this.registerMissionObject( "DustSimulation", "Dust Simulation" ); + %this.registerMissionObject( "DustEffecter", "Dust Effecter" ); + + %this.endGroup(); + + %this.beginGroup( "Level" ); + + %this.registerMissionObject( "MissionArea", "Mission Area" ); + %this.registerMissionObject( "Path" ); + %this.registerMissionObject( "Marker", "Path Node" ); + %this.registerMissionObject( "Trigger" ); + %this.registerMissionObject( "PhysicalZone", "Physical Zone" ); + %this.registerMissionObject( "Camera" ); + %this.registerMissionObject( "LevelInfo", "Level Info" ); + %this.registerMissionObject( "TimeOfDay", "Time of Day" ); + %this.registerMissionObject( "Zone", "Zone" ); + %this.registerMissionObject( "Portal", "Zone Portal" ); + %this.registerMissionObject( "SpawnSphere", "Player Spawn Sphere", "PlayerDropPoint" ); + %this.registerMissionObject( "SpawnSphere", "Observer Spawn Sphere", "ObserverDropPoint" ); + %this.registerMissionObject( "SFXSpace", "Sound Space" ); + %this.registerMissionObject( "OcclusionVolume", "Occlusion Volume" ); + + %this.endGroup(); + + %this.beginGroup( "System" ); + + %this.registerMissionObject( "SimGroup" ); + + %this.endGroup(); + + %this.beginGroup( "ExampleObjects" ); + + %this.registerMissionObject( "RenderObjectExample" ); + %this.registerMissionObject( "RenderMeshExample" ); + %this.registerMissionObject( "RenderShapeExample" ); + + %this.endGroup(); +} + +function EWCreatorWindow::onWake( %this ) +{ + CreatorTabBook.selectPage( 0 ); + CreatorTabBook.onTabSelected( "Scripted" ); +} + +function EWCreatorWindow::beginGroup( %this, %group ) +{ + %this.currentGroup = %group; +} + +function EWCreatorWindow::endGroup( %this, %group ) +{ + %this.currentGroup = ""; +} + +function EWCreatorWindow::getCreateObjectPosition() +{ + %focusPoint = LocalClientConnection.getControlObject().getLookAtPoint(); + if( %focusPoint $= "" ) + return "0 0 0"; + else + return getWord( %focusPoint, 1 ) SPC getWord( %focusPoint, 2 ) SPC getWord( %focusPoint, 3 ); +} + +function EWCreatorWindow::registerMissionObject( %this, %class, %name, %buildfunc, %group ) +{ + if( !isClass(%class) ) + return; + + if ( %name $= "" ) + %name = %class; + if ( %this.currentGroup !$= "" && %group $= "" ) + %group = %this.currentGroup; + + if ( %class $= "" || %group $= "" ) + { + warn( "EWCreatorWindow::registerMissionObject, invalid parameters!" ); + return; + } + + %args = new ScriptObject(); + %args.val[0] = %class; + %args.val[1] = %name; + %args.val[2] = %buildfunc; + + %this.array.push_back( %group, %args ); +} + +function EWCreatorWindow::getNewObjectGroup( %this ) +{ + return %this.objectGroup; +} + +function EWCreatorWindow::setNewObjectGroup( %this, %group ) +{ + if( %this.objectGroup ) + { + %oldItemId = EditorTree.findItemByObjectId( %this.objectGroup ); + if( %oldItemId > 0 ) + EditorTree.markItem( %oldItemId, false ); + } + + %group = %group.getID(); + %this.objectGroup = %group; + %itemId = EditorTree.findItemByObjectId( %group ); + EditorTree.markItem( %itemId ); +} + +function EWCreatorWindow::createInterior( %this, %file ) +{ + if ( !$missionRunning ) + return; + + if(isFunction("getObjectLimit") && MissionGroup.getFullCount() >= getObjectLimit()) + { + MessageBoxOKBuy( "Object Limit Reached", "You have exceeded the object limit of " @ getObjectLimit() @ " for this demo. You can remove objects if you would like to add more.", "", "Canvas.showPurchaseScreen(\"objectlimit\");" ); + return; + } + + if( !isObject(%this.objectGroup) ) + %this.setNewObjectGroup( MissionGroup ); + + %objId = new InteriorInstance() + { + position = %this.getCreateObjectPosition(); + rotation = "0 0 0"; + interiorFile = %file; + parentGroup = %this.objectGroup; + }; + + %this.onObjectCreated( %objId ); +} + +function EWCreatorWindow::createStatic( %this, %file ) +{ + if ( !$missionRunning ) + return; + + if(isFunction("getObjectLimit") && MissionGroup.getFullCount() >= getObjectLimit()) + { + MessageBoxOKBuy( "Object Limit Reached", "You have exceeded the object limit of " @ getObjectLimit() @ " for this demo. You can remove objects if you would like to add more.", "", "Canvas.showPurchaseScreen(\"objectlimit\");" ); + return; + } + + if( !isObject(%this.objectGroup) ) + %this.setNewObjectGroup( MissionGroup ); + + %objId = new TSStatic() + { + shapeName = %file; + position = %this.getCreateObjectPosition(); + parentGroup = %this.objectGroup; + }; + + %this.onObjectCreated( %objId ); +} + +function EWCreatorWindow::createPrefab( %this, %file ) +{ + if ( !$missionRunning ) + return; + + if(isFunction("getObjectLimit") && MissionGroup.getFullCount() >= getObjectLimit()) + { + MessageBoxOKBuy( "Object Limit Reached", "You have exceeded the object limit of " @ getObjectLimit() @ " for this demo. You can remove objects if you would like to add more.", "", "Canvas.showPurchaseScreen(\"objectlimit\");" ); + return; + } + + if( !isObject(%this.objectGroup) ) + %this.setNewObjectGroup( MissionGroup ); + + %objId = new Prefab() + { + filename = %file; + position = %this.getCreateObjectPosition(); + parentGroup = %this.objectGroup; + }; + + %this.onObjectCreated( %objId ); +} + +function EWCreatorWindow::createObject( %this, %cmd ) +{ + if ( !$missionRunning ) + return; + + if(isFunction("getObjectLimit") && MissionGroup.getFullCount() >= getObjectLimit()) + { + MessageBoxOKBuy( "Object Limit Reached", "You have exceeded the object limit of " @ getObjectLimit() @ " for this demo. You can remove objects if you would like to add more.", "", "Canvas.showPurchaseScreen(\"objectlimit\");" ); + return; + } + + if( !isObject(%this.objectGroup) ) + %this.setNewObjectGroup( MissionGroup ); + + pushInstantGroup(); + %objId = eval(%cmd); + popInstantGroup(); + + if( isObject( %objId ) ) + %this.onFinishCreateObject( %objId ); + + return %objId; +} + +function EWCreatorWindow::onFinishCreateObject( %this, %objId ) +{ + %this.objectGroup.add( %objId ); + + if( %objId.isMemberOfClass( "SceneObject" ) ) + { + %objId.position = %this.getCreateObjectPosition(); + + //flush new position + %objId.setTransform( %objId.getTransform() ); + } + + %this.onObjectCreated( %objId ); +} + +function EWCreatorWindow::onObjectCreated( %this, %objId ) +{ + // Can we submit an undo action? + if ( isObject( %objId ) ) + MECreateUndoAction::submit( %objId ); + + EditorTree.clearSelection(); + EWorldEditor.clearSelection(); + EWorldEditor.selectObject( %objId ); + + // When we drop the selection don't store undo + // state for it... the creation deals with it. + EWorldEditor.dropSelection( true ); +} + +function CreatorTabBook::onTabSelected( %this, %text, %idx ) +{ + if ( %this.isAwake() ) + { + EWCreatorWindow.tab = %text; + EWCreatorWindow.navigate( "" ); + } +} + +function EWCreatorWindow::navigate( %this, %address ) +{ + CreatorIconArray.frozen = true; + CreatorIconArray.clear(); + CreatorPopupMenu.clear(); + + if ( %this.tab $= "Scripted" ) + { + %category = getWord( %address, 1 ); + %dataGroup = "DataBlockGroup"; + + for ( %i = 0; %i < %dataGroup.getCount(); %i++ ) + { + %obj = %dataGroup.getObject(%i); + // echo ("Obj: " @ %obj.getName() @ " - " @ %obj.category ); + + if ( %obj.category $= "" && %obj.category == 0 ) + continue; + + // Add category to popup menu if not there already + if ( CreatorPopupMenu.findText( %obj.category ) == -1 ) + CreatorPopupMenu.add( %obj.category ); + + if ( %address $= "" ) + { + %ctrl = %this.findIconCtrl( %obj.category ); + if ( %ctrl == -1 ) + { + %this.addFolderIcon( %obj.category ); + } + } + else if ( %address $= %obj.category ) + { + %ctrl = %this.findIconCtrl( %obj.getName() ); + if ( %ctrl == -1 ) + %this.addShapeIcon( %obj ); + } + } + } + + if ( %this.tab $= "Meshes" ) + { + %fullPath = findFirstFileMultiExpr( "*.dts" TAB "*.dae" TAB "*.kmz" TAB "*.dif" ); + + while ( %fullPath !$= "" ) + { + if (strstr(%fullPath, "cached.dts") != -1) + { + %fullPath = findNextFileMultiExpr( "*.dts" TAB "*.dae" TAB "*.kmz" TAB "*.dif" ); + continue; + } + + %fullPath = makeRelativePath( %fullPath, getMainDotCSDir() ); + %splitPath = strreplace( %fullPath, "/", " " ); + if( getWord(%splitPath, 0) $= "tools" ) + { + %fullPath = findNextFileMultiExpr( "*.dts" TAB "*.dae" TAB "*.kmz" TAB "*.dif" ); + continue; + } + + %dirCount = getWordCount( %splitPath ) - 1; + + %pathFolders = getWords( %splitPath, 0, %dirCount - 1 ); + + // Add this file's path (parent folders) to the + // popup menu if it isn't there yet. + %temp = strreplace( %pathFolders, " ", "/" ); + %r = CreatorPopupMenu.findText( %temp ); + if ( %r == -1 ) + { + CreatorPopupMenu.add( %temp ); + } + + // Is this file in the current folder? + if ( stricmp( %pathFolders, %address ) == 0 ) + { + if ( fileExt( %fullPath ) $= ".dif" ) + %this.addInteriorIcon( %fullPath ); + else + %this.addStaticIcon( %fullPath ); + } + // Then is this file in a subfolder we need to add + // a folder icon for? + else + { + %wordIdx = 0; + %add = false; + + if ( %address $= "" ) + { + %add = true; + %wordIdx = 0; + } + else + { + for ( ; %wordIdx < %dirCount; %wordIdx++ ) + { + %temp = getWords( %splitPath, 0, %wordIdx ); + if ( stricmp( %temp, %address ) == 0 ) + { + %add = true; + %wordIdx++; + break; + } + } + } + + if ( %add == true ) + { + %folder = getWord( %splitPath, %wordIdx ); + + %ctrl = %this.findIconCtrl( %folder ); + if ( %ctrl == -1 ) + %this.addFolderIcon( %folder ); + } + } + + %fullPath = findNextFileMultiExpr( "*.dts" TAB "*.dae" TAB "*.kmz" TAB "*.dif" ); + } + } + + if ( %this.tab $= "Level" ) + { + // Add groups to popup menu + %array = %this.array; + %array.sortk(); + + %count = %array.count(); + + if ( %count > 0 ) + { + %lastGroup = ""; + + for ( %i = 0; %i < %count; %i++ ) + { + %group = %array.getKey( %i ); + + if ( %group !$= %lastGroup ) + { + CreatorPopupMenu.add( %group ); + + if ( %address $= "" ) + %this.addFolderIcon( %group ); + } + + if ( %address $= %group ) + { + %args = %array.getValue( %i ); + %class = %args.val[0]; + %name = %args.val[1]; + %func = %args.val[2]; + + %this.addMissionObjectIcon( %class, %name, %func ); + } + + %lastGroup = %group; + } + } + } + + if ( %this.tab $= "Prefabs" ) + { + %expr = "*.prefab"; + %fullPath = findFirstFile( %expr ); + + while ( %fullPath !$= "" ) + { + %fullPath = makeRelativePath( %fullPath, getMainDotCSDir() ); + %splitPath = strreplace( %fullPath, "/", " " ); + if( getWord(%splitPath, 0) $= "tools" ) + { + %fullPath = findNextFile( %expr ); + continue; + } + + %dirCount = getWordCount( %splitPath ) - 1; + + %pathFolders = getWords( %splitPath, 0, %dirCount - 1 ); + + // Add this file's path (parent folders) to the + // popup menu if it isn't there yet. + %temp = strreplace( %pathFolders, " ", "/" ); + %r = CreatorPopupMenu.findText( %temp ); + if ( %r == -1 ) + { + CreatorPopupMenu.add( %temp ); + } + + // Is this file in the current folder? + if ( stricmp( %pathFolders, %address ) == 0 ) + { + %this.addPrefabIcon( %fullPath ); + } + // Then is this file in a subfolder we need to add + // a folder icon for? + else + { + %wordIdx = 0; + %add = false; + + if ( %address $= "" ) + { + %add = true; + %wordIdx = 0; + } + else + { + for ( ; %wordIdx < %dirCount; %wordIdx++ ) + { + %temp = getWords( %splitPath, 0, %wordIdx ); + if ( stricmp( %temp, %address ) == 0 ) + { + %add = true; + %wordIdx++; + break; + } + } + } + + if ( %add == true ) + { + %folder = getWord( %splitPath, %wordIdx ); + + %ctrl = %this.findIconCtrl( %folder ); + if ( %ctrl == -1 ) + %this.addFolderIcon( %folder ); + } + } + + %fullPath = findNextFile( %expr ); + } + } + + CreatorIconArray.sort( "alphaIconCompare" ); + + for ( %i = 0; %i < CreatorIconArray.getCount(); %i++ ) + { + CreatorIconArray.getObject(%i).autoSize = false; + } + + CreatorIconArray.frozen = false; + CreatorIconArray.refresh(); + + // Recalculate the array for the parent guiScrollCtrl + CreatorIconArray.getParent().computeSizes(); + + %this.address = %address; + + CreatorPopupMenu.sort(); + + %str = strreplace( %address, " ", "/" ); + %r = CreatorPopupMenu.findText( %str ); + if ( %r != -1 ) + CreatorPopupMenu.setSelected( %r, false ); + else + CreatorPopupMenu.setText( %str ); + CreatorPopupMenu.tooltip = %str; +} + +function EWCreatorWindow::navigateDown( %this, %folder ) +{ + if ( %this.address $= "" ) + %address = %folder; + else + %address = %this.address SPC %folder; + + // Because this is called from an IconButton::onClick command + // we have to wait a tick before actually calling navigate, else + // we would delete the button out from under itself. + %this.schedule( 1, "navigate", %address ); +} + +function EWCreatorWindow::navigateUp( %this ) +{ + %count = getWordCount( %this.address ); + + if ( %count == 0 ) + return; + + if ( %count == 1 ) + %address = ""; + else + %address = getWords( %this.address, 0, %count - 2 ); + + %this.navigate( %address ); +} + +function EWCreatorWindow::setListView( %this, %noupdate ) +{ + //CreatorIconArray.clear(); + //CreatorIconArray.setVisible( false ); + + CreatorIconArray.setVisible( true ); + %this.contentCtrl = CreatorIconArray; + %this.isList = true; + + if ( %noupdate == true ) + %this.navigate( %this.address ); +} + +//function EWCreatorWindow::setIconView( %this ) +//{ + //echo( "setIconView" ); + // + //CreatorIconStack.clear(); + //CreatorIconStack.setVisible( false ); + // + //CreatorIconArray.setVisible( true ); + //%this.contentCtrl = CreatorIconArray; + //%this.isList = false; + // + //%this.navigate( %this.address ); +//} + +function EWCreatorWindow::findIconCtrl( %this, %name ) +{ + for ( %i = 0; %i < %this.contentCtrl.getCount(); %i++ ) + { + %ctrl = %this.contentCtrl.getObject( %i ); + if ( %ctrl.text $= %name ) + return %ctrl; + } + + return -1; +} + +function EWCreatorWindow::createIcon( %this ) +{ + %ctrl = new GuiIconButtonCtrl() + { + profile = "GuiCreatorIconButtonProfile"; + buttonType = "radioButton"; + groupNum = "-1"; + }; + + if ( %this.isList ) + { + %ctrl.iconLocation = "Left"; + %ctrl.textLocation = "Right"; + %ctrl.extent = "348 19"; + %ctrl.textMargin = 8; + %ctrl.buttonMargin = "2 2"; + %ctrl.autoSize = true; + } + else + { + %ctrl.iconLocation = "Center"; + %ctrl.textLocation = "Bottom"; + %ctrl.extent = "40 40"; + } + + return %ctrl; +} + +function EWCreatorWindow::addFolderIcon( %this, %text ) +{ + %ctrl = %this.createIcon(); + + %ctrl.altCommand = "EWCreatorWindow.navigateDown(\"" @ %text @ "\");"; + %ctrl.iconBitmap = "core/art/gui/images/folder.png"; + %ctrl.text = %text; + %ctrl.tooltip = %text; + %ctrl.class = "CreatorFolderIconBtn"; + + %ctrl.buttonType = "radioButton"; + %ctrl.groupNum = "-1"; + + %this.contentCtrl.addGuiControl( %ctrl ); +} + +function EWCreatorWindow::addMissionObjectIcon( %this, %class, %name, %buildfunc ) +{ + %ctrl = %this.createIcon(); + + // If we don't find a specific function for building an + // object then fall back to the stock one + %method = "build" @ %buildfunc; + if( !ObjectBuilderGui.isMethod( %method ) ) + %method = "build" @ %class; + + if( !ObjectBuilderGui.isMethod( %method ) ) + %cmd = "return new " @ %class @ "();"; + else + %cmd = "ObjectBuilderGui." @ %method @ "();"; + + %ctrl.altCommand = "ObjectBuilderGui.newObjectCallback = \"EWCreatorWindow.onFinishCreateObject\"; EWCreatorWindow.createObject( \"" @ %cmd @ "\" );"; + %ctrl.iconBitmap = EditorIconRegistry::findIconByClassName( %class ); + %ctrl.text = %name; + %ctrl.class = "CreatorMissionObjectIconBtn"; + %ctrl.tooltip = %class; + + %ctrl.buttonType = "radioButton"; + %ctrl.groupNum = "-1"; + + %this.contentCtrl.addGuiControl( %ctrl ); +} + +function EWCreatorWindow::addShapeIcon( %this, %datablock ) +{ + %ctrl = %this.createIcon(); + + %name = %datablock.getName(); + %class = %datablock.getClassName(); + %cmd = %class @ "::create(" @ %name @ ");"; + + %shapePath = ( %datablock.shapeFile !$= "" ) ? %datablock.shapeFile : %datablock.shapeName; + + %createCmd = "EWCreatorWindow.createObject( \\\"" @ %cmd @ "\\\" );"; + %ctrl.altCommand = "ColladaImportDlg.showDialog( \"" @ %shapePath @ "\", \"" @ %createCmd @ "\" );"; + + %ctrl.iconBitmap = EditorIconRegistry::findIconByClassName( %class ); + %ctrl.text = %name; + %ctrl.class = "CreatorShapeIconBtn"; + %ctrl.tooltip = %name; + + %ctrl.buttonType = "radioButton"; + %ctrl.groupNum = "-1"; + + %this.contentCtrl.addGuiControl( %ctrl ); +} + +function EWCreatorWindow::addStaticIcon( %this, %fullPath ) +{ + %ctrl = %this.createIcon(); + + %ext = fileExt( %fullPath ); + %file = fileBase( %fullPath ); + %fileLong = %file @ %ext; + %tip = %fileLong NL + "Size: " @ fileSize( %fullPath ) / 1000.0 SPC "KB" NL + "Date Created: " @ fileCreatedTime( %fullPath ) NL + "Last Modified: " @ fileModifiedTime( %fullPath ); + + %createCmd = "EWCreatorWindow.createStatic( \\\"" @ %fullPath @ "\\\" );"; + %ctrl.altCommand = "ColladaImportDlg.showDialog( \"" @ %fullPath @ "\", \"" @ %createCmd @ "\" );"; + + %ctrl.iconBitmap = ( ( %ext $= ".dts" ) ? EditorIconRegistry::findIconByClassName( "TSStatic" ) : "tools/gui/images/iconCollada" ); + %ctrl.text = %file; + %ctrl.class = "CreatorStaticIconBtn"; + %ctrl.tooltip = %tip; + + %ctrl.buttonType = "radioButton"; + %ctrl.groupNum = "-1"; + + %this.contentCtrl.addGuiControl( %ctrl ); +} + +function EWCreatorWindow::addInteriorIcon( %this, %fullPath ) +{ + %ctrl = EWCreatorWindow.createIcon(); + + %file = fileBase( %fullPath ); + %fileLong = %file @ fileExt( %fullPath ); + + %tip = %fileLong NL + "Size: " @ fileSize( %fullPath ) / 1000.0 SPC "KB" NL + "Date Created: " @ fileCreatedTime( %fullPath ) NL + "Last Modified: " @ fileModifiedTime( %fullPath ); + + %ctrl.altCommand = "EWCreatorWindow.createInterior( \"" @ %fullPath @ "\" );"; + %ctrl.iconBitmap = EditorIconRegistry::findIconByClassName( "InteriorInstance" ); + %ctrl.text = %file; + %ctrl.class = "CreatorInteriorIconBtn"; + %ctrl.tooltip = %tip; + + %ctrl.buttonType = "radioButton"; + %ctrl.groupNum = "-1"; + + %this.contentCtrl.addGuiControl( %ctrl ); +} + +function EWCreatorWindow::addPrefabIcon( %this, %fullPath ) +{ + %ctrl = %this.createIcon(); + + %ext = fileExt( %fullPath ); + %file = fileBase( %fullPath ); + %fileLong = %file @ %ext; + %tip = %fileLong NL + "Size: " @ fileSize( %fullPath ) / 1000.0 SPC "KB" NL + "Date Created: " @ fileCreatedTime( %fullPath ) NL + "Last Modified: " @ fileModifiedTime( %fullPath ); + + %ctrl.altCommand = "EWCreatorWindow.createPrefab( \"" @ %fullPath @ "\" );"; + %ctrl.iconBitmap = EditorIconRegistry::findIconByClassName( "Prefab" ); + %ctrl.text = %file; + %ctrl.class = "CreatorPrefabIconBtn"; + %ctrl.tooltip = %tip; + + %ctrl.buttonType = "radioButton"; + %ctrl.groupNum = "-1"; + + %this.contentCtrl.addGuiControl( %ctrl ); +} + +function CreatorPopupMenu::onSelect( %this, %id, %text ) +{ + %split = strreplace( %text, "/", " " ); + EWCreatorWindow.navigate( %split ); +} + +function alphaIconCompare( %a, %b ) +{ + if ( %a.class $= "CreatorFolderIconBtn" ) + if ( %b.class !$= "CreatorFolderIconBtn" ) + return -1; + + if ( %b.class $= "CreatorFolderIconBtn" ) + if ( %a.class !$= "CreatorFolderIconBtn" ) + return 1; + + %result = stricmp( %a.text, %b.text ); + return %result; +} + +// Generic create object helper for use from the console. + +function genericCreateObject( %class ) +{ + if ( !isClass( %class ) ) + { + warn( "createObject( " @ %class @ " ) - Was not a valid class." ); + return; + } + + %cmd = "return new " @ %class @ "();"; + + %obj = EWCreatorWindow.createObject( %cmd ); + + // In case the caller wants it. + return %obj; +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/worldEditor/scripts/editors/missionArea.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/editors/missionArea.ed.cs new file mode 100644 index 000000000..a2b3f90a9 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/editors/missionArea.ed.cs @@ -0,0 +1,30 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function AreaEditor::onUpdate(%this, %area) +{ + AreaEditingText.setValue( "X: " @ getWord(%area,0) @ " Y: " @ getWord(%area,1) @ " W: " @ getWord(%area,2) @ " H: " @ getWord(%area,3)); +} + +function AreaEditor::onWorldOffset(%this, %offset) +{ +} diff --git a/Templates/Empty/game/tools/worldEditor/scripts/editors/terrainEditor.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/editors/terrainEditor.ed.cs new file mode 100644 index 000000000..c06822d1c --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/editors/terrainEditor.ed.cs @@ -0,0 +1,478 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +/// The texture filename filter used with OpenFileDialog. +$TerrainEditor::TextureFileSpec = "Image Files (*.png, *.jpg, *.dds)|*.png;*.jpg;*.dds|All Files (*.*)|*.*|"; + +function TerrainEditor::init( %this ) +{ + %this.attachTerrain(); + %this.setBrushSize( 9, 9 ); + + new PersistenceManager( ETerrainPersistMan ); +} + +/// +function EPainter_TerrainMaterialUpdateCallback( %mat, %matIndex ) +{ + // Skip over a bad selection. + if ( %matIndex == -1 || !isObject( %mat ) ) + return; + + // Update the material and the UI. + ETerrainEditor.updateMaterial( %matIndex, %mat.getInternalName() ); + EPainter.setup( %matIndex ); +} + +function EPainter_TerrainMaterialAddCallback( %mat, %matIndex ) +{ + // Ignore bad materials. + if ( !isObject( %mat ) ) + return; + + // Add it and update the UI. + ETerrainEditor.addMaterial( %mat.getInternalName() ); + EPainter.setup( %matIndex ); +} + +function TerrainEditor::setPaintMaterial( %this, %matIndex, %terrainMat ) +{ + assert( isObject( %terrainMat ), "TerrainEditor::setPaintMaterial - Got bad material!" ); + + ETerrainEditor.paintIndex = %matIndex; + ETerrainMaterialSelected.selectedMatIndex = %matIndex; + ETerrainMaterialSelected.selectedMat = %terrainMat; + ETerrainMaterialSelected.bitmap = %terrainMat.diffuseMap; + ETerrainMaterialSelectedEdit.Visible = isObject(%terrainMat); + TerrainTextureText.text = %terrainMat.getInternalName(); +} + +function TerrainEditor::setup( %this ) +{ + %action = %this.savedAction; + %desc = %this.savedActionDesc; + if ( %this.savedAction $= "" ) + { + %action = brushAdjustHeight; + } + + %this.switchAction( %action ); +} + +function EPainter::updateLayers( %this, %matIndex ) +{ + // Default to whatever was selected before. + if ( %matIndex $= "" ) + %matIndex = ETerrainEditor.paintIndex; + + // The material string is a newline seperated string of + // TerrainMaterial internal names which we can use to find + // the actual material data in TerrainMaterialSet. + + %mats = ETerrainEditor.getMaterials(); + + %matList = %this-->theMaterialList; + %matList.deleteAllObjects(); + %listWidth = getWord( %matList.getExtent(), 0 ); + + for( %i = 0; %i < getRecordCount( %mats ); %i++ ) + { + %matInternalName = getRecord( %mats, %i ); + %mat = TerrainMaterialSet.findObjectByInternalName( %matInternalName ); + + // Is there no material info for this slot? + if ( !isObject( %mat ) ) + continue; + + %index = %matList.getCount(); + %command = "ETerrainEditor.setPaintMaterial( " @ %index @ ", " @ %mat @ " );"; + %altCommand = "TerrainMaterialDlg.show( " @ %index @ ", " @ %mat @ ", EPainter_TerrainMaterialUpdateCallback );"; + + %ctrl = new GuiIconButtonCtrl() + { + class = "EPainterIconBtn"; + internalName = "EPainterMaterialButton" @ %i; + profile = "GuiCreatorIconButtonProfile"; + iconLocation = "Left"; + textLocation = "Right"; + extent = %listWidth SPC "46"; + textMargin = 5; + buttonMargin = "4 4"; + buttonType = "RadioButton"; + sizeIconToButton = true; + makeIconSquare = true; + tooltipprofile = "GuiToolTipProfile"; + command = %command; + altCommand = %altCommand; + useMouseEvents = true; + + new GuiBitmapButtonCtrl() + { + bitmap = "tools/gui/images/delete"; + buttonType = "PushButton"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = ( %listwidth - 20 ) SPC "26"; + Extent = "17 17"; + command = "EPainter.showMaterialDeleteDlg( " @ %matInternalName @ " );"; + }; + }; + + %ctrl.setText( %matInternalName ); + %ctrl.setBitmap( %mat.diffuseMap ); + + %tooltip = %matInternalName; + if(%i < 9) + %tooltip = %tooltip @ " (" @ (%i+1) @ ")"; + else if(%i == 9) + %tooltip = %tooltip @ " (0)"; + %ctrl.tooltip = %tooltip; + + %matList.add( %ctrl ); + } + + %matCount = %matList.getCount(); + + // Add one more layer as the 'add new' layer. + %ctrl = new GuiIconButtonCtrl() + { + profile = "GuiCreatorIconButtonProfile"; + iconBitmap = "~/worldEditor/images/terrainpainter/new_layer_icon"; + iconLocation = "Left"; + textLocation = "Right"; + extent = %listWidth SPC "46"; + textMargin = 5; + buttonMargin = "4 4"; + buttonType = "PushButton"; + sizeIconToButton = true; + makeIconSquare = true; + tooltipprofile = "GuiToolTipProfile"; + text = "New Layer"; + tooltip = "New Layer"; + command = "TerrainMaterialDlg.show( " @ %matCount @ ", 0, EPainter_TerrainMaterialAddCallback );"; + }; + %matList.add( %ctrl ); + + // Make sure our selection is valid and that we're + // not selecting the 'New Layer' button. + + if( %matIndex < 0 ) + return; + if( %matIndex >= %matCount ) + %matIndex = 0; + + // To make things simple... click the paint material button to + // active it and initialize other state. + %ctrl = %matList.getObject( %matIndex ); + %ctrl.performClick(); +} + +function EPainter::showMaterialDeleteDlg( %this, %matInternalName ) +{ + MessageBoxYesNo( "Confirmation", + "Really remove material '" @ %matInternalName @ "' from the terrain?", + %this @ ".removeMaterial( " @ %matInternalName @ " );", "" ); +} + +function EPainter::removeMaterial( %this, %matInternalName ) +{ + %selIndex = ETerrainEditor.paintIndex - 1; + + // Remove the material from the terrain. + + %index = ETerrainEditor.getMaterialIndex( %matInternalName ); + if( %index != -1 ) + ETerrainEditor.removeMaterial( %index ); + + // Update the material list. + + %this.updateLayers( %selIndex ); +} + +function EPainter::setup( %this, %matIndex ) +{ + // Update the layer listing. + %this.updateLayers( %matIndex ); + + // Automagically put us into material paint mode. + ETerrainEditor.currentMode = "paint"; + ETerrainEditor.selectionHidden = true; + ETerrainEditor.currentAction = paintMaterial; + ETerrainEditor.currentActionDesc = "Paint material on terrain"; + ETerrainEditor.setAction( ETerrainEditor.currentAction ); + EditorGuiStatusBar.setInfo(ETerrainEditor.currentActionDesc); + ETerrainEditor.renderVertexSelection = true; +} + +function onNeedRelight() +{ + if( RelightMessage.visible == false ) + RelightMessage.visible = true; +} + +function TerrainEditor::onGuiUpdate(%this, %text) +{ + %minHeight = getWord(%text, 1); + %avgHeight = getWord(%text, 2); + %maxHeight = getWord(%text, 3); + + %mouseBrushInfo = " (Mouse) #: " @ getWord(%text, 0) @ " avg: " @ %avgHeight @ " " @ ETerrainEditor.currentAction; + %selectionInfo = " (Selected) #: " @ getWord(%text, 4) @ " avg: " @ getWord(%text, 5); + + TEMouseBrushInfo.setValue(%mouseBrushInfo); + TEMouseBrushInfo1.setValue(%mouseBrushInfo); + TESelectionInfo.setValue(%selectionInfo); + TESelectionInfo1.setValue(%selectionInfo); + + EditorGuiStatusBar.setSelection("min: " @ %minHeight @ " avg: " @ %avgHeight @ " max: " @ %maxHeight); +} + +function TerrainEditor::onBrushChanged( %this ) +{ + EditorGui.currentEditor.syncBrushInfo(); +} + +function TerrainEditor::toggleBrushType( %this, %brush ) +{ + %this.setBrushType( %brush.internalName ); +} + +function TerrainEditor::offsetBrush(%this, %x, %y) +{ + %curPos = %this.getBrushPos(); + %this.setBrushPos(getWord(%curPos, 0) + %x, getWord(%curPos, 1) + %y); +} + +function TerrainEditor::onActiveTerrainChange(%this, %newTerrain) +{ + // Need to refresh the terrain painter. + if ( EditorGui.currentEditor.getId() == TerrainPainterPlugin.getId() ) + EPainter.setup(ETerrainEditor.paintIndex); +} + +function TerrainEditor::getActionDescription( %this, %action ) +{ + switch$( %action ) + { + case "brushAdjustHeight": + return "Adjust terrain height up or down."; + + case "raiseHeight": + return "Raise terrain height."; + + case "lowerHeight": + return "Lower terrain height."; + + case "smoothHeight": + return "Smooth terrain."; + + case "paintNoise": + return "Modify terrain height using noise."; + + case "flattenHeight": + return "Flatten terrain."; + + case "setHeight": + return "Set terrain height to defined value."; + + case "setEmpty": + return "Remove terrain collision."; + + case "clearEmpty": + return "Add back terrain collision."; + + default: + return ""; + } +} + +/// This is only ment for terrain editing actions and not +/// processed actions or the terrain material painting action. +function TerrainEditor::switchAction( %this, %action ) +{ + %actionDesc = %this.getActionDescription(%action); + + %this.currentMode = "paint"; + %this.selectionHidden = true; + %this.currentAction = %action; + %this.currentActionDesc = %actionDesc; + %this.savedAction = %action; + %this.savedActionDesc = %actionDesc; + + if ( %action $= "setEmpty" || + %action $= "clearEmpty" || + %action $= "setHeight" ) + %this.renderSolidBrush = true; + else + %this.renderSolidBrush = false; + + EditorGuiStatusBar.setInfo(%actionDesc); + + %this.setAction( %this.currentAction ); +} + +function TerrainEditor::onSmoothHeightmap( %this ) +{ + if ( !%this.getActiveTerrain() ) + return; + + // Show the dialog first and let the user + // set the smoothing parameters. + + + + // Now create the terrain smoothing action to + // get the work done and perform later undos. + %action = new TerrainSmoothAction(); + %action.smooth( %this.getActiveTerrain(), 1.0, 1 ); + %action.addToManager( Editor.getUndoManager() ); +} + +function TerrainEditor::onMaterialUndo( %this ) +{ + // Update the gui to reflect the current materials. + EPainter.updateLayers(); +} + +//------------------------------------------------------------------------------ +// Functions +//------------------------------------------------------------------------------ + +function TerrainEditorSettingsGui::onWake(%this) +{ + TESoftSelectFilter.setValue(ETerrainEditor.softSelectFilter); +} + +function TerrainEditorSettingsGui::onSleep(%this) +{ + ETerrainEditor.softSelectFilter = TESoftSelectFilter.getValue(); +} + +function TESettingsApplyButton::onAction(%this) +{ + ETerrainEditor.softSelectFilter = TESoftSelectFilter.getValue(); + ETerrainEditor.resetSelWeights(true); + ETerrainEditor.processAction("softSelect"); +} + +function getPrefSetting(%pref, %default) +{ + // + if(%pref $= "") + return(%default); + else + return(%pref); +} + +function TerrainEditorPlugin::setEditorFunction(%this) +{ + %terrainExists = parseMissionGroup( "TerrainBlock" ); + + if( %terrainExists == false ) + MessageBoxYesNoCancel("No Terrain","Would you like to create a New Terrain?", "Canvas.pushDialog(CreateNewTerrainGui);"); + + return %terrainExists; +} + +function TerrainPainterPlugin::setEditorFunction(%this, %overrideGroup) +{ + %terrainExists = parseMissionGroup( "TerrainBlock" ); + + if( %terrainExists == false ) + MessageBoxYesNoCancel("No Terrain","Would you like to create a New Terrain?", "Canvas.pushDialog(CreateNewTerrainGui);"); + + return %terrainExists; +} + +function EPainterIconBtn::onMouseDragged( %this ) +{ + %payload = new GuiControl() + { + profile = GuiCreatorIconButtonProfile; + position = "0 0"; + extent = %this.extent.x SPC "5"; + dragSourceControl = %this; + }; + + %xOffset = getWord( %payload.extent, 0 ) / 2; + %yOffset = getWord( %payload.extent, 1 ) / 2; + %cursorpos = Canvas.getCursorPos(); + %xPos = getWord( %cursorpos, 0 ) - %xOffset; + %yPos = getWord( %cursorpos, 1 ) - %yOffset; + + // Create the drag control. + + %ctrl = new GuiDragAndDropControl() + { + canSaveDynamicFields = "0"; + Profile = EPainterDragDropProfile; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = %xPos SPC %yPos; + extent = %payload.extent; + MinExtent = "4 4"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + deleteOnMouseUp = true; + }; + + %ctrl.add( %payload ); + + Canvas.getContent().add( %ctrl ); + %ctrl.startDragging( %xOffset, %yOffset ); +} + +function EPainterIconBtn::onControlDragged( %this, %payload ) +{ + %payload.getParent().position = %this.getGlobalPosition(); +} + +function EPainterIconBtn::onControlDropped( %this, %payload ) +{ + %srcBtn = %payload.dragSourceControl; + %dstBtn = %this; + %stack = %this.getParent(); + + // Not dropped on a valid Button. + // Really this shouldnt happen since we are in a callback on our specialized + // EPainterIconBtn namespace. + if ( %stack != %dstBtn.getParent() || %stack != EPainterStack.getId() ) + { + echo( "Not dropped on valid control" ); + return; + } + + // Dropped on the original control, no order change. + // Simulate a click on the control, instead of a drag/drop. + if ( %srcBtn == %dstBtn ) + { + %dstBtn.performClick(); + return; + } + + %dstIndex = %stack.getObjectIndex( %dstBtn ); + ETerrainEditor.reorderMaterial( %stack.getObjectIndex( %srcBtn ), %dstIndex ); + + // select the button/material we just reordered. + %stack.getObject( %dstIndex ).performClick(); +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/worldEditor/scripts/editors/worldEditor.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/editors/worldEditor.ed.cs new file mode 100644 index 000000000..ffb16f9a4 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/editors/worldEditor.ed.cs @@ -0,0 +1,483 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function WorldEditor::onSelect( %this, %obj ) +{ + EditorTree.addSelection( %obj ); + + _setShadowVizLight( %obj ); + + //Inspector.inspect( %obj ); + + if ( isObject( %obj ) && %obj.isMethod( "onEditorSelect" ) ) + %obj.onEditorSelect( %this.getSelectionSize() ); + + EditorGui.currentEditor.onObjectSelected( %obj ); + + // Inform the camera + commandToServer('EditorOrbitCameraSelectChange', %this.getSelectionSize(), %this.getSelectionCentroid()); + + EditorGuiStatusBar.setSelectionObjectsByCount(%this.getSelectionSize()); + + // Update the materialEditorList + $Tools::materialEditorList = %obj.getId(); + + // Used to help the Material Editor( the M.E doesn't utilize its own TS control ) + // so this dirty extension is used to fake it + if ( MaterialEditorPreviewWindow.isVisible() ) + MaterialEditorGui.prepareActiveObject(); + + // Update the Transform Selection window + ETransformSelection.onSelectionChanged(); +} + +function WorldEditor::onMultiSelect( %this, %set ) +{ + // This is called when completing a drag selection ( on3DMouseUp ) + // so we can avoid calling onSelect for every object. We can only + // do most of this stuff, like inspecting, on one object at a time anyway. + + %count = %set.getCount(); + %i = 0; + + foreach( %obj in %set ) + { + if ( %obj.isMethod( "onEditorSelect" ) ) + %obj.onEditorSelect( %count ); + + %i ++; + EditorTree.addSelection( %obj, %i == %count ); + EditorGui.currentEditor.onObjectSelected( %obj ); + } + + // Inform the camera + commandToServer( 'EditorOrbitCameraSelectChange', %count, %this.getSelectionCentroid() ); + + EditorGuiStatusBar.setSelectionObjectsByCount( EWorldEditor.getSelectionSize() ); + + // Update the Transform Selection window, if it is + // visible. + + if( ETransformSelection.isVisible() ) + ETransformSelection.onSelectionChanged(); +} + +function WorldEditor::onUnSelect( %this, %obj ) +{ + if ( isObject( %obj ) && %obj.isMethod( "onEditorUnselect" ) ) + %obj.onEditorUnselect(); + + EditorGui.currentEditor.onObjectDeselected( %obj ); + + Inspector.removeInspect( %obj ); + EditorTree.removeSelection(%obj); + + // Inform the camera + commandToServer('EditorOrbitCameraSelectChange', %this.getSelectionSize(), %this.getSelectionCentroid()); + + EditorGuiStatusBar.setSelectionObjectsByCount(%this.getSelectionSize()); + + // Update the Transform Selection window + ETransformSelection.onSelectionChanged(); +} + +function WorldEditor::onClearSelection( %this ) +{ + EditorGui.currentEditor.onSelectionCleared(); + + EditorTree.clearSelection(); + + // Inform the camera + commandToServer('EditorOrbitCameraSelectChange', %this.getSelectionSize(), %this.getSelectionCentroid()); + + EditorGuiStatusBar.setSelectionObjectsByCount(%this.getSelectionSize()); + + // Update the Transform Selection window + ETransformSelection.onSelectionChanged(); +} + +function WorldEditor::onSelectionCentroidChanged( %this ) +{ + // Inform the camera + commandToServer('EditorOrbitCameraSelectChange', %this.getSelectionSize(), %this.getSelectionCentroid()); +} + +////////////////////////////////////////////////////////////////////////// + +function WorldEditor::init(%this) +{ + // add objclasses which we do not want to collide with + %this.ignoreObjClass(Sky, AIObjective); + + // editing modes + %this.numEditModes = 3; + %this.editMode[0] = "move"; + %this.editMode[1] = "rotate"; + %this.editMode[2] = "scale"; + + // context menu + new GuiControl(WEContextPopupDlg, EditorGuiGroup) + { + profile = "GuiModelessDialogProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + + new GuiPopUpMenuCtrl(WEContextPopup) + { + profile = "GuiScrollProfile"; + position = "0 0"; + extent = "0 0"; + minExtent = "0 0"; + maxPopupHeight = "200"; + command = "canvas.popDialog(WEContextPopupDlg);"; + }; + }; + WEContextPopup.setVisible(false); + + // Make sure we have an active selection set. + if( !%this.getActiveSelection() ) + %this.setActiveSelection( new WorldEditorSelection( EWorldEditorSelection ) ); +} + +//------------------------------------------------------------------------------ + +function WorldEditor::onDblClick(%this, %obj) +{ + // Commented out because making someone double click to do this is stupid + // and has the possibility of moving hte object + + //Inspector.inspect(%obj); + //InspectorNameEdit.setValue(%obj.getName()); +} + +function WorldEditor::onClick( %this, %obj ) +{ + Inspector.inspect( %obj ); +} + +function WorldEditor::onEndDrag( %this, %obj ) +{ + Inspector.inspect( %obj ); + Inspector.apply(); +} + +//------------------------------------------------------------------------------ + +function WorldEditor::export(%this) +{ + getSaveFilename("~/editor/*.mac|mac file", %this @ ".doExport", "selection.mac"); +} + +function WorldEditor::doExport(%this, %file) +{ + missionGroup.save("~/editor/" @ %file, true); +} + +function WorldEditor::import(%this) +{ + getLoadFilename("~/editor/*.mac|mac file", %this @ ".doImport"); +} + +function WorldEditor::doImport(%this, %file) +{ + exec("~/editor/" @ %file); +} + +function WorldEditor::onGuiUpdate(%this, %text) +{ +} + +function WorldEditor::getSelectionLockCount(%this) +{ + %ret = 0; + for(%i = 0; %i < %this.getSelectionSize(); %i++) + { + %obj = %this.getSelectedObject(%i); + if(%obj.locked) + %ret++; + } + return %ret; +} + +function WorldEditor::getSelectionHiddenCount(%this) +{ + %ret = 0; + for(%i = 0; %i < %this.getSelectionSize(); %i++) + { + %obj = %this.getSelectedObject(%i); + if(%obj.hidden) + %ret++; + } + return %ret; +} + +function WorldEditor::dropCameraToSelection(%this) +{ + if(%this.getSelectionSize() == 0) + return; + + %pos = %this.getSelectionCentroid(); + %cam = LocalClientConnection.camera.getTransform(); + + // set the pnt + %cam = setWord(%cam, 0, getWord(%pos, 0)); + %cam = setWord(%cam, 1, getWord(%pos, 1)); + %cam = setWord(%cam, 2, getWord(%pos, 2)); + + LocalClientConnection.camera.setTransform(%cam); +} + +/// Pastes the selection at the same place (used to move obj from a group to another) +function WorldEditor::moveSelectionInPlace(%this) +{ + %saveDropType = %this.dropType; + %this.dropType = "atCentroid"; + %this.copySelection(); + %this.deleteSelection(); + %this.pasteSelection(); + %this.dropType = %saveDropType; +} + +function WorldEditor::addSelectionToAddGroup(%this) +{ + for(%i = 0; %i < %this.getSelectionSize(); %i++) + { + %obj = %this.getSelectedObject(%i); + $InstantGroup.add(%obj); + } +} + +// resets the scale and rotation on the selection set +function WorldEditor::resetTransforms(%this) +{ + %this.addUndoState(); + + for(%i = 0; %i < %this.getSelectionSize(); %i++) + { + %obj = %this.getSelectedObject(%i); + %transform = %obj.getTransform(); + + %transform = setWord(%transform, 3, "0"); + %transform = setWord(%transform, 4, "0"); + %transform = setWord(%transform, 5, "1"); + %transform = setWord(%transform, 6, "0"); + + // + %obj.setTransform(%transform); + %obj.setScale("1 1 1"); + } +} + + +function WorldEditorToolbarDlg::init(%this) +{ + WorldEditorInspectorCheckBox.setValue( WorldEditorToolFrameSet.isMember( "EditorToolInspectorGui" ) ); + WorldEditorMissionAreaCheckBox.setValue( WorldEditorToolFrameSet.isMember( "EditorToolMissionAreaGui" ) ); + WorldEditorTreeCheckBox.setValue( WorldEditorToolFrameSet.isMember( "EditorToolTreeViewGui" ) ); + WorldEditorCreatorCheckBox.setValue( WorldEditorToolFrameSet.isMember( "EditorToolCreatorGui" ) ); +} + +function WorldEditor::onAddSelected(%this,%obj) +{ + EditorTree.addSelection(%obj); +} + +function WorldEditor::onWorldEditorUndo( %this ) +{ + Inspector.refresh(); +} + +function Inspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ) +{ + // The instant group will try to add our + // UndoAction if we don't disable it. + pushInstantGroup(); + + %nameOrClass = %object.getName(); + if ( %nameOrClass $= "" ) + %nameOrClass = %object.getClassname(); + + %action = new InspectorFieldUndoAction() + { + actionName = %nameOrClass @ "." @ %fieldName @ " Change"; + + objectId = %object.getId(); + fieldName = %fieldName; + fieldValue = %oldValue; + arrayIndex = %arrayIndex; + + inspectorGui = %this; + }; + + // If it's a datablock, initiate a retransmit. Don't do so + // immediately so as the actual field value will only be set + // by the inspector code after this method has returned. + + if( %object.isMemberOfClass( "SimDataBlock" ) ) + %object.schedule( 1, "reloadOnLocalClient" ); + + // Restore the instant group. + popInstantGroup(); + + %action.addToManager( Editor.getUndoManager() ); + EWorldEditor.isDirty = true; + + // Update the selection + if(EWorldEditor.getSelectionSize() > 0 && (%fieldName $= "position" || %fieldName $= "rotation" || %fieldName $= "scale")) + { + EWorldEditor.invalidateSelectionCentroid(); + } +} + +function Inspector::onFieldSelected( %this, %fieldName, %fieldTypeStr, %fieldDoc ) +{ + FieldInfoControl.setText( "<font:ArialBold:14>" @ %fieldName @ "<font:ArialItalic:14> (" @ %fieldTypeStr @ ") " NL "<font:Arial:14>" @ %fieldDoc ); +} + +// The following three methods are for fields that edit field value live and thus cannot record +// undo information during edits. For these fields, undo information is recorded in advance and +// then either queued or disarded when the field edit is finished. + +function Inspector::onInspectorPreFieldModification( %this, %fieldName, %arrayIndex ) +{ + pushInstantGroup(); + %undoManager = Editor.getUndoManager(); + + %numObjects = %this.getNumInspectObjects(); + if( %numObjects > 1 ) + %action = %undoManager.pushCompound( "Multiple Field Edit" ); + + for( %i = 0; %i < %numObjects; %i ++ ) + { + %object = %this.getInspectObject( %i ); + + %nameOrClass = %object.getName(); + if ( %nameOrClass $= "" ) + %nameOrClass = %object.getClassname(); + + %undo = new InspectorFieldUndoAction() + { + actionName = %nameOrClass @ "." @ %fieldName @ " Change"; + + objectId = %object.getId(); + fieldName = %fieldName; + fieldValue = %object.getFieldValue( %fieldName, %arrayIndex ); + arrayIndex = %arrayIndex; + + inspectorGui = %this; + }; + + if( %numObjects > 1 ) + %undo.addToManager( %undoManager ); + else + { + %action = %undo; + break; + } + } + + %this.currentFieldEditAction = %action; + popInstantGroup(); +} + +function Inspector::onInspectorPostFieldModification( %this ) +{ + if( %this.currentFieldEditAction.isMemberOfClass( "CompoundUndoAction" ) ) + { + // Finish multiple field edit. + Editor.getUndoManager().popCompound(); + } + else + { + // Queue single field undo. + %this.currentFieldEditAction.addToManager( Editor.getUndoManager() ); + } + + %this.currentFieldEditAction = ""; + EWorldEditor.isDirty = true; +} + +function Inspector::onInspectorDiscardFieldModification( %this ) +{ + %this.currentFieldEditAction.undo(); + + if( %this.currentFieldEditAction.isMemberOfClass( "CompoundUndoAction" ) ) + { + // Multiple field editor. Pop and discard. + Editor.getUndoManager().popCompound( true ); + } + else + { + // Single field edit. Just kill undo action. + %this.currentFieldEditAction.delete(); + } + + %this.currentFieldEditAction = ""; +} + +function Inspector::inspect( %this, %obj ) +{ + //echo( "inspecting: " @ %obj ); + + %name = ""; + if ( isObject( %obj ) ) + %name = %obj.getName(); + else + FieldInfoControl.setText( "" ); + + //InspectorNameEdit.setValue( %name ); + Parent::inspect( %this, %obj ); +} + +function Inspector::onBeginCompoundEdit( %this ) +{ + Editor.getUndoManager().pushCompound( "Multiple Field Edit" ); +} + +function Inspector::onEndCompoundEdit( %this ) +{ + Editor.getUndoManager().popCompound(); +} + +function Inspector::onCancelCompoundEdit( %this ) +{ + Editor.getUndoManager().popCompound( true ); +} + +function foCollaps (%this, %tab){ + switch$ (%tab){ + case "container0": + %tab.visible = "0"; + buttxon1.position = getWord(buttxon0.position, 0)+32 SPC getWord(buttxon1.position, 1); + buttxon2.position = getWord(buttxon1.position, 0)+32 SPC getWord(buttxon2.position, 1); + case "container1": + %tab.visible = "0"; + case "container2": + %tab.visible = "0"; + } +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/worldEditor/scripts/interfaces/levelInfoEditor.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/interfaces/levelInfoEditor.ed.cs new file mode 100644 index 000000000..903f14dcf --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/interfaces/levelInfoEditor.ed.cs @@ -0,0 +1,27 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- +// Define the field types for objects that link to the namespace LevelInfo +function LevelInfo::onDefineFieldTypes( %this ) +{ + %this.setFieldType("Desc", "TypeString"); + %this.setFieldType("DescLines", "TypeS32"); +} diff --git a/Templates/Empty/game/tools/worldEditor/scripts/interfaces/simObjectEditor.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/interfaces/simObjectEditor.ed.cs new file mode 100644 index 000000000..57826ae77 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/interfaces/simObjectEditor.ed.cs @@ -0,0 +1,26 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- +// Define the field types for objects that link to the namespace MissionInfo +function SimObject::onDefineFieldTypes( %this ) +{ + %this.setFieldType("Locked", "TypeBool"); +} \ No newline at end of file diff --git a/Templates/Empty/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.cs new file mode 100644 index 000000000..d55fb495a --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.cs @@ -0,0 +1,568 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::show( %this, %matIndex, %terrMat, %onApplyCallback ) +{ + Canvas.pushDialog( %this ); + + %this.matIndex = %matIndex; + %this.onApplyCallback = %onApplyCallback; + + %matLibTree = %this-->matLibTree; + %item = %matLibTree.findItemByObjectId( %terrMat ); + if ( %item != -1 ) + { + %matLibTree.selectItem( %item ); + %matLibTree.scrollVisible( %item ); + } + else + { + for( %i = 1; %i < %matLibTree.getItemCount(); %i++ ) + { + %terrMat = TerrainMaterialDlg-->matLibTree.getItemValue(%i); + if( %terrMat.getClassName() $= "TerrainMaterial" ) + { + %matLibTree.selectItem( %i, true ); + %matLibTree.scrollVisible( %i ); + break; + } + } + } +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::showByObjectId( %this, %matObjectId, %onApplyCallback ) +{ + Canvas.pushDialog( %this ); + + %this.matIndex = -1; + %this.onApplyCallback = %onApplyCallback; + + %matLibTree = %this-->matLibTree; + %matLibTree.clearSelection(); + %item = %matLibTree.findItemByObjectId( %matObjectId ); + if ( %item != -1 ) + { + %matLibTree.selectItem( %item ); + %matLibTree.scrollVisible( %item ); + } +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::onWake( %this ) +{ + if( !isObject( ETerrainMaterialPersistMan ) ) + new PersistenceManager( ETerrainMaterialPersistMan ); + + if( !isObject( TerrainMaterialDlgNewGroup ) ) + new SimGroup( TerrainMaterialDlgNewGroup ); + if( !isObject( TerrainMaterialDlgDeleteGroup ) ) + new SimGroup( TerrainMaterialDlgDeleteGroup ); + + // Snapshot the materials. + %this.snapshotMaterials(); + + // Refresh the material list. + %matLibTree = %this-->matLibTree; + %matLibTree.clear(); + + %matLibTree.open( TerrainMaterialSet, false ); + + %matLibTree.buildVisibleTree( true ); + %item = %matLibTree.getFirstRootItem(); + %matLibTree.expandItem( %item ); + + %this.activateMaterialCtrls( true ); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::onSleep( %this ) +{ + if( isObject( TerrainMaterialDlgSnapshot ) ) + TerrainMaterialDlgSnapshot.delete(); + + %this-->matLibTree.clear(); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::dialogApply( %this ) +{ + // Move all new materials we have created to the root group. + + %newCount = TerrainMaterialDlgNewGroup.getCount(); + for( %i = 0; %i < %newCount; %i ++ ) + RootGroup.add( TerrainMaterialDlgNewGroup.getObject( %i ) ); + + // Finalize deletion of all removed materials. + + %deletedCount = TerrainMaterialDlgDeleteGroup.getCount(); + for( %i = 0; %i < %deletedCount; %i ++ ) + { + %mat = TerrainMaterialDlgDeleteGroup.getObject( %i ); + ETerrainMaterialPersistMan.removeObjectFromFile( %mat ); + + %matIndex = ETerrainEditor.getMaterialIndex( %mat.internalName ); + if( %matIndex != -1 ) + { + ETerrainEditor.removeMaterial( %matIndex ); + EPainter.updateLayers(); + } + + %mat.delete(); + } + + // Make sure we save any changes to the current selection. + %this.saveDirtyMaterial( %this.activeMat ); + + // Save all changes. + ETerrainMaterialPersistMan.saveDirty(); + + // Delete the snapshot. + TerrainMaterialDlgSnapshot.delete(); + + // Remove ourselves from the canvas. + Canvas.popDialog( TerrainMaterialDlg ); + + call( %this.onApplyCallback, %this.activeMat, %this.matIndex ); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::dialogCancel( %this ) +{ + // Restore material properties we have changed. + + %this.restoreMaterials(); + + // Clear the persistence manager state. + + ETerrainMaterialPersistMan.clearAll(); + + // Delete all new object we have created. + + TerrainMaterialDlgNewGroup.clear(); + + // Restore materials we have marked for deletion. + + %deletedCount = TerrainMaterialDlgDeleteGroup.getCount(); + for( %i = 0; %i < %deletedCount; %i ++ ) + { + %mat = TerrainMaterialDlgDeleteGroup.getObject( %i ); + %mat.parentGroup = RootGroup; + TerrainMaterialSet.add( %mat ); + } + + Canvas.popDialog( TerrainMaterialDlg ); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::setMaterialName( %this, %newName ) +{ + %mat = %this.activeMat; + + if( %mat.internalName !$= %newName ) + { + %existingMat = TerrainMaterialSet.findObjectByInternalName( %newName ); + if( isObject( %existingMat ) ) + { + MessageBoxOK( "Error", + "There already is a terrain material called '" @ %newName @ "'.", "", "" ); + } + else + { + %mat.setInternalName( %newName ); + %this-->matLibTree.buildVisibleTree( false ); + } + } +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::changeBase( %this ) +{ + %ctrl = %this-->baseTexCtrl; + %file = %ctrl.bitmap; + if( getSubStr( %file, 0 , 6 ) $= "tools/" ) + %file = ""; + + %file = TerrainMaterialDlg._selectTextureFileDialog( %file ); + if( %file $= "" ) + { + if( %ctrl.bitmap !$= "" ) + %file = %ctrl.bitmap; + else + %file = "tools/materialeditor/gui/unknownImage"; + } + + %file = makeRelativePath( %file, getMainDotCsDir() ); + %ctrl.setBitmap( %file ); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::changeDetail( %this ) +{ + %ctrl = %this-->detailTexCtrl; + %file = %ctrl.bitmap; + if( getSubStr( %file, 0 , 6 ) $= "tools/" ) + %file = ""; + + %file = TerrainMaterialDlg._selectTextureFileDialog( %file ); + if( %file $= "" ) + { + if( %ctrl.bitmap !$= "" ) + %file = %ctrl.bitmap; + else + %file = "tools/materialeditor/gui/unknownImage"; + } + + %file = makeRelativePath( %file, getMainDotCsDir() ); + %ctrl.setBitmap( %file ); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::changeNormal( %this ) +{ + %ctrl = %this-->normTexCtrl; + %file = %ctrl.bitmap; + if( getSubStr( %file, 0 , 6 ) $= "tools/" ) + %file = ""; + + %file = TerrainMaterialDlg._selectTextureFileDialog( %file ); + if( %file $= "" ) + { + if( %ctrl.bitmap !$= "" ) + %file = %ctrl.bitmap; + else + %file = "tools/materialeditor/gui/unknownImage"; + } + + %file = makeRelativePath( %file, getMainDotCsDir() ); + %ctrl.setBitmap( %file ); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::newMat( %this ) +{ + // Create a unique material name. + %matName = getUniqueInternalName( "newMaterial", TerrainMaterialSet, true ); + + // Create the new material. + %newMat = new TerrainMaterial() + { + internalName = %matName; + parentGroup = TerrainMaterialDlgNewGroup; + }; + %newMat.setFileName( "art/terrains/materials.cs" ); + + // Mark it as dirty and to be saved in the default location. + ETerrainMaterialPersistMan.setDirty( %newMat, "art/terrains/materials.cs" ); + + %matLibTree = %this-->matLibTree; + %matLibTree.buildVisibleTree( true ); + %item = %matLibTree.findItemByObjectId( %newMat ); + %matLibTree.selectItem( %item ); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::deleteMat( %this ) +{ + if( !isObject( %this.activeMat ) ) + return; + + // Cannot delete this material if it is the only one left on the Terrain + if ( ( ETerrainEditor.getMaterialCount() == 1 ) && + ( ETerrainEditor.getMaterialIndex( %this.activeMat.internalName ) != -1 ) ) + { + MessageBoxOK( "Error", "Cannot delete this Material, it is the only " @ + "Material still in use by the active Terrain." ); + return; + } + + TerrainMaterialSet.remove( %this.activeMat ); + TerrainMaterialDlgDeleteGroup.add( %this.activeMat ); + + %matLibTree = %this-->matLibTree; + %matLibTree.open( TerrainMaterialSet, false ); + %matLibTree.selectItem( 1 ); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::activateMaterialCtrls( %this, %active ) +{ + %parent = %this-->matSettingsParent; + %count = %parent.getCount(); + for ( %i = 0; %i < %count; %i++ ) + %parent.getObject( %i ).setActive( %active ); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialTreeCtrl::onSelect( %this, %item ) +{ + TerrainMaterialDlg.setActiveMaterial( %item ); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialTreeCtrl::onUnSelect( %this, %item ) +{ + TerrainMaterialDlg.saveDirtyMaterial( %item ); + TerrainMaterialDlg.setActiveMaterial( 0 ); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::setActiveMaterial( %this, %mat ) +{ + if ( isObject( %mat ) && + %mat.isMemberOfClass( TerrainMaterial ) ) + { + %this.activeMat = %mat; + + %this-->matNameCtrl.setText( %mat.internalName ); + if (%mat.diffuseMap $= ""){ + %this-->baseTexCtrl.setBitmap( "tools/materialeditor/gui/unknownImage" ); + }else{ + %this-->baseTexCtrl.setBitmap( %mat.diffuseMap ); + } + if (%mat.detailMap $= ""){ + %this-->detailTexCtrl.setBitmap( "tools/materialeditor/gui/unknownImage" ); + }else{ + %this-->detailTexCtrl.setBitmap( %mat.detailMap ); + } + if (%mat.normalMap $= ""){ + %this-->normTexCtrl.setBitmap( "tools/materialeditor/gui/unknownImage" ); + }else{ + %this-->normTexCtrl.setBitmap( %mat.normalMap ); + } + %this-->detSizeCtrl.setText( %mat.detailSize ); + %this-->baseSizeCtrl.setText( %mat.diffuseSize ); + %this-->detStrengthCtrl.setText( %mat.detailStrength ); + %this-->detDistanceCtrl.setText( %mat.detailDistance ); + %this-->sideProjectionCtrl.setValue( %mat.useSideProjection ); + %this-->parallaxScaleCtrl.setText( %mat.parallaxScale ); + + %this.activateMaterialCtrls( true ); + } + else + { + %this.activeMat = 0; + %this.activateMaterialCtrls( false ); + } +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat ) +{ + // Skip over obviously bad cases. + if ( !isObject( %mat ) || + !%mat.isMemberOfClass( TerrainMaterial ) ) + return; + + // Read out properties from the dialog. + + %newName = %this-->matNameCtrl.getText(); + + if (%this-->baseTexCtrl.bitmap $= "tools/materialeditor/gui/unknownImage"){ + %newDiffuse = ""; + }else{ + %newDiffuse = %this-->baseTexCtrl.bitmap; + } + if (%this-->normTexCtrl.bitmap $= "tools/materialeditor/gui/unknownImage"){ + %newNormal = ""; + }else{ + %newNormal = %this-->normTexCtrl.bitmap; + } + if (%this-->detailTexCtrl.bitmap $= "tools/materialeditor/gui/unknownImage"){ + %newDetail = ""; + }else{ + %newDetail = %this-->detailTexCtrl.bitmap; + } + %detailSize = %this-->detSizeCtrl.getText(); + %diffuseSize = %this-->baseSizeCtrl.getText(); + %detailStrength = %this-->detStrengthCtrl.getText(); + %detailDistance = %this-->detDistanceCtrl.getText(); + %useSideProjection = %this-->sideProjectionCtrl.getValue(); + %parallaxScale = %this-->parallaxScaleCtrl.getText(); + + // If no properties of this materials have changed, + // return. + + if ( %mat.internalName $= %newName && + %mat.diffuseMap $= %newDiffuse && + %mat.normalMap $= %newNormal && + %mat.detailMap $= %newDetail && + %mat.detailSize == %detailSize && + %mat.diffuseSize == %diffuseSize && + %mat.detailStrength == %detailStrength && + %mat.detailDistance == %detailDistance && + %mat.useSideProjection == %useSideProjection && + %mat.parallaxScale == %parallaxScale ) + return; + + // Make sure the material name is unique. + + if( %mat.internalName !$= %newName ) + { + %existingMat = TerrainMaterialSet.findObjectByInternalName( %newName ); + if( isObject( %existingMat ) ) + { + MessageBoxOK( "Error", + "There already is a terrain material called '" @ %newName @ "'.", "", "" ); + + // Reset the name edit control to the old name. + + %this-->matNameCtrl.setText( %mat.internalName ); + } + else + %mat.setInternalName( %newName ); + } + + %mat.diffuseMap = %newDiffuse; + %mat.normalMap = %newNormal; + %mat.detailMap = %newDetail; + %mat.detailSize = %detailSize; + %mat.diffuseSize = %diffuseSize; + %mat.detailStrength = %detailStrength; + %mat.detailDistance = %detailDistance; + %mat.useSideProjection = %useSideProjection; + %mat.parallaxScale = %parallaxScale; + + // Mark the material as dirty and needing saving. + + %fileName = %mat.getFileName(); + if( %fileName $= "" ) + %fileName = "art/terrains/materials.cs"; + + ETerrainMaterialPersistMan.setDirty( %mat, %fileName ); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::snapshotMaterials( %this ) +{ + if( !isObject( TerrainMaterialDlgSnapshot ) ) + new SimGroup( TerrainMaterialDlgSnapshot ); + + %group = TerrainMaterialDlgSnapshot; + %group.clear(); + + %matCount = TerrainMaterialSet.getCount(); + for( %i = 0; %i < %matCount; %i ++ ) + { + %mat = TerrainMaterialSet.getObject( %i ); + if( !isMemberOfClass( %mat.getClassName(), "TerrainMaterial" ) ) + continue; + + %snapshot = new ScriptObject() + { + parentGroup = %group; + material = %mat; + internalName = %mat.internalName; + diffuseMap = %mat.diffuseMap; + normalMap = %mat.normalMap; + detailMap = %mat.detailMap; + detailSize = %mat.detailSize; + diffuseSize = %mat.diffuseSize; + detailStrength = %mat.detailStrength; + detailDistance = %mat.detailDistance; + useSideProjection = %mat.useSideProjection; + parallaxScale = %mat.parallaxScale; + }; + } +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::restoreMaterials( %this ) +{ + if( !isObject( TerrainMaterialDlgSnapshot ) ) + { + error( "TerrainMaterial::restoreMaterials - no snapshot present" ); + return; + } + + %count = TerrainMaterialDlgSnapshot.getCount(); + for( %i = 0; %i < %count; %i ++ ) + { + %obj = TerrainMaterialDlgSnapshot.getObject( %i ); + %mat = %obj.material; + + %mat.setInternalName( %obj.internalName ); + %mat.diffuseMap = %obj.diffuseMap; + %mat.normalMap = %obj.normalMap; + %mat.detailMap = %obj.detailMap; + %mat.detailSize = %obj.detailSize; + %mat.diffuseSize = %obj.diffuseSize; + %mat.detailStrength = %obj.detailStrength; + %mat.detailDistance = %obj.detailDistance; + %mat.useSideProjection = %obj.useSideProjection; + %mat.parallaxScale = %obj.parallaxScale; + } +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::_selectTextureFileDialog( %this, %defaultFileName ) +{ + if( $Pref::TerrainEditor::LastPath $= "" ) + $Pref::TerrainEditor::LastPath = "art/terrains"; + + %dlg = new OpenFileDialog() + { + Filters = $TerrainEditor::TextureFileSpec; + DefaultPath = $Pref::TerrainEditor::LastPath; + DefaultFile = %defaultFileName; + ChangePath = false; + MustExist = true; + }; + + %ret = %dlg.Execute(); + if ( %ret ) + { + $Pref::TerrainEditor::LastPath = filePath( %dlg.FileName ); + %file = %dlg.FileName; + } + + %dlg.delete(); + + if ( !%ret ) + return; + + %file = filePath(%file) @ "/" @ fileBase(%file); + + return %file; +} diff --git a/Templates/Empty/game/tools/worldEditor/scripts/lighting.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/lighting.ed.cs new file mode 100644 index 000000000..8886b8eb9 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/lighting.ed.cs @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function EditorLightingMenu::onAdd( %this ) +{ + Parent::onAdd( %this ); + + // Get the light manager names. + %lightManagers = getLightManagerNames(); + + // Where we gonna insert them? + %this.lmFirstIndex = %this.getItemCount(); + + // Add the light mangers to the lighting menu. + %count = getFieldCount( %lightManagers ); + for ( %i = 0; %i < %count; %i++ ) + { + %lm = getField( %lightManagers, %i ); + + // Store a reverse lookup of the light manager + // name to the menu index... used in onMenuSelect. + %index = %this.lmFirstIndex + %i; + %this.lmToIndex[ %lm ] = %index; + + // The command just sets the light manager. + %cmd = "setLightManager(\"" @ %lm @ "\"); $pref::lightManager = \"" @ %lm @ "\";"; + + // Add it. + %this.addItem( %index, %lm TAB "" TAB %cmd ); + } + + // Store for later in EditorLightingMenu. + %this.lmLastIndex = %index; +} + +function EditorLightingMenu::onMenuSelect( %this ) +{ + %lm = getActiveLightManager(); + %index = %this.lmToIndex[ %lm ]; + %this.checkRadioItem( %this.lmFirstIndex, %this.lmLastIndex, %index ); + + //%selSize = EWorldEditor.getSelectionSize(); + %this.enableItem( 1, true /*%selSize == 1*/ ); +} diff --git a/Templates/Empty/game/tools/worldEditor/scripts/menuHandlers.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/menuHandlers.ed.cs new file mode 100644 index 000000000..d694d134d --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/menuHandlers.ed.cs @@ -0,0 +1,915 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +$Pref::WorldEditor::FileSpec = "Torque Mission Files (*.mis)|*.mis|All Files (*.*)|*.*|"; + +////////////////////////////////////////////////////////////////////////// +// File Menu Handlers +////////////////////////////////////////////////////////////////////////// + +function EditorFileMenu::onMenuSelect(%this) +{ + // don't do this since it won't exist if this is a "demo" + if(!isWebDemo()) + %this.enableItem(2, EditorIsDirty()); +} + +////////////////////////////////////////////////////////////////////////// + +// Package that gets temporarily activated to toggle editor after mission loading. +// Deactivates itself. +package BootEditor { + +function GameConnection::initialControlSet( %this ) +{ + Parent::initialControlSet( %this ); + + toggleEditor( true ); + deactivatePackage( "BootEditor" ); +} + +}; + +////////////////////////////////////////////////////////////////////////// + +/// Checks the various dirty flags and returns true if the +/// mission or other related resources need to be saved. +function EditorIsDirty() +{ + // We kept a hard coded test here, but we could break these + // into the registered tools if we wanted to. + %isDirty = ( isObject( "ETerrainEditor" ) && ( ETerrainEditor.isMissionDirty || ETerrainEditor.isDirty ) ) + || ( isObject( "EWorldEditor" ) && EWorldEditor.isDirty ) + || ( isObject( "ETerrainPersistMan" ) && ETerrainPersistMan.hasDirty() ); + + // Give the editor plugins a chance to set the dirty flag. + for ( %i = 0; %i < EditorPluginSet.getCount(); %i++ ) + { + %obj = EditorPluginSet.getObject(%i); + %isDirty |= %obj.isDirty(); + } + + return %isDirty; +} + +/// Clears all the dirty state without saving. +function EditorClearDirty() +{ + EWorldEditor.isDirty = false; + ETerrainEditor.isDirty = false; + ETerrainEditor.isMissionDirty = false; + ETerrainPersistMan.clearAll(); + + for ( %i = 0; %i < EditorPluginSet.getCount(); %i++ ) + { + %obj = EditorPluginSet.getObject(%i); + %obj.clearDirty(); + } +} + +function EditorQuitGame() +{ + if( EditorIsDirty() && !isWebDemo()) + { + MessageBoxYesNoCancel("Level Modified", "Would you like to save your changes before quitting?", "EditorSaveMissionMenu(); quit();", "quit();", "" ); + } + else + quit(); +} + +function EditorExitMission() +{ + if( EditorIsDirty() && !isWebDemo() ) + { + MessageBoxYesNoCancel("Level Modified", "Would you like to save your changes before exiting?", "EditorDoExitMission(true);", "EditorDoExitMission(false);", ""); + } + else + EditorDoExitMission(false); +} + +function EditorDoExitMission(%saveFirst) +{ + if(%saveFirst && !isWebDemo()) + { + EditorSaveMissionMenu(); + } + else + { + EditorClearDirty(); + } + + if ( $UseUnifiedShell ) + { + if (isObject( UnifiedMainMenuGui )) + Editor.close("UnifiedMainMenuGui"); + else if (isObject( MainMenuGui )) + Editor.close("MainMenuGui"); + } + else if (isObject( MainMenuGui )) + Editor.close("MainMenuGui"); + + disconnect(); +} + +function EditorOpenTorsionProject( %projectFile ) +{ + // Make sure we have a valid path to the Torsion installation. + + %torsionPath = EditorSettings.value( "WorldEditor/torsionPath" ); + if( !isFile( %torsionPath ) ) + { + MessageBoxOK( + "Torsion Not Found", + "Torsion not found at '" @ %torsionPath @ "'. Please set the correct path in the preferences." + ); + return; + } + + // Determine the path to the .torsion file. + + if( %projectFile $= "" ) + { + %projectName = fileBase( getExecutableName() ); + %projectFile = makeFullPath( %projectName @ ".torsion" ); + if( !isFile( %projectFile ) ) + { + %projectFile = findFirstFile( "*.torsion", false ); + if( !isFile( %projectFile ) ) + { + MessageBoxOK( + "Project File Not Found", + "Cannot find .torsion project file in '" @ getMainDotCsDir() @ "'." + ); + return; + } + } + } + + // Open the project in Torsion. + + shellExecute( %torsionPath, "\"" @ %projectFile @ "\"" ); +} + +function EditorOpenFileInTorsion( %file, %line ) +{ + // Make sure we have a valid path to the Torsion installation. + + %torsionPath = EditorSettings.value( "WorldEditor/torsionPath" ); + if( !isFile( %torsionPath ) ) + { + MessageBoxOK( + "Torsion Not Found", + "Torsion not found at '" @ %torsionPath @ "'. Please set the correct path in the preferences." + ); + return; + } + + // If no file was specified, take the current mission file. + + if( %file $= "" ) + %file = makeFullPath( $Server::MissionFile ); + + // Open the file in Torsion. + + %args = "\"" @ %file; + if( %line !$= "" ) + %args = %args @ ":" @ %line; + %args = %args @ "\""; + + shellExecute( %torsionPath, %args ); +} + +function EditorOpenDeclarationInTorsion( %object ) +{ + %fileName = %object.getFileName(); + if( %fileName $= "" ) + return; + + EditorOpenFileInTorsion( makeFullPath( %fileName ), %object.getDeclarationLine() ); +} + +function EditorNewLevel( %file ) +{ + if(isWebDemo()) + return; + + %saveFirst = false; + if ( EditorIsDirty() ) + { + error(knob); + %saveFirst = MessageBox("Mission Modified", "Would you like to save changes to the current mission \"" @ + $Server::MissionFile @ "\" before creating a new mission?", "SaveDontSave", "Question") == $MROk; + } + + if(%saveFirst) + EditorSaveMission(); + + // Clear dirty flags first to avoid duplicate dialog box from EditorOpenMission() + if( isObject( Editor ) ) + { + EditorClearDirty(); + Editor.getUndoManager().clearAll(); + } + + if( %file $= "" ) + %file = EditorSettings.value( "WorldEditor/newLevelFile" ); + + if( !$missionRunning ) + { + activatePackage( "BootEditor" ); + StartLevel( %file ); + } + else + EditorOpenMission(%file); + + //EWorldEditor.isDirty = true; + //ETerrainEditor.isDirty = true; + EditorGui.saveAs = true; +} + +function EditorSaveMissionMenu() +{ + if(!$Pref::disableSaving && !isWebDemo()) + { + if(EditorGui.saveAs) + EditorSaveMissionAs(); + else + EditorSaveMission(); + } + else + { + EditorSaveMissionMenuDisableSave(); + } +} + +function EditorSaveMission() +{ + // just save the mission without renaming it + if(isFunction("getObjectLimit") && MissionGroup.getFullCount() >= getObjectLimit()) + { + MessageBoxOKBuy( "Object Limit Reached", "You have exceeded the object limit of " @ getObjectLimit() @ " for this demo. You can remove objects if you would like to add more.", "", "Canvas.showPurchaseScreen(\"objectlimit\");" ); + return; + } + + // first check for dirty and read-only files: + if((EWorldEditor.isDirty || ETerrainEditor.isMissionDirty) && !isWriteableFileName($Server::MissionFile)) + { + MessageBox("Error", "Mission file \""@ $Server::MissionFile @ "\" is read-only. Continue?", "Ok", "Stop"); + return false; + } + if(ETerrainEditor.isDirty) + { + // Find all of the terrain files + initContainerTypeSearch($TypeMasks::TerrainObjectType); + + while ((%terrainObject = containerSearchNext()) != 0) + { + if (!isWriteableFileName(%terrainObject.terrainFile)) + { + if (MessageBox("Error", "Terrain file \""@ %terrainObject.terrainFile @ "\" is read-only. Continue?", "Ok", "Stop") == $MROk) + continue; + else + return false; + } + } + } + + // now write the terrain and mission files out: + + if(EWorldEditor.isDirty || ETerrainEditor.isMissionDirty) + MissionGroup.save($Server::MissionFile); + if(ETerrainEditor.isDirty) + { + // Find all of the terrain files + initContainerTypeSearch($TypeMasks::TerrainObjectType); + + while ((%terrainObject = containerSearchNext()) != 0) + %terrainObject.save(%terrainObject.terrainFile); + } + + ETerrainPersistMan.saveDirty(); + + // Give EditorPlugins a chance to save. + for ( %i = 0; %i < EditorPluginSet.getCount(); %i++ ) + { + %obj = EditorPluginSet.getObject(%i); + if ( %obj.isDirty() ) + %obj.onSaveMission( $Server::MissionFile ); + } + + EditorClearDirty(); + + EditorGui.saveAs = false; + + return true; +} + +function EditorSaveMissionMenuDisableSave() +{ + GenericPromptDialog-->GenericPromptWindow.text = "Warning"; + GenericPromptDialog-->GenericPromptText.setText("Saving disabled in demo mode."); + Canvas.pushDialog( GenericPromptDialog ); +} + +function EditorSaveMissionAs( %missionName ) +{ + if(isFunction("getObjectLimit") && MissionGroup.getFullCount() >= getObjectLimit()) + { + MessageBoxOKBuy( "Object Limit Reached", "You have exceeded the object limit of " @ getObjectLimit() @ " for this demo. You can remove objects if you would like to add more.", "", "Canvas.showPurchaseScreen(\"objectlimit\");" ); + return; + } + + if(!$Pref::disableSaving && !isWebDemo()) + { + // If we didn't get passed a new mission name then + // prompt the user for one. + if ( %missionName $= "" ) + { + %dlg = new SaveFileDialog() + { + Filters = $Pref::WorldEditor::FileSpec; + DefaultPath = EditorSettings.value("LevelInformation/levelsDirectory"); + ChangePath = false; + OverwritePrompt = true; + }; + + %ret = %dlg.Execute(); + if(%ret) + { + // Immediately override/set the levelsDirectory + EditorSettings.setValue( "LevelInformation/levelsDirectory", collapseFilename(filePath( %dlg.FileName )) ); + + %missionName = %dlg.FileName; + } + + %dlg.delete(); + + if(! %ret) + return; + } + + if( fileExt( %missionName ) !$= ".mis" ) + %missionName = %missionName @ ".mis"; + + EWorldEditor.isDirty = true; + %saveMissionFile = $Server::MissionFile; + + $Server::MissionFile = %missionName; + + %copyTerrainsFailed = false; + + // Rename all the terrain files. Save all previous names so we can + // reset them if saving fails. + %newMissionName = fileBase(%missionName); + %oldMissionName = fileBase(%saveMissionFile); + + initContainerTypeSearch( $TypeMasks::TerrainObjectType ); + %savedTerrNames = new ScriptObject(); + for( %i = 0;; %i ++ ) + { + %terrainObject = containerSearchNext(); + if( !%terrainObject ) + break; + + %savedTerrNames.array[ %i ] = %terrainObject.terrainFile; + + %terrainFilePath = makeRelativePath( filePath( %terrainObject.terrainFile ), getMainDotCsDir() ); + %terrainFileName = fileName( %terrainObject.terrainFile ); + + // Workaround to have terrains created in an unsaved "New Level..." mission + // moved to the correct place. + + if( EditorGui.saveAs && %terrainFilePath $= "tools/art/terrains" ) + %terrainFilePath = "art/terrains"; + + // Try and follow the existing naming convention. + // If we can't, use systematic terrain file names. + if( strstr( %terrainFileName, %oldMissionName ) >= 0 ) + %terrainFileName = strreplace( %terrainFileName, %oldMissionName, %newMissionName ); + else + %terrainFileName = %newMissionName @ "_" @ %i @ ".ter"; + + %newTerrainFile = %terrainFilePath @ "/" @ %terrainFileName; + + if (!isWriteableFileName(%newTerrainFile)) + { + if (MessageBox("Error", "Terrain file \""@ %newTerrainFile @ "\" is read-only. Continue?", "Ok", "Stop") == $MROk) + continue; + else + { + %copyTerrainsFailed = true; + break; + } + } + + if( !%terrainObject.save( %newTerrainFile ) ) + { + error( "Failed to save '" @ %newTerrainFile @ "'" ); + %copyTerrainsFailed = true; + break; + } + + %terrainObject.terrainFile = %newTerrainFile; + } + + ETerrainEditor.isDirty = false; + + // Save the mission. + if(%copyTerrainsFailed || !EditorSaveMission()) + { + // It failed, so restore the mission and terrain filenames. + + $Server::MissionFile = %saveMissionFile; + + initContainerTypeSearch( $TypeMasks::TerrainObjectType ); + for( %i = 0;; %i ++ ) + { + %terrainObject = containerSearchNext(); + if( !%terrainObject ) + break; + + %terrainObject.terrainFile = %savedTerrNames.array[ %i ]; + } + } + + %savedTerrNames.delete(); + } + else + { + EditorSaveMissionMenuDisableSave(); + } + +} + +function EditorOpenMission(%filename) +{ + if( EditorIsDirty() && !isWebDemo() ) + { + // "EditorSaveBeforeLoad();", "getLoadFilename(\"*.mis\", \"EditorDoLoadMission\");" + if(MessageBox("Mission Modified", "Would you like to save changes to the current mission \"" @ + $Server::MissionFile @ "\" before opening a new mission?", SaveDontSave, Question) == $MROk) + { + if(! EditorSaveMission()) + return; + } + } + + if(%filename $= "") + { + %dlg = new OpenFileDialog() + { + Filters = $Pref::WorldEditor::FileSpec; + DefaultPath = EditorSettings.value("LevelInformation/levelsDirectory"); + ChangePath = false; + MustExist = true; + }; + + %ret = %dlg.Execute(); + if(%ret) + { + // Immediately override/set the levelsDirectory + EditorSettings.setValue( "LevelInformation/levelsDirectory", collapseFilename(filePath( %dlg.FileName )) ); + %filename = %dlg.FileName; + } + + %dlg.delete(); + + if(! %ret) + return; + } + + // close the current editor, it will get cleaned up by MissionCleanup + if( isObject( "Editor" ) ) + Editor.close( LoadingGui ); + + EditorClearDirty(); + + // If we haven't yet connnected, create a server now. + // Otherwise just load the mission. + + if( !$missionRunning ) + { + activatePackage( "BootEditor" ); + StartLevel( %filename ); + } + else + { + loadMission( %filename, true ) ; + + pushInstantGroup(); + + // recreate and open the editor + Editor::create(); + MissionCleanup.add( Editor ); + MissionCleanup.add( Editor.getUndoManager() ); + EditorGui.loadingMission = true; + Editor.open(); + + popInstantGroup(); + } +} + +function EditorExportToCollada() +{ + if ( !$Pref::disableSaving && !isWebDemo() ) + { + %dlg = new SaveFileDialog() + { + Filters = "COLLADA Files (*.dae)|*.dae|"; + DefaultPath = $Pref::WorldEditor::LastPath; + DefaultFile = ""; + ChangePath = false; + OverwritePrompt = true; + }; + + %ret = %dlg.Execute(); + if ( %ret ) + { + $Pref::WorldEditor::LastPath = filePath( %dlg.FileName ); + %exportFile = %dlg.FileName; + } + + if( fileExt( %exportFile ) !$= ".dae" ) + %exportFile = %exportFile @ ".dae"; + + %dlg.delete(); + + if ( !%ret ) + return; + + if ( EditorGui.currentEditor.getId() == ShapeEditorPlugin.getId() ) + ShapeEdShapeView.exportToCollada( %exportFile ); + else + EWorldEditor.colladaExportSelection( %exportFile ); + } +} + +function EditorMakePrefab() +{ + // Should this be protected or not? + if ( !$Pref::disableSaving && !isWebDemo() ) + { + %dlg = new SaveFileDialog() + { + Filters = "Prefab Files (*.prefab)|*.prefab|"; + DefaultPath = $Pref::WorldEditor::LastPath; + DefaultFile = ""; + ChangePath = false; + OverwritePrompt = true; + }; + + %ret = %dlg.Execute(); + if ( %ret ) + { + $Pref::WorldEditor::LastPath = filePath( %dlg.FileName ); + %saveFile = %dlg.FileName; + } + + if( fileExt( %saveFile ) !$= ".prefab" ) + %saveFile = %saveFile @ ".prefab"; + + %dlg.delete(); + + if ( !%ret ) + return; + + EWorldEditor.makeSelectionPrefab( %saveFile ); + + EditorTree.buildVisibleTree( true ); + } +} + +function EditorExplodePrefab() +{ + //echo( "EditorExplodePrefab()" ); + EWorldEditor.explodeSelectedPrefab(); + EditorTree.buildVisibleTree( true ); +} + +function EditorMount() +{ + echo( "EditorMount" ); + + %size = EWorldEditor.getSelectionSize(); + if ( %size != 2 ) + return; + + %a = EWorldEditor.getSelectedObject(0); + %b = EWorldEditor.getSelectedObject(1); + + //%a.mountObject( %b, 0 ); + EWorldEditor.mountRelative( %a, %b ); +} + +function EditorUnmount() +{ + echo( "EditorUnmount" ); + + %obj = EWorldEditor.getSelectedObject(0); + %obj.unmount(); +} + +////////////////////////////////////////////////////////////////////////// +// View Menu Handlers +////////////////////////////////////////////////////////////////////////// + +function EditorViewMenu::onMenuSelect( %this ) +{ + %this.checkItem( 1, EWorldEditor.renderOrthoGrid ); +} + +////////////////////////////////////////////////////////////////////////// +// Edit Menu Handlers +////////////////////////////////////////////////////////////////////////// + +function EditorEditMenu::onMenuSelect( %this ) +{ + // UndoManager is in charge of enabling or disabling the undo/redo items. + Editor.getUndoManager().updateUndoMenu( %this ); + + // SICKHEAD: It a perfect world we would abstract + // cut/copy/paste with a generic selection object + // which would know how to process itself. + + // Give the active editor a chance at fixing up + // the state of the edit menu. + // Do we really need this check here? + if ( isObject( EditorGui.currentEditor ) ) + EditorGui.currentEditor.onEditMenuSelect( %this ); +} + +////////////////////////////////////////////////////////////////////////// + +function EditorMenuEditDelete() +{ + if ( isObject( EditorGui.currentEditor ) ) + EditorGui.currentEditor.handleDelete(); +} + +function EditorMenuEditDeselect() +{ + if ( isObject( EditorGui.currentEditor ) ) + EditorGui.currentEditor.handleDeselect(); +} + +function EditorMenuEditCut() +{ + if ( isObject( EditorGui.currentEditor ) ) + EditorGui.currentEditor.handleCut(); +} + +function EditorMenuEditCopy() +{ + if ( isObject( EditorGui.currentEditor ) ) + EditorGui.currentEditor.handleCopy(); +} + +function EditorMenuEditPaste() +{ + if ( isObject( EditorGui.currentEditor ) ) + EditorGui.currentEditor.handlePaste(); +} + + + +////////////////////////////////////////////////////////////////////////// +// Window Menu Handler +////////////////////////////////////////////////////////////////////////// + +function EditorToolsMenu::onSelectItem(%this, %id) +{ + %toolName = getField( %this.item[%id], 2 ); + + EditorGui.setEditor(%toolName, %paletteName ); + + %this.checkRadioItem(0, %this.getItemCount(), %id); + return true; +} + +function EditorToolsMenu::setupDefaultState(%this) +{ + Parent::setupDefaultState(%this); +} + +////////////////////////////////////////////////////////////////////////// +// Camera Menu Handler +////////////////////////////////////////////////////////////////////////// + +function EditorCameraMenu::onSelectItem(%this, %id, %text) +{ + if(%id == 0 || %id == 1) + { + // Handle the Free Camera/Orbit Camera toggle + %this.checkRadioItem(0, 1, %id); + } + + return Parent::onSelectItem(%this, %id, %text); +} + +function EditorCameraMenu::setupDefaultState(%this) +{ + // Set the Free Camera/Orbit Camera check marks + %this.checkRadioItem(0, 1, 0); + Parent::setupDefaultState(%this); +} + +function EditorFreeCameraTypeMenu::onSelectItem(%this, %id, %text) +{ + // Handle the camera type radio + %this.checkRadioItem(0, 2, %id); + + return Parent::onSelectItem(%this, %id, %text); +} + +function EditorFreeCameraTypeMenu::setupDefaultState(%this) +{ + // Set the camera type check marks + %this.checkRadioItem(0, 2, 0); + Parent::setupDefaultState(%this); +} + +function EditorCameraSpeedMenu::onSelectItem(%this, %id, %text) +{ + // Grab and set speed + %speed = getField( %this.item[%id], 2 ); + $Camera::movementSpeed = %speed; + + // Update Editor + %this.checkRadioItem(0, 6, %id); + + // Update Toolbar TextEdit + EWorldEditorCameraSpeed.setText( $Camera::movementSpeed ); + + // Update Toolbar Slider + CameraSpeedDropdownCtrlContainer-->Slider.setValue( $Camera::movementSpeed ); + + return true; +} +function EditorCameraSpeedMenu::setupDefaultState(%this) +{ + // Setup camera speed gui's. Both menu and editorgui + %this.setupGuiControls(); + + //Grab and set speed + %defaultSpeed = EditorSettings.value("LevelInformation/levels/" @ EditorGui.levelName @ "/cameraSpeed"); + if( %defaultSpeed $= "" ) + { + // Update Editor with default speed + %defaultSpeed = 25; + } + $Camera::movementSpeed = %defaultSpeed; + + // Update Toolbar TextEdit + EWorldEditorCameraSpeed.setText( %defaultSpeed ); + + // Update Toolbar Slider + CameraSpeedDropdownCtrlContainer-->Slider.setValue( %defaultSpeed ); + + Parent::setupDefaultState(%this); +} + +function EditorCameraSpeedMenu::setupGuiControls(%this) +{ + // Default levelInfo params + %minSpeed = 5; + %maxSpeed = 200; + + %speedA = EditorSettings.value("LevelInformation/levels/" @ EditorGui.levelName @ "/cameraSpeedMin"); + %speedB = EditorSettings.value("LevelInformation/levels/" @ EditorGui.levelName @ "/cameraSpeedMax"); + if( %speedA < %speedB ) + { + if( %speedA == 0 ) + { + if( %speedB > 1 ) + %minSpeed = 1; + else + %minSpeed = 0.1; + } + else + { + %minSpeed = %speedA; + } + + %maxSpeed = %speedB; + } + + // Set up the camera speed items + %inc = ( (%maxSpeed - %minSpeed) / (%this.getItemCount() - 1) ); + for( %i = 0; %i < %this.getItemCount(); %i++) + %this.item[%i] = setField( %this.item[%i], 2, (%minSpeed + (%inc * %i))); + + // Set up min/max camera slider range + eval("CameraSpeedDropdownCtrlContainer-->Slider.range = \"" @ %minSpeed @ " " @ %maxSpeed @ "\";"); +} +////////////////////////////////////////////////////////////////////////// +// World Menu Handler Object Menu +////////////////////////////////////////////////////////////////////////// + +function EditorWorldMenu::onMenuSelect(%this) +{ + %selSize = EWorldEditor.getSelectionSize(); + %lockCount = EWorldEditor.getSelectionLockCount(); + %hideCount = EWorldEditor.getSelectionHiddenCount(); + + %this.enableItem(0, %lockCount < %selSize); // Lock Selection + %this.enableItem(1, %lockCount > 0); // Unlock Selection + %this.enableItem(3, %hideCount < %selSize); // Hide Selection + %this.enableItem(4, %hideCount > 0); // Show Selection + %this.enableItem(6, %selSize > 1 && %lockCount == 0); // Align bounds + %this.enableItem(7, %selSize > 1 && %lockCount == 0); // Align center + %this.enableItem(9, %selSize > 0 && %lockCount == 0); // Reset Transforms + %this.enableItem(10, %selSize > 0 && %lockCount == 0); // Reset Selected Rotation + %this.enableItem(11, %selSize > 0 && %lockCount == 0); // Reset Selected Scale + %this.enableItem(12, %selSize > 0 && %lockCount == 0); // Transform Selection + %this.enableItem(14, %selSize > 0 && %lockCount == 0); // Drop Selection + + %this.enableItem(17, %selSize > 0); // Make Prefab + %this.enableItem(18, %selSize > 0); // Explode Prefab + + %this.enableItem(20, %selSize > 1); // Mount + %this.enableItem(21, %selSize > 0); // Unmount +} + +////////////////////////////////////////////////////////////////////////// + +function EditorDropTypeMenu::onSelectItem(%this, %id, %text) +{ + // This sets up which drop script function to use when + // a drop type is selected in the menu. + EWorldEditor.dropType = getField(%this.item[%id], 2); + + %this.checkRadioItem(0, (%this.getItemCount() - 1), %id); + + return true; +} + +function EditorDropTypeMenu::setupDefaultState(%this) +{ + // Check the radio item for the currently set drop type. + + %numItems = %this.getItemCount(); + + %dropTypeIndex = 0; + for( ; %dropTypeIndex < %numItems; %dropTypeIndex ++ ) + if( getField( %this.item[ %dropTypeIndex ], 2 ) $= EWorldEditor.dropType ) + break; + + // Default to screenCenter if we didn't match anything. + if( %dropTypeIndex > (%numItems - 1) ) + %dropTypeIndex = 4; + + %this.checkRadioItem( 0, (%numItems - 1), %dropTypeIndex ); + + Parent::setupDefaultState(%this); +} + +////////////////////////////////////////////////////////////////////////// + +function EditorAlignBoundsMenu::onSelectItem(%this, %id, %text) +{ + // Have the editor align all selected objects by the selected bounds. + EWorldEditor.alignByBounds(getField(%this.item[%id], 2)); + + return true; +} + +function EditorAlignBoundsMenu::setupDefaultState(%this) +{ + // Allow the parent to set the menu's default state + Parent::setupDefaultState(%this); +} + +////////////////////////////////////////////////////////////////////////// + +function EditorAlignCenterMenu::onSelectItem(%this, %id, %text) +{ + // Have the editor align all selected objects by the selected axis. + EWorldEditor.alignByAxis(getField(%this.item[%id], 2)); + + return true; +} + +function EditorAlignCenterMenu::setupDefaultState(%this) +{ + // Allow the parent to set the menu's default state + Parent::setupDefaultState(%this); +} diff --git a/Templates/Empty/game/tools/worldEditor/scripts/menus.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/menus.ed.cs new file mode 100644 index 000000000..021d6bb6e --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/menus.ed.cs @@ -0,0 +1,406 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function EditorGui::buildMenus(%this) +{ + if(isObject(%this.menuBar)) + return; + + //set up %cmdctrl variable so that it matches OS standards + if( $platform $= "macos" ) + { + %cmdCtrl = "Cmd"; + %menuCmdCtrl = "Cmd"; + %quitShortcut = "Cmd Q"; + %redoShortcut = "Cmd-Shift Z"; + } + else + { + %cmdCtrl = "Ctrl"; + %menuCmdCtrl = "Alt"; + %quitShortcut = "Alt F4"; + %redoShortcut = "Ctrl Y"; + } + + // Sub menus (temporary, until MenuBuilder gets updated) + // The speed increments located here are overwritten in EditorCameraSpeedMenu::setupDefaultState. + // The new min/max for the editor camera speed range can be set in each level's levelInfo object. + %this.cameraSpeedMenu = new PopupMenu(EditorCameraSpeedOptions) + { + superClass = "MenuBuilder"; + class = "EditorCameraSpeedMenu"; + + item[0] = "Slowest" TAB %cmdCtrl @ "-Shift 1" TAB "5"; + item[1] = "Slow" TAB %cmdCtrl @ "-Shift 2" TAB "35"; + item[2] = "Slower" TAB %cmdCtrl @ "-Shift 3" TAB "70"; + item[3] = "Normal" TAB %cmdCtrl @ "-Shift 4" TAB "100"; + item[4] = "Faster" TAB %cmdCtrl @ "-Shift 5" TAB "130"; + item[5] = "Fast" TAB %cmdCtrl @ "-Shift 6" TAB "165"; + item[6] = "Fastest" TAB %cmdCtrl @ "-Shift 7" TAB "200"; + }; + %this.freeCameraTypeMenu = new PopupMenu(EditorFreeCameraTypeOptions) + { + superClass = "MenuBuilder"; + class = "EditorFreeCameraTypeMenu"; + + item[0] = "Standard" TAB "Ctrl 1" TAB "EditorGuiStatusBar.setCamera(\"Standard Camera\");"; + item[1] = "Orbit Camera" TAB "Ctrl 2" TAB "EditorGuiStatusBar.setCamera(\"Orbit Camera\");"; + Item[2] = "-"; + item[3] = "Smoothed" TAB "" TAB "EditorGuiStatusBar.setCamera(\"Smooth Camera\");"; + item[4] = "Smoothed Rotate" TAB "" TAB "EditorGuiStatusBar.setCamera(\"Smooth Rot Camera\");"; + }; + %this.playerCameraTypeMenu = new PopupMenu(EditorPlayerCameraTypeOptions) + { + superClass = "MenuBuilder"; + class = "EditorPlayerCameraTypeMenu"; + + Item[0] = "First Person" TAB "" TAB "EditorGuiStatusBar.setCamera(\"1st Person Camera\");"; + Item[1] = "Third Person" TAB "" TAB "EditorGuiStatusBar.setCamera(\"3rd Person Camera\");"; + }; + %this.cameraBookmarksMenu = new PopupMenu(EditorCameraBookmarks) + { + superClass = "MenuBuilder"; + class = "EditorCameraBookmarksMenu"; + + //item[0] = "None"; + }; + %this.viewTypeMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + + item[ 0 ] = "Top" TAB "Alt 2" TAB "EditorGuiStatusBar.setCamera(\"Top View\");"; + item[ 1 ] = "Bottom" TAB "Alt 5" TAB "EditorGuiStatusBar.setCamera(\"Bottom View\");"; + item[ 2 ] = "Front" TAB "Alt 3" TAB "EditorGuiStatusBar.setCamera(\"Front View\");"; + item[ 3 ] = "Back" TAB "Alt 6" TAB "EditorGuiStatusBar.setCamera(\"Back View\");"; + item[ 4 ] = "Left" TAB "Alt 4" TAB "EditorGuiStatusBar.setCamera(\"Left View\");"; + item[ 5 ] = "Right" TAB "Alt 7" TAB "EditorGuiStatusBar.setCamera(\"Right View\");"; + item[ 6 ] = "Perspective" TAB "Alt 1" TAB "EditorGuiStatusBar.setCamera(\"Standard Camera\");"; + item[ 7 ] = "Isometric" TAB "Alt 8" TAB "EditorGuiStatusBar.setCamera(\"Isometric View\");"; + }; + + // Menu bar + %this.menuBar = new MenuBar() + { + dynamicItemInsertPos = 3; + }; + + // File Menu + %fileMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorFileMenu"; + + barTitle = "File"; + }; + + if(!isWebDemo()) + { + %fileMenu.appendItem("New Level" TAB "" TAB "schedule( 1, 0, \"EditorNewLevel\" );"); + %fileMenu.appendItem("Open Level..." TAB %cmdCtrl SPC "O" TAB "schedule( 1, 0, \"EditorOpenMission\" );"); + %fileMenu.appendItem("Save Level" TAB %cmdCtrl SPC "S" TAB "EditorSaveMissionMenu();"); + %fileMenu.appendItem("Save Level As..." TAB "" TAB "EditorSaveMissionAs();"); + %fileMenu.appendItem("-"); + + if( $platform $= "windows" ) + { + %fileMenu.appendItem( "Open Project in Torsion" TAB "" TAB "EditorOpenTorsionProject();" ); + %fileMenu.appendItem( "Open Level File in Torsion" TAB "" TAB "EditorOpenFileInTorsion();" ); + %fileMenu.appendItem( "-" ); + } + } + + %fileMenu.appendItem("Create Blank Terrain" TAB "" TAB "Canvas.pushDialog( CreateNewTerrainGui );"); + %fileMenu.appendItem("Import Terrain Heightmap" TAB "" TAB "Canvas.pushDialog( TerrainImportGui );"); + + if(!isWebDemo()) + { + %fileMenu.appendItem("Export Terrain Heightmap" TAB "" TAB "Canvas.pushDialog( TerrainExportGui );"); + %fileMenu.appendItem("-"); + %fileMenu.appendItem("Export Interiors To COLLADA..." TAB "" TAB "Canvas.pushDialog( InteriorExportGui );"); + %fileMenu.appendItem("Export To COLLADA..." TAB "" TAB "EditorExportToCollada();"); + //item[5] = "Import Terraform Data..." TAB "" TAB "Heightfield::import();"; + //item[6] = "Import Texture Data..." TAB "" TAB "Texture::import();"; + //item[7] = "-"; + //item[8] = "Export Terraform Data..." TAB "" TAB "Heightfield::saveBitmap(\"\");"; + } + + %fileMenu.appendItem( "-" ); + %fileMenu.appendItem( "Add FMOD Designer Audio..." TAB "" TAB "AddFMODProjectDlg.show();" ); + + %fileMenu.appendItem("-"); + %fileMenu.appendItem("Play Level" TAB "F11" TAB "Editor.close(\"PlayGui\");"); + + if(!isWebDemo()) + { + %fileMenu.appendItem("Exit Level" TAB "" TAB "EditorExitMission();"); + %fileMenu.appendItem("Quit" TAB %quitShortcut TAB "EditorQuitGame();"); + } + %this.menuBar.insert(%fileMenu, %this.menuBar.getCount()); + + // Edit Menu + %editMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorEditMenu"; + internalName = "EditMenu"; + + barTitle = "Edit"; + + item[0] = "Undo" TAB %cmdCtrl SPC "Z" TAB "Editor.getUndoManager().undo();"; + item[1] = "Redo" TAB %redoShortcut TAB "Editor.getUndoManager().redo();"; + item[2] = "-"; + item[3] = "Cut" TAB %cmdCtrl SPC "X" TAB "EditorMenuEditCut();"; + item[4] = "Copy" TAB %cmdCtrl SPC "C" TAB "EditorMenuEditCopy();"; + item[5] = "Paste" TAB %cmdCtrl SPC "V" TAB "EditorMenuEditPaste();"; + item[6] = "Delete" TAB "Delete" TAB "EditorMenuEditDelete();"; + item[7] = "-"; + item[8] = "Deselect" TAB "X" TAB "EditorMenuEditDeselect();"; + Item[9] = "Select..." TAB "" TAB "EditorGui.toggleObjectSelectionsWindow();"; + item[10] = "-"; + item[11] = "Audio Parameters..." TAB "" TAB "EditorGui.toggleSFXParametersWindow();"; + item[12] = "Editor Settings..." TAB "" TAB "ESettingsWindow.ToggleVisibility();"; + item[13] = "Snap Options..." TAB "" TAB "ESnapOptions.ToggleVisibility();"; + item[14] = "-"; + item[15] = "Game Options..." TAB "" TAB "Canvas.pushDialog(optionsDlg);"; + item[16] = "PostEffect Manager" TAB "" TAB "Canvas.pushDialog(PostFXManager);"; + }; + %this.menuBar.insert(%editMenu, %this.menuBar.getCount()); + + // View Menu + %viewMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorViewMenu"; + internalName = "viewMenu"; + + barTitle = "View"; + + item[ 0 ] = "Visibility Layers" TAB "Alt V" TAB "VisibilityDropdownToggle();"; + item[ 1 ] = "Show Grid in Ortho Views" TAB %cmdCtrl @ "-Shift-Alt G" TAB "EditorGui.toggleOrthoGrid();"; + }; + %this.menuBar.insert(%viewMenu, %this.menuBar.getCount()); + + // Camera Menu + %cameraMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorCameraMenu"; + + barTitle = "Camera"; + + item[0] = "World Camera" TAB %this.freeCameraTypeMenu; + item[1] = "Player Camera" TAB %this.playerCameraTypeMenu; + item[2] = "-"; + Item[3] = "Toggle Camera" TAB %menuCmdCtrl SPC "C" TAB "commandToServer('ToggleCamera');"; + item[4] = "Place Camera at Selection" TAB "Ctrl Q" TAB "EWorldEditor.dropCameraToSelection();"; + item[5] = "Place Camera at Player" TAB "Alt Q" TAB "commandToServer('dropCameraAtPlayer');"; + item[6] = "Place Player at Camera" TAB "Alt W" TAB "commandToServer('DropPlayerAtCamera');"; + item[7] = "-"; + item[8] = "Fit View to Selection" TAB "F" TAB "commandToServer('EditorCameraAutoFit', EWorldEditor.getSelectionRadius()+1);"; + item[9] = "Fit View To Selection and Orbit" TAB "Alt F" TAB "EditorGuiStatusBar.setCamera(\"Orbit Camera\"); commandToServer('EditorCameraAutoFit', EWorldEditor.getSelectionRadius()+1);"; + item[10] = "-"; + item[11] = "Speed" TAB %this.cameraSpeedMenu; + item[12] = "View" TAB %this.viewTypeMenu; + item[13] = "-"; + Item[14] = "Add Bookmark..." TAB "Ctrl B" TAB "EditorGui.addCameraBookmarkByGui();"; + Item[15] = "Manage Bookmarks..." TAB "Ctrl-Shift B" TAB "EditorGui.toggleCameraBookmarkWindow();"; + item[16] = "Jump to Bookmark" TAB %this.cameraBookmarksMenu; + }; + %this.menuBar.insert(%cameraMenu, %this.menuBar.getCount()); + + // Editors Menu + %editorsMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorToolsMenu"; + + barTitle = "Editors"; + + //item[0] = "Object Editor" TAB "F1" TAB WorldEditorInspectorPlugin; + //item[1] = "Material Editor" TAB "F2" TAB MaterialEditorPlugin; + //item[2] = "-"; + //item[3] = "Terrain Editor" TAB "F3" TAB TerrainEditorPlugin; + //item[4] = "Terrain Painter" TAB "F4" TAB TerrainPainterPlugin; + //item[5] = "-"; + }; + %this.menuBar.insert(%editorsMenu, %this.menuBar.getCount()); + + // Lighting Menu + %lightingMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorLightingMenu"; + + barTitle = "Lighting"; + + item[0] = "Full Relight" TAB "Alt L" TAB "Editor.lightScene(\"\", forceAlways);"; + item[1] = "Toggle ShadowViz" TAB "" TAB "toggleShadowViz();"; + item[2] = "-"; + + // NOTE: The light managers will be inserted as the + // last menu items in EditorLightingMenu::onAdd(). + }; + %this.menuBar.insert(%lightingMenu, %this.menuBar.getCount()); + + // Help Menu + %helpMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorHelpMenu"; + + barTitle = "Help"; + + item[0] = "Online Documentation..." TAB "Alt F1" TAB "gotoWebPage(EWorldEditor.documentationURL);"; + item[1] = "Offline User Guide..." TAB "" TAB "gotoWebPage(EWorldEditor.documentationLocal);"; + item[2] = "Offline Reference Guide..." TAB "" TAB "shellexecute(EWorldEditor.documentationReference);"; + item[3] = "Torque 3D Forums..." TAB "" TAB "gotoWebPage(EWorldEditor.forumURL);"; + }; + %this.menuBar.insert(%helpMenu, %this.menuBar.getCount()); + + // Menus that are added/removed dynamically (temporary) + + // World Menu + if(! isObject(%this.worldMenu)) + { + %this.dropTypeMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorDropTypeMenu"; + + // The onSelectItem() callback for this menu re-purposes the command field + // as the MenuBuilder version is not used. + item[0] = "at Origin" TAB "" TAB "atOrigin"; + item[1] = "at Camera" TAB "" TAB "atCamera"; + item[2] = "at Camera w/Rotation" TAB "" TAB "atCameraRot"; + item[3] = "Below Camera" TAB "" TAB "belowCamera"; + item[4] = "Screen Center" TAB "" TAB "screenCenter"; + item[5] = "at Centroid" TAB "" TAB "atCentroid"; + item[6] = "to Terrain" TAB "" TAB "toTerrain"; + item[7] = "Below Selection" TAB "" TAB "belowSelection"; + }; + + %this.alignBoundsMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorAlignBoundsMenu"; + + // The onSelectItem() callback for this menu re-purposes the command field + // as the MenuBuilder version is not used. + item[0] = "+X Axis" TAB "" TAB "0"; + item[1] = "+Y Axis" TAB "" TAB "1"; + item[2] = "+Z Axis" TAB "" TAB "2"; + item[3] = "-X Axis" TAB "" TAB "3"; + item[4] = "-Y Axis" TAB "" TAB "4"; + item[5] = "-Z Axis" TAB "" TAB "5"; + }; + + %this.alignCenterMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorAlignCenterMenu"; + + // The onSelectItem() callback for this menu re-purposes the command field + // as the MenuBuilder version is not used. + item[0] = "X Axis" TAB "" TAB "0"; + item[1] = "Y Axis" TAB "" TAB "1"; + item[2] = "Z Axis" TAB "" TAB "2"; + }; + + %this.worldMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorWorldMenu"; + + barTitle = "Object"; + + item[0] = "Lock Selection" TAB %cmdCtrl @ " L" TAB "EWorldEditor.lockSelection(true); EWorldEditor.syncGui();"; + item[1] = "Unlock Selection" TAB %cmdCtrl @ "-Shift L" TAB "EWorldEditor.lockSelection(false); EWorldEditor.syncGui();"; + item[2] = "-"; + item[3] = "Hide Selection" TAB %cmdCtrl @ " H" TAB "EWorldEditor.hideSelection(true); EWorldEditor.syncGui();"; + item[4] = "Show Selection" TAB %cmdCtrl @ "-Shift H" TAB "EWorldEditor.hideSelection(false); EWorldEditor.syncGui();"; + item[5] = "-"; + item[6] = "Align Bounds" TAB %this.alignBoundsMenu; + item[7] = "Align Center" TAB %this.alignCenterMenu; + item[8] = "-"; + item[9] = "Reset Transforms" TAB "Ctrl R" TAB "EWorldEditor.resetTransforms();"; + item[10] = "Reset Selected Rotation" TAB "" TAB "EWorldEditor.resetSelectedRotation();"; + item[11] = "Reset Selected Scale" TAB "" TAB "EWorldEditor.resetSelectedScale();"; + item[12] = "Transform Selection..." TAB "Ctrl T" TAB "ETransformSelection.ToggleVisibility();"; + item[13] = "-"; + //item[13] = "Drop Camera to Selection" TAB "Ctrl Q" TAB "EWorldEditor.dropCameraToSelection();"; + //item[14] = "Add Selection to Instant Group" TAB "" TAB "EWorldEditor.addSelectionToAddGroup();"; + item[14] = "Drop Selection" TAB "Ctrl D" TAB "EWorldEditor.dropSelection();"; + //item[15] = "-"; + item[15] = "Drop Location" TAB %this.dropTypeMenu; + Item[16] = "-"; + Item[17] = "Make Selection Prefab" TAB "" TAB "EditorMakePrefab();"; + Item[18] = "Explode Selected Prefab" TAB "" TAB "EditorExplodePrefab();"; + Item[19] = "-"; + Item[20] = "Mount Selection A to B" TAB "" TAB "EditorMount();"; + Item[21] = "Unmount Selected Object" TAB "" TAB "EditorUnmount();"; + }; + } +} + +////////////////////////////////////////////////////////////////////////// + +function EditorGui::attachMenus(%this) +{ + %this.menuBar.attachToCanvas(Canvas, 0); +} + +function EditorGui::detachMenus(%this) +{ + %this.menuBar.removeFromCanvas(); +} + +function EditorGui::setMenuDefaultState(%this) +{ + if(! isObject(%this.menuBar)) + return 0; + + for(%i = 0;%i < %this.menuBar.getCount();%i++) + { + %menu = %this.menuBar.getObject(%i); + %menu.setupDefaultState(); + } + + %this.worldMenu.setupDefaultState(); +} + +////////////////////////////////////////////////////////////////////////// + +function EditorGui::findMenu(%this, %name) +{ + if(! isObject(%this.menuBar)) + return 0; + + for(%i = 0;%i < %this.menuBar.getCount();%i++) + { + %menu = %this.menuBar.getObject(%i); + + if(%name $= %menu.barTitle) + return %menu; + } + + return 0; +} diff --git a/Templates/Empty/game/tools/worldEditor/scripts/objectSnapOptions.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/objectSnapOptions.ed.cs new file mode 100644 index 000000000..33c231e53 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/objectSnapOptions.ed.cs @@ -0,0 +1,95 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + + +function ESnapOptions::onWake( %this ) +{ + ESnapOptionsTabTerrain-->NoAlignment.setStateOn(1); + + ESnapOptionsTabSoft-->NoAlignment.setStateOn(1); + ESnapOptionsTabSoft-->RenderSnapBounds.setStateOn(1); + ESnapOptionsTabSoft-->SnapBackfaceTolerance.setText(EWorldEditor.getSoftSnapBackfaceTolerance()); +} + +function ESnapOptions::hideDialog( %this ) +{ + %this.setVisible(false); + SnapToBar-->snappingSettingsBtn.setStateOn(false); +} + +function ESnapOptions::ToggleVisibility() +{ + if ( ESnapOptions.visible ) + { + ESnapOptions.setVisible(false); + SnapToBar-->snappingSettingsBtn.setStateOn(false); + } + else + { + ESnapOptions.setVisible(true); + ESnapOptions.selectWindow(); + ESnapOptions.setCollapseGroup(false); + SnapToBar-->snappingSettingsBtn.setStateOn(true); + } +} + +function ESnapOptions::setTerrainSnapAlignment( %this, %val ) +{ + EWorldEditor.setTerrainSnapAlignment(%val); +} + +function ESnapOptions::setSoftSnapAlignment( %this, %val ) +{ + EWorldEditor.setSoftSnapAlignment(%val); +} + +function ESnapOptions::setSoftSnapSize( %this ) +{ + %val = ESnapOptions-->SnapSize.getText(); + + EWorldEditor.setSoftSnapSize(%val); + EWorldEditor.syncGui(); +} + +function ESnapOptions::setGridSnapSize( %this ) +{ + %val = ESnapOptions-->GridSize.getText(); + + EWorldEditor.setGridSize( %val ); +} + +function ESnapOptions::toggleRenderSnapBounds( %this ) +{ + EWorldEditor.softSnapRender( ESnapOptionsTabSoft-->RenderSnapBounds.getValue() ); +} + +function ESnapOptions::toggleRenderSnappedTriangle( %this ) +{ + EWorldEditor.softSnapRenderTriangle( ESnapOptionsTabSoft-->RenderSnappedTriangle.getValue() ); +} + +function ESnapOptions::getSoftSnapBackfaceTolerance( %this ) +{ + %val = ESnapOptions-->SnapBackfaceTolerance.getText(); + + EWorldEditor.setSoftSnapBackfaceTolerance(%val); +} diff --git a/Templates/Empty/game/tools/worldEditor/scripts/transformSelection.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/transformSelection.ed.cs new file mode 100644 index 000000000..7777e4acb --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/transformSelection.ed.cs @@ -0,0 +1,448 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function ETransformSelection::onWake( %this ) +{ + // Make everything relative + ETransformSelection-->PosRelative.setStateOn( true ); + ETransformSelection-->RotRelative.setStateOn( true ); + ETransformSelection-->ScaleRelative.setStateOn( true ); + ETransformSelection-->SizeRelative.setStateOn( false ); + + ETransformSelection-->GetPosButton.setActive( false ); + ETransformSelection-->GetRotButton.setActive( false ); + ETransformSelection-->GetScaleButton.setActive( false ); + ETransformSelection-->GetSizeButton.setActive( false ); + + // Size is always local + ETransformSelection-->SizeLocal.setStateOn( true ); + ETransformSelection-->SizeLocal.setActive( false ); + + ETransformSelection-->ScaleTabBook.selectPage( 0 ); // Scale page + + ETransformSelection-->ApplyButton.setActive( false ); + + EWorldEditor.ETransformSelectionDisplayed = false; +} + +function ETransformSelection::onVisible( %this, %state ) +{ + // If we are made visible, sync to the world editor + // selection. + + if( %state ) + %this.onSelectionChanged(); +} + +function ETransformSelection::hideDialog( %this ) +{ + %this.setVisible(false); + EWorldEditor.ETransformSelectionDisplayed = false; +} + +function ETransformSelection::ToggleVisibility( %this ) +{ + if ( ETransformSelection.visible ) + { + ETransformSelection.setVisible(false); + EWorldEditor.ETransformSelectionDisplayed = false; + } + else + { + ETransformSelection.setVisible(true); + ETransformSelection.selectWindow(); + ETransformSelection.setCollapseGroup(false); + EWorldEditor.ETransformSelectionDisplayed = true; + } +} + +function ETransformSelection::disableAllButtons( %this ) +{ + ETransformSelection-->GetPosButton.setActive( false ); + ETransformSelection-->GetRotButton.setActive( false ); + ETransformSelection-->GetScaleButton.setActive( false ); + ETransformSelection-->GetSizeButton.setActive( false ); + + ETransformSelection-->ApplyButton.setActive( false ); +} + +function ETransformSelection::onSelectionChanged( %this ) +{ + // Count the number of selected SceneObjects. There are + // other object classes that could be selected, such + // as SimGroups. + %count = EWorldEditor.getSelectionSize(); + %sceneObjects = 0; + %globalBoundsObjects = 0; + for( %i=0; %i<%count; %i++) + { + %obj = EWorldEditor.getSelectedObject( %i ); + if( %obj.isMemberOfClass("SceneObject") ) + { + %sceneObjects++; + + if( %obj.isGlobalBounds() ) + { + %globalBoundsObjects++; + } + } + } + + if( %sceneObjects == 0 ) + { + // With nothing selected, disable all Get buttons + ETransformSelection.disableAllButtons(); + } + else if( %sceneObjects == 1 ) + { + // With one selected, all Get buttons are active + ETransformSelection-->GetPosButton.setActive( true ); + ETransformSelection-->GetRotButton.setActive( true ); + + // Special case for Scale and Size for global bounds objects + if( %globalBoundsObjects == 1 ) + { + ETransformSelection-->GetSizeButton.setActive( false ); + ETransformSelection-->GetScaleButton.setActive( false ); + } + else + { + ETransformSelection-->GetSizeButton.setActive( true ); + ETransformSelection-->GetScaleButton.setActive( true ); + } + + ETransformSelection-->ApplyButton.setActive( true ); + } + else + { + // With more than one selected, only the position button + // is active + ETransformSelection-->GetPosButton.setActive( true ); + ETransformSelection-->GetRotButton.setActive( false ); + ETransformSelection-->GetScaleButton.setActive( false ); + ETransformSelection-->GetSizeButton.setActive( false ); + + ETransformSelection-->ApplyButton.setActive( true ); + + // If both RotRelative and RotLocal are unchecked, then go with RotLocal + if( ETransformSelection-->RotRelative.getValue() == 0 && ETransformSelection-->RotLocal.getValue() == 0 ) + { + ETransformSelection-->RotLocal.setStateOn( true ); + } + } +} + +function ETransformSelection::apply( %this ) +{ + %position = ETransformSelection-->DoPosition.getValue(); + %p = ETransformSelection-->PosX.getValue() SPC ETransformSelection-->PosY.getValue() SPC ETransformSelection-->PosZ.getValue(); + %relativePos = ETransformSelection-->PosRelative.getValue(); + + %rotate = ETransformSelection-->DoRotation.getValue(); + %r = mDegToRad(ETransformSelection-->Pitch.getValue()) SPC mDegToRad(ETransformSelection-->Bank.getValue()) SPC mDegToRad(ETransformSelection-->Heading.getValue()); + %relativeRot = ETransformSelection-->RotRelative.getValue(); + %rotLocal = ETransformSelection-->RotLocal.getValue(); + + // We need to check which Tab page is active + if( ETransformSelection-->ScaleTabBook.getSelectedPage() == 0 ) + { + // Scale Page + %scale = ETransformSelection-->DoScale.getValue(); + %s = ETransformSelection-->ScaleX.getValue() SPC ETransformSelection-->ScaleY.getValue() SPC ETransformSelection-->ScaleZ.getValue(); + %sRelative = ETransformSelection-->ScaleRelative.getValue(); + %sLocal = ETransformSelection-->ScaleLocal.getValue(); + + %size = false; + } + else + { + // Size Page + %size = ETransformSelection-->DoSize.getValue(); + %s = ETransformSelection-->SizeX.getValue() SPC ETransformSelection-->SizeY.getValue() SPC ETransformSelection-->SizeZ.getValue(); + %sRelative = ETransformSelection-->SizeRelative.getValue(); + %sLocal = ETransformSelection-->SizeLocal.getValue(); + + %scale = false; + } + + EWorldEditor.transformSelection(%position, %p, %relativePos, %rotate, %r, %relativeRot, %rotLocal, %scale ? 1 : (%size ? 2 : 0), %s, %sRelative, %sLocal); +} + +function ETransformSelection::getAbsPosition( %this ) +{ + %pos = EWorldEditor.getSelectionCentroid(); + ETransformSelection-->PosX.setText(getWord(%pos, 0)); + ETransformSelection-->PosY.setText(getWord(%pos, 1)); + ETransformSelection-->PosZ.setText(getWord(%pos, 2)); + + // Turn off relative as we're populating absolute values + ETransformSelection-->PosRelative.setValue(0); + + // Finally, set the Position check box as active. The user + // likely wants this if they're getting the position. + ETransformSelection-->DoPosition.setValue(1); +} + +function ETransformSelection::getAbsRotation( %this ) +{ + %count = EWorldEditor.getSelectionSize(); + + // If we have more than one SceneObject selected, + // we must exit. + %obj = -1; + for( %i=0; %i<%count; %i++) + { + %test = EWorldEditor.getSelectedObject( %i ); + if( %test.isMemberOfClass("SceneObject") ) + { + if( %obj != -1 ) + return; + + %obj = %test; + } + } + + if( %obj == -1 ) + { + // No SceneObjects selected + return; + } + + %rot = %obj.getEulerRotation(); + ETransformSelection-->Pitch.setText(getWord(%rot, 0)); + ETransformSelection-->Bank.setText(getWord(%rot, 1)); + ETransformSelection-->Heading.setText(getWord(%rot, 2)); + + // Turn off relative as we're populating absolute values. + // Of course this means that we need to set local on. + ETransformSelection-->RotRelative.setValue(0); + ETransformSelection-->RotLocal.setValue(1); + + // Finally, set the Rotation check box as active. The user + // likely wants this if they're getting the position. + ETransformSelection-->DoRotation.setValue(1); +} + +function ETransformSelection::getAbsScale( %this ) +{ + %count = EWorldEditor.getSelectionSize(); + + // If we have more than one SceneObject selected, + // we must exit. + %obj = -1; + for( %i=0; %i<%count; %i++) + { + %test = EWorldEditor.getSelectedObject( %i ); + if( %test.isMemberOfClass("SceneObject") ) + { + if( %obj != -1 ) + return; + + %obj = %test; + } + } + + if( %obj == -1 ) + { + // No SceneObjects selected + return; + } + + %scale = %obj.scale; + %scalex = getWord(%scale, 0); + ETransformSelection-->ScaleX.setText(%scalex); + if( ETransformSelectionScaleProportional.getValue() == false ) + { + ETransformSelection-->ScaleY.setText(getWord(%scale, 1)); + ETransformSelection-->ScaleZ.setText(getWord(%scale, 2)); + } + else + { + ETransformSelection-->ScaleY.setText(%scalex); + ETransformSelection-->ScaleZ.setText(%scalex); + } + + // Turn off relative as we're populating absolute values + ETransformSelection-->ScaleRelative.setValue(0); + + // Finally, set the Scale check box as active. The user + // likely wants this if they're getting the position. + ETransformSelection-->DoScale.setValue(1); +} + +function ETransformSelection::getAbsSize( %this ) +{ + %count = EWorldEditor.getSelectionSize(); + + // If we have more than one SceneObject selected, + // we must exit. + %obj = -1; + for( %i=0; %i<%count; %i++) + { + %test = EWorldEditor.getSelectedObject( %i ); + if( %test.isMemberOfClass("SceneObject") ) + { + if( %obj != -1 ) + return; + + %obj = %test; + } + } + + if( %obj == -1 ) + { + // No SceneObjects selected + return; + } + + %size = %obj.getObjectBox(); + %scale = %obj.getScale(); + + %sizex = (getWord(%size, 3) - getWord(%size, 0)) * getWord(%scale, 0); + ETransformSelection-->SizeX.setText( %sizex ); + if( ETransformSelectionSizeProportional.getValue() == false ) + { + ETransformSelection-->SizeY.setText( (getWord(%size, 4) - getWord(%size, 1)) * getWord(%scale, 1) ); + ETransformSelection-->SizeZ.setText( (getWord(%size, 5) - getWord(%size, 2)) * getWord(%scale, 2) ); + } + else + { + ETransformSelection-->SizeY.setText( %sizex ); + ETransformSelection-->SizeZ.setText( %sizex ); + } + + // Turn off relative as we're populating absolute values + ETransformSelection-->SizeRelative.setValue(0); + + // Finally, set the Size check box as active. The user + // likely wants this if they're getting the position. + ETransformSelection-->DoSize.setValue(1); +} + +function ETransformSelection::RotRelativeChanged( %this ) +{ + if( ETransformSelection-->RotRelative.getValue() == 0 ) + { + // With absolute rotation, it must happen locally + ETransformSelection-->RotLocal.setStateOn( true ); + } +} + +function ETransformSelection::RotLocalChanged( %this ) +{ + if( ETransformSelection-->RotLocal.getValue() == 0 ) + { + // Non-local rotation can only happen relatively + ETransformSelection-->RotRelative.setStateOn( true ); + } +} + +//----------------------------------------------------------------------------- + +function ETransformSelectionScaleProportional::onClick( %this ) +{ + if( %this.getValue() == 1 ) + { + %scalex = ETransformSelection-->ScaleX.getValue(); + ETransformSelection-->ScaleY.setValue( %scalex ); + ETransformSelection-->ScaleZ.setValue( %scalex ); + + ETransformSelection-->ScaleY.setActive( false ); + ETransformSelection-->ScaleZ.setActive( false ); + } + else + { + ETransformSelection-->ScaleY.setActive( true ); + ETransformSelection-->ScaleZ.setActive( true ); + } + + Parent::onClick(%this); +} + +function ETransformSelectionSizeProportional::onClick( %this ) +{ + if( %this.getValue() == 1 ) + { + %scalex = ETransformSelection-->SizeX.getValue(); + ETransformSelection-->SizeY.setValue( %scalex ); + ETransformSelection-->SizeZ.setValue( %scalex ); + + ETransformSelection-->SizeY.setActive( false ); + ETransformSelection-->SizeZ.setActive( false ); + } + else + { + ETransformSelection-->SizeY.setActive( true ); + ETransformSelection-->SizeZ.setActive( true ); + } + + Parent::onClick(%this); +} + +//----------------------------------------------------------------------------- + +function ETransformSelectionButtonClass::onClick( %this ) +{ + %id = %this.getRoot().getFirstResponder(); + if( %id > -1 && ETransformSelection.controlIsChild(%id) ) + { + (%id).clearFirstResponder(true); + } +} + +function ETransformSelectionCheckBoxClass::onClick( %this ) +{ + %id = %this.getRoot().getFirstResponder(); + if( %id > -1 && ETransformSelection.controlIsChild(%id) ) + { + (%id).clearFirstResponder(true); + } +} + +//----------------------------------------------------------------------------- + +function ETransformSelectionTextEdit::onGainFirstResponder( %this ) +{ + if( %this.isActive() ) + { + %this.selectAllText(); + } +} + +function ETransformSelectionTextEdit::onValidate( %this ) +{ + if( %this.getInternalName() $= "ScaleX" && ETransformSelectionScaleProportional.getValue() == true ) + { + // Set the Y and Z values to match + %scalex = ETransformSelection-->ScaleX.getValue(); + ETransformSelection-->ScaleY.setValue( %scalex ); + ETransformSelection-->ScaleZ.setValue( %scalex ); + } + + if( %this.getInternalName() $= "SizeX" && ETransformSelectionSizeProportional.getValue() == true ) + { + // Set the Y and Z values to match + %sizex = ETransformSelection-->SizeX.getValue(); + ETransformSelection-->SizeY.setValue( %sizex ); + ETransformSelection-->SizeZ.setValue( %sizex ); + } +} diff --git a/Templates/Empty/game/tools/worldEditor/scripts/undoManager.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/undoManager.ed.cs new file mode 100644 index 000000000..7f05ffd19 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/undoManager.ed.cs @@ -0,0 +1,147 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function EUndoManager::onUndo( %this ) +{ +} + +function EUndoManager::onRedo( %this ) +{ +} + +function EUndoManager::onAddUndo( %this ) +{ +} + +function EUndoManager::onRemoveUndo( %this ) +{ +} + +function EUndoManager::onClear( %this ) +{ +} + +function EUndoManager::updateUndoMenu( %this, %editMenu ) +{ + // TODO: If we ever fix the TerrainEditor and WorldEditor + // to have descriptive UndoAction names then we can change + // the text as part of the menu update. + + %undoName = %this.getNextUndoName(); + %redoName = %this.getNextRedoName(); + + %editMenu.setItemName( 0, "Undo " @ %undoName ); + %editMenu.setItemName( 1, "Redo " @ %redoName ); + + %editMenu.enableItem( 0, %undoName !$= "" ); + %editMenu.enableItem( 1, %redoName !$= "" ); +} + + +/// A helper for submitting a creation undo action. +function MECreateUndoAction::submit( %undoObject ) +{ + // The instant group will try to add our + // UndoAction if we don't disable it. + pushInstantGroup(); + + // Create the undo action. + %action = new MECreateUndoAction() + { + actionName = "Create " @ %undoObject.getClassName(); + }; + + // Restore the instant group. + popInstantGroup(); + + // Set the object to undo. + %action.addObject( %undoObject ); + + // Submit it. + %action.addToManager( Editor.getUndoManager() ); +} + +function MECreateUndoAction::onUndone( %this ) +{ + EWorldEditor.syncGui(); +} + +function MECreateUndoAction::onRedone( %this ) +{ + EWorldEditor.syncGui(); +} + + +/// A helper for submitting a delete undo action. +/// If %wordSeperated is not specified or is false it is assumed %deleteObjects +/// is tab sperated. +function MEDeleteUndoAction::submit( %deleteObjects, %wordSeperated ) +{ + // The instant group will try to add our + // UndoAction if we don't disable it. + pushInstantGroup(); + + // Create the undo action. + %action = new MEDeleteUndoAction() + { + actionName = "Delete"; + }; + + // Restore the instant group. + popInstantGroup(); + + // Add the deletion objects to the action which + // will take care of properly deleting them. + %deleteObjects = trim( %deleteObjects ); + + if ( %wordSeperated ) + { + %count = getWordCount( %deleteObjects ); + for ( %i = 0; %i < %count; %i++ ) + { + %object = getWord( %deleteObjects, %i ); + %action.deleteObject( %object ); + } + } + else + { + %count = getFieldCount( %deleteObjects ); + for ( %i = 0; %i < %count; %i++ ) + { + %object = getField( %deleteObjects, %i ); + %action.deleteObject( %object ); + } + } + + // Submit it. + %action.addToManager( Editor.getUndoManager() ); +} + +function MEDeleteUndoAction::onUndone( %this ) +{ + EWorldEditor.syncGui(); +} + +function MEDeleteUndoAction::onRedone( %this ) +{ + EWorldEditor.syncGui(); +} diff --git a/Templates/Empty/game/tools/worldEditor/scripts/visibilityLayer.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/visibilityLayer.ed.cs new file mode 100644 index 000000000..ae69d8f82 --- /dev/null +++ b/Templates/Empty/game/tools/worldEditor/scripts/visibilityLayer.ed.cs @@ -0,0 +1,193 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +function EVisibility::onWake( %this ) +{ + // Create the array if it + // doesn't already exist. + if ( !isObject( %this.array ) ) + %this.array = new ArrayObject(); + + // Create the array if it + // doesn't already exist. + if ( !isObject( %this.classArray ) ) + { + %this.classArray = new ArrayObject(); + %this.addClassOptions(); + } + + %this.updateOptions(); + +} + +function EVisibility::updateOptions( %this ) +{ + // First clear the stack control. + %this-->theVisOptionsList.clear(); + + // Go through all the + // parameters in our array and + // create a check box for each. + for ( %i = 0; %i < %this.array.count(); %i++ ) + { + %text = " " @ %this.array.getValue( %i ); + %val = %this.array.getKey( %i ); + %var = getWord( %val, 0 ); + %toggleFunction = getWord( %val, 1 ); + + %textLength = strlen( %text ); + + %cmd = ""; + if ( %toggleFunction !$= "" ) + %cmd = %toggleFunction @ "( $thisControl.getValue() );"; + + %checkBox = new GuiCheckBoxCtrl() + { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiCheckBoxListProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = (%textLength * 4) @ " 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Variable = %var; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = %text; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + Command = %cmd; + }; + + %this-->theVisOptionsList.addGuiControl( %checkBox ); + } +} + +function EVisibility::addOption( %this, %text, %varName, %toggleFunction ) +{ + // Create the array if it + // doesn't already exist. + if ( !isObject( %this.array ) ) + %this.array = new ArrayObject(); + + %this.array.push_back( %varName @ " " @ %toggleFunction, %text ); + %this.array.uniqueKey(); + %this.array.sortd(); + %this.updateOptions(); +} + +function EVisibility::addClassOptions( %this ) +{ + %visList = %this-->theClassVisList; + %selList = %this-->theClassSelList; + + // First clear the stack control. + + %visList.clear(); + %selList.clear(); + + %classList = enumerateConsoleClasses( "SceneObject" ); + %classCount = getFieldCount( %classList ); + + for ( %i = 0; %i < %classCount; %i++ ) + { + %className = getField( %classList, %i ); + %this.classArray.push_back( %className ); + } + + // Remove duplicates and sort by key. + %this.classArray.uniqueKey(); + %this.classArray.sortkd(); + + // Go through all the + // parameters in our array and + // create a check box for each. + for ( %i = 0; %i < %this.classArray.count(); %i++ ) + { + %class = %this.classArray.getKey( %i ); + + %visVar = "$" @ %class @ "::isRenderable"; + %selVar = "$" @ %class @ "::isSelectable"; + + %textLength = strlen( %class ); + %text = " " @ %class; + + // Add visibility toggle. + + %visCheckBox = new GuiCheckBoxCtrl() + { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiCheckBoxListFlipedProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = (%textLength * 4) @ " 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Variable = %visVar; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Show/hide all " @ %class @ " objects."; + text = %text; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + + %visList.addGuiControl( %visCheckBox ); + + // Add selectability toggle. + + %selCheckBox = new GuiCheckBoxCtrl() + { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiCheckBoxListFlipedProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = (%textLength * 4) @ " 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Variable = %selVar; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Enable/disable selection of all " @ %class @ " objects."; + text = %text; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + + %selList.addGuiControl( %selCheckBox ); + } +} diff --git a/Templates/Empty/game/web/getplugin.jpg b/Templates/Empty/game/web/getplugin.jpg new file mode 100644 index 000000000..9881868cc Binary files /dev/null and b/Templates/Empty/game/web/getplugin.jpg differ diff --git a/Templates/Empty/game/web/jquery-1.3.2.min.js b/Templates/Empty/game/web/jquery-1.3.2.min.js new file mode 100644 index 000000000..b1ae21d8b --- /dev/null +++ b/Templates/Empty/game/web/jquery-1.3.2.min.js @@ -0,0 +1,19 @@ +/* + * jQuery JavaScript Library v1.3.2 + * http://jquery.com/ + * + * Copyright (c) 2009 John Resig + * Dual licensed under the MIT and GPL licenses. + * http://docs.jquery.com/License + * + * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009) + * Revision: 6246 + */ +(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F<J;F++){var G=M[F];if(G.selected){K=o(G).val();if(H){return K}L.push(K)}}return L}return(E.value||"").replace(/\r/g,"")}return g}if(typeof K==="number"){K+=""}return this.each(function(){if(this.nodeType!=1){return}if(o.isArray(K)&&/radio|checkbox/.test(this.type)){this.checked=(o.inArray(this.value,K)>=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G<E;G++){L.call(K(this[G],H),this.length>1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H<I;H++){if((G=arguments[H])!=null){for(var F in G){var K=J[F],L=G[F];if(J===L){continue}if(E&&L&&typeof L==="object"&&!L.nodeType){J[F]=o.extend(E,K||(L.length!=null?[]:{}),L)}else{if(L!==g){J[F]=L}}}}}return J};var b=/z-?index|font-?weight|opacity|zoom|line-?height/i,q=document.defaultView||{},s=Object.prototype.toString;o.extend({noConflict:function(E){l.$=p;if(E){l.jQuery=y}return o},isFunction:function(E){return s.call(E)==="[object Function]"},isArray:function(E){return s.call(E)==="[object Array]"},isXMLDoc:function(E){return E.nodeType===9&&E.documentElement.nodeName!=="HTML"||!!E.ownerDocument&&o.isXMLDoc(E.ownerDocument)},globalEval:function(G){if(G&&/\S/.test(G)){var F=document.getElementsByTagName("head")[0]||document.documentElement,E=document.createElement("script");E.type="text/javascript";if(o.support.scriptEval){E.appendChild(document.createTextNode(G))}else{E.text=G}F.insertBefore(E,F.firstChild);F.removeChild(E)}},nodeName:function(F,E){return F.nodeName&&F.nodeName.toUpperCase()==E.toUpperCase()},each:function(G,K,F){var E,H=0,I=G.length;if(F){if(I===g){for(E in G){if(K.apply(G[E],F)===false){break}}}else{for(;H<I;){if(K.apply(G[H++],F)===false){break}}}}else{if(I===g){for(E in G){if(K.call(G[E],E,G[E])===false){break}}}else{for(var J=G[0];H<I&&K.call(J,H,J)!==false;J=G[++H]){}}}return G},prop:function(H,I,G,F,E){if(o.isFunction(I)){I=I.call(H,F)}return typeof I==="number"&&G=="curCSS"&&!b.test(E)?I+"px":I},className:{add:function(E,F){o.each((F||"").split(/\s+/),function(G,H){if(E.nodeType==1&&!o.className.has(E.className,H)){E.className+=(E.className?" ":"")+H}})},remove:function(E,F){if(E.nodeType==1){E.className=F!==g?o.grep(E.className.split(/\s+/),function(G){return !o.className.has(F,G)}).join(" "):""}},has:function(F,E){return F&&o.inArray(E,(F.className||F).toString().split(/\s+/))>-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+"></"+T+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!O.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!O.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!O.indexOf("<td")||!O.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!O.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||!o.support.htmlSerialize&&[1,"div<div>","</div>"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/<tbody/i.test(S),N=!O.indexOf("<table")&&!R?L.firstChild&&L.firstChild.childNodes:Q[1]=="<table>"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E<F;E++){if(H[E]===G){return E}}return -1},merge:function(H,E){var F=0,G,I=H.length;if(!o.support.getAll){while((G=E[F++])!=null){if(G.nodeType!=8){H[I++]=G}}}else{while((G=E[F++])!=null){H[I++]=G}}return H},unique:function(K){var F=[],E={};try{for(var G=0,H=K.length;G<H;G++){var J=o.data(K[G]);if(!E[J]){E[J]=true;F.push(K[G])}}}catch(I){F=K}return F},grep:function(F,J,E){var G=[];for(var H=0,I=F.length;H<I;H++){if(!E!=!J(F[H],H)){G.push(F[H])}}return G},map:function(E,J){var F=[];for(var G=0,H=E.length;G<H;G++){var I=J(E[G],G);if(I!=null){F[F.length]=I}}return F.concat.apply([],F)}});var C=navigator.userAgent.toLowerCase();o.browser={version:(C.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[0,"0"])[1],safari:/webkit/.test(C),opera:/opera/.test(C),msie:/msie/.test(C)&&!/opera/.test(C),mozilla:/mozilla/.test(C)&&!/(compatible|webkit)/.test(C)};o.each({parent:function(E){return E.parentNode},parents:function(E){return o.dir(E,"parentNode")},next:function(E){return o.nth(E,2,"nextSibling")},prev:function(E){return o.nth(E,2,"previousSibling")},nextAll:function(E){return o.dir(E,"nextSibling")},prevAll:function(E){return o.dir(E,"previousSibling")},siblings:function(E){return o.sibling(E.parentNode.firstChild,E)},children:function(E){return o.sibling(E.firstChild)},contents:function(E){return o.nodeName(E,"iframe")?E.contentDocument||E.contentWindow.document:o.makeArray(E.childNodes)}},function(E,F){o.fn[E]=function(G){var H=o.map(this,F);if(G&&typeof G=="string"){H=o.multiFilter(G,H)}return this.pushStack(o.unique(H),E,G)}});o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(E,F){o.fn[E]=function(G){var J=[],L=o(G);for(var K=0,H=L.length;K<H;K++){var I=(K>0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}}); +/* + * Sizzle CSS Selector Engine - v0.9.3 + * Copyright 2009, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa<ab.length;aa++){if(ab[aa]===ab[aa-1]){ab.splice(aa--,1)}}}}}return ab};F.matches=function(T,U){return F(T,null,null,U)};F.find=function(aa,T,ab){var Z,X;if(!aa){return[]}for(var W=0,V=I.order.length;W<V;W++){var Y=I.order[W],X;if((X=I.match[Y].exec(aa))){var U=RegExp.leftContext;if(U.substr(U.length-1)!=="\\"){X[1]=(X[1]||"").replace(/\\/g,"");Z=I.find[Y](X,T,ab);if(Z!=null){aa=aa.replace(I.match[Y],"");break}}}}if(!Z){Z=T.getElementsByTagName("*")}return{set:Z,expr:aa}};F.filter=function(ad,ac,ag,W){var V=ad,ai=[],aa=ac,Y,T,Z=ac&&ac[0]&&Q(ac[0]);while(ad&&ac.length){for(var ab in I.filter){if((Y=I.match[ab].exec(ad))!=null){var U=I.filter[ab],ah,af;T=false;if(aa==ai){ai=[]}if(I.preFilter[ab]){Y=I.preFilter[ab](Y,aa,ag,ai,W,Z);if(!Y){T=ah=true}else{if(Y===true){continue}}}if(Y){for(var X=0;(af=aa[X])!=null;X++){if(af){ah=U(af,Y,X,aa);var ae=W^!!ah;if(ag&&ah!=null){if(ae){T=true}else{aa[X]=false}}else{if(ae){ai.push(af);T=true}}}}}if(ah!==g){if(!ag){aa=ai}ad=ad.replace(I.match[ab],"");if(!T){return[]}break}}}if(ad==V){if(T==null){throw"Syntax error, unrecognized expression: "+ad}else{break}}V=ad}return aa};var I=F.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(T){return T.getAttribute("href")}},relative:{"+":function(aa,T,Z){var X=typeof T==="string",ab=X&&!/\W/.test(T),Y=X&&!ab;if(ab&&!Z){T=T.toUpperCase()}for(var W=0,V=aa.length,U;W<V;W++){if((U=aa[W])){while((U=U.previousSibling)&&U.nodeType!==1){}aa[W]=Y||U&&U.nodeName===T?U||false:U===T}}if(Y){F.filter(T,aa,true)}},">":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){var W=Y.parentNode;Z[V]=W.nodeName===U?W:false}}}else{for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){Z[V]=X?Y.parentNode:Y.parentNode===U}}if(X){F.filter(U,Z,true)}}},"":function(W,U,Y){var V=L++,T=S;if(!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("parentNode",U,V,W,X,Y)},"~":function(W,U,Y){var V=L++,T=S;if(typeof U==="string"&&!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("previousSibling",U,V,W,X,Y)}},find:{ID:function(U,V,W){if(typeof V.getElementById!=="undefined"&&!W){var T=V.getElementById(U[1]);return T?[T]:[]}},NAME:function(V,Y,Z){if(typeof Y.getElementsByName!=="undefined"){var U=[],X=Y.getElementsByName(V[1]);for(var W=0,T=X.length;W<T;W++){if(X[W].getAttribute("name")===V[1]){U.push(X[W])}}return U.length===0?null:U}},TAG:function(T,U){return U.getElementsByTagName(T[1])}},preFilter:{CLASS:function(W,U,V,T,Z,aa){W=" "+W[1].replace(/\\/g,"")+" ";if(aa){return W}for(var X=0,Y;(Y=U[X])!=null;X++){if(Y){if(Z^(Y.className&&(" "+Y.className+" ").indexOf(W)>=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return U<T[3]-0},gt:function(V,U,T){return U>T[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W<T;W++){if(Y[W]===Z){return false}}return true}}}},CHILD:function(T,W){var Z=W[1],U=T;switch(Z){case"only":case"first":while(U=U.previousSibling){if(U.nodeType===1){return false}}if(Z=="first"){return true}U=T;case"last":while(U=U.nextSibling){if(U.nodeType===1){return false}}return true;case"nth":var V=W[2],ac=W[3];if(V==1&&ac==0){return true}var Y=W[0],ab=T.parentNode;if(ab&&(ab.sizcache!==Y||!T.nodeIndex)){var X=0;for(U=ab.firstChild;U;U=U.nextSibling){if(U.nodeType===1){U.nodeIndex=++X}}ab.sizcache=Y}var aa=T.nodeIndex-ac;if(V==0){return aa==0}else{return(aa%V==0&&aa/V>=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V<T;V++){U.push(X[V])}}else{for(var V=0;X[V];V++){U.push(X[V])}}}return U}}var G;if(document.documentElement.compareDocumentPosition){G=function(U,T){var V=U.compareDocumentPosition(T)&4?-1:U===T?0:1;if(V===0){hasDuplicate=true}return V}}else{if("sourceIndex" in document.documentElement){G=function(U,T){var V=U.sourceIndex-T.sourceIndex;if(V===0){hasDuplicate=true}return V}}else{if(document.createRange){G=function(W,U){var V=W.ownerDocument.createRange(),T=U.ownerDocument.createRange();V.selectNode(W);V.collapse(true);T.selectNode(U);T.collapse(true);var X=V.compareBoundaryPoints(Range.START_TO_END,T);if(X===0){hasDuplicate=true}return X}}}}(function(){var U=document.createElement("form"),V="script"+(new Date).getTime();U.innerHTML="<input name='"+V+"'/>";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="<a href='#'></a>";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="<p class='TEST'></p>";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="<div class='test e'></div><div class='test'></div>";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1&&!ac){T.sizcache=Y;T.sizset=W}if(T.nodeName===Z){X=T;break}T=T[U]}ad[W]=X}}}function S(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1){if(!ac){T.sizcache=Y;T.sizset=W}if(typeof Z!=="string"){if(T===Z){X=true;break}}else{if(F.filter(Z,[T]).length>0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z<U;Z++){F(T,V[Z],W)}return F.filter(X,W)};o.find=F;o.filter=F.filter;o.expr=F.selectors;o.expr[":"]=o.expr.filters;F.selectors.filters.hidden=function(T){return T.offsetWidth===0||T.offsetHeight===0};F.selectors.filters.visible=function(T){return T.offsetWidth>0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F<E.length){o.event.proxy(G,E[F++])}return this.click(o.event.proxy(G,function(H){this.lastToggle=(this.lastToggle||0)%F;H.preventDefault();return E[this.lastToggle++].apply(this,arguments)||false}))},hover:function(E,F){return this.mouseenter(E).mouseleave(F)},ready:function(E){B();if(o.isReady){E.call(document,o)}else{o.readyList.push(E)}return this},live:function(G,F){var E=o.event.proxy(F);E.guid+=this.selector+G;o(document).bind(i(G,this.selector),this.selector,E);return this},die:function(F,E){o(document).unbind(i(F,this.selector),E?{guid:E.guid+this.selector+F}:null);return this}});function c(H){var E=RegExp("(^|\\.)"+H.type+"(\\.|$)"),G=true,F=[];o.each(o.data(this,"events").live||[],function(I,J){if(E.test(J.type)){var K=o(H.target).closest(J.data)[0];if(K){F.push({elem:K,fn:J})}}});F.sort(function(J,I){return o.data(J.elem,"closest")-o.data(I.elem,"closest")});o.each(F,function(){if(this.fn.call(this.elem,H,this.fn.data)===false){return(G=false)}});return G}function i(F,E){return["live",F,E.replace(/\./g,"`").replace(/ /g,"|")].join(".")}o.extend({isReady:false,readyList:[],ready:function(){if(!o.isReady){o.isReady=true;if(o.readyList){o.each(o.readyList,function(){this.call(document,o)});o.readyList=null}o(document).triggerHandler("ready")}}});var x=false;function B(){if(x){return}x=true;if(document.addEventListener){document.addEventListener("DOMContentLoaded",function(){document.removeEventListener("DOMContentLoaded",arguments.callee,false);o.ready()},false)}else{if(document.attachEvent){document.attachEvent("onreadystatechange",function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",arguments.callee);o.ready()}});if(document.documentElement.doScroll&&l==l.top){(function(){if(o.isReady){return}try{document.documentElement.doScroll("left")}catch(E){setTimeout(arguments.callee,0);return}o.ready()})()}}}o.event.add(l,"load",o.ready)}o.each(("blur,focus,load,resize,scroll,unload,click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,change,select,submit,keydown,keypress,keyup,error").split(","),function(F,E){o.fn[E]=function(G){return G?this.bind(E,G):this.trigger(E)}});o(l).bind("unload",function(){for(var E in o.cache){if(E!=1&&o.cache[E].handle){o.event.remove(o.cache[E].handle.elem)}}});(function(){o.support={};var F=document.documentElement,G=document.createElement("script"),K=document.createElement("div"),J="script"+(new Date).getTime();K.style.display="none";K.innerHTML=' <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';var H=K.getElementsByTagName("*"),E=K.getElementsByTagName("a")[0];if(!H||!H.length||!E){return}o.support={leadingWhitespace:K.firstChild.nodeType==3,tbody:!K.getElementsByTagName("tbody").length,objectAll:!!K.getElementsByTagName("object")[0].getElementsByTagName("*").length,htmlSerialize:!!K.getElementsByTagName("link").length,style:/red/.test(E.getAttribute("style")),hrefNormalized:E.getAttribute("href")==="/a",opacity:E.style.opacity==="0.5",cssFloat:!!E.style.cssFloat,scriptEval:false,noCloneEvent:true,boxModel:null};G.type="text/javascript";try{G.appendChild(document.createTextNode("window."+J+"=1;"))}catch(I){}F.insertBefore(G,F.firstChild);if(l[J]){o.support.scriptEval=true;delete l[J]}F.removeChild(G);if(K.attachEvent&&K.fireEvent){K.attachEvent("onclick",function(){o.support.noCloneEvent=false;K.detachEvent("onclick",arguments.callee)});K.cloneNode(true).fireEvent("onclick")}o(function(){var L=document.createElement("div");L.style.width=L.style.paddingLeft="1px";document.body.appendChild(L);o.boxModel=o.support.boxModel=L.offsetWidth===2;document.body.removeChild(L).style.display="none"})})();var w=o.support.cssFloat?"cssFloat":"styleFloat";o.props={"for":"htmlFor","class":"className","float":w,cssFloat:w,styleFloat:w,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",tabindex:"tabIndex"};o.fn.extend({_load:o.fn.load,load:function(G,J,K){if(typeof G!=="string"){return this._load(G)}var I=G.indexOf(" ");if(I>=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("<div/>").append(M.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H<F;H++){var E=o.data(this[H],"olddisplay");this[H].style.display=E||"";if(o.css(this[H],"display")==="none"){var G=this[H].tagName,K;if(m[G]){K=m[G]}else{var I=o("<"+G+" />").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H<F;H++){this[H].style.display=o.data(this[H],"olddisplay")||""}return this}},hide:function(H,I){if(H){return this.animate(t("hide",3),H,I)}else{for(var G=0,F=this.length;G<F;G++){var E=o.data(this[G],"olddisplay");if(!E&&E!=="none"){o.data(this[G],"olddisplay",o.css(this[G],"display"))}}for(var G=0,F=this.length;G<F;G++){this[G].style.display="none"}return this}},_toggle:o.fn.toggle,toggle:function(G,F){var E=typeof G==="boolean";return o.isFunction(G)&&o.isFunction(F)?this._toggle.apply(this,arguments):G==null||E?this.each(function(){var H=E?G:o(this).is(":hidden");o(this)[H?"show":"hide"]()}):this.animate(t("toggle",3),G,F)},fadeTo:function(E,G,F){return this.animate({opacity:G},E,F)},animate:function(I,F,H,G){var E=o.speed(F,H,G);return this[E.queue===false?"each":"queue"](function(){var K=o.extend({},E),M,L=this.nodeType==1&&o(this).is(":hidden"),J=this;for(M in I){if(I[M]=="hide"&&L||I[M]=="show"&&!L){return K.complete.call(this)}if((M=="height"||M=="width")&&this.style){K.display=o.css(this,"display");K.overflow=this.style.overflow}}if(K.overflow!=null){this.style.overflow="hidden"}K.curAnim=o.extend({},I);o.each(I,function(O,S){var R=new o.fx(J,K,O);if(/toggle|show|hide/.test(S)){R[S=="toggle"?L?"show":"hide":S](I)}else{var Q=S.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),T=R.cur(true)||0;if(Q){var N=parseFloat(Q[2]),P=Q[3]||"px";if(P!="px"){J.style[O]=(N||1)+P;T=((N||1)/R.cur(true))*T;J.style[O]=T+P}if(Q[1]){N=((Q[1]=="-="?-1:1)*N)+T}R.custom(T,N,P)}else{R.custom(T,S,"")}}});return true})},stop:function(F,E){var G=o.timers;if(F){this.queue([])}this.each(function(){for(var H=G.length-1;H>=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J<K.length;J++){if(!K[J]()){K.splice(J--,1)}}if(!K.length){clearInterval(n);n=g}},13)}},show:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.show=true;this.custom(this.prop=="width"||this.prop=="height"?1:0,this.cur());o(this.elem).show()},hide:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(H){var G=e();if(H||G>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})(); \ No newline at end of file diff --git a/Templates/Empty/game/web/sample.html b/Templates/Empty/game/web/sample.html new file mode 100644 index 000000000..599566cfb --- /dev/null +++ b/Templates/Empty/game/web/sample.html @@ -0,0 +1,259 @@ +<!-- saved from url=(0013)about:internet --> +<!-- see, http://technet.microsoft.com/en-us/library/bb457150.aspx#EHAA for how, why, this works for local controls --> +<!-- Please note that the saved from line must end in CR LF. Some HTML editors only insert a LF. (Thanks Microsoft) --> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<meta name="description" content="Web Game Template" /> +<script type="text/javascript" src="jquery-1.3.2.min.js"></script> +<link rel="stylesheet" href="styles.css" type="text/css" /> + +<script type="text/javascript" language="javascript"> + +// Relative path on web server to installer +var installerPath = "MyGameInstaller" + +ua = navigator.userAgent.toLowerCase(); +if( ua.indexOf('os x') != -1 || ua.indexOf('osx') != -1) + installerPath += ".pkg"; +else + installerPath += ".exe"; + +// Firefox/Chrome/Safari +var mimeType = "application/x-emptytemplateplugin"; + +// Internet Explorer +var projId = "IEEmptyPlugin.IEWebGameCtrl.1"; +var clsId = "D62D1B36-253D-4218-B033-5ACE0B42B8BF"; + +var pluginInstalled = false; +var minimumPluginVersion = 1.0; + +// You can set this to true if you want the page to automatically reload +// once the plugin is installed. However, this can be better handled by +// the installer process in most cases (by opening up web page at end of +// install process, setting up desktop/start menu shortcuts to launch web page +// etc +var autoReload = false; + +// Default client screen (overridden below from actual browser window) +var cscreenW = 800; +var cscreenH = 600; + +function getClientScreenSize() { + if( typeof( window.innerWidth ) == 'number' ) { + //Non-IE + cscreenW = window.innerWidth; + cscreenH = window.innerHeight; + } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) { + //IE 6+ in 'standards compliant mode' + cscreenW = document.documentElement.clientWidth; + cscreenH = document.documentElement.clientHeight; + } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) { + //IE 4 compatible + cscreenW = document.body.clientWidth; + cscreenH = document.body.clientHeight; + } +} + +function gameObjectResize(){ + if (!pluginInstalled) + return; + + getClientScreenSize(); + var aspectRatio = 800.0/600.0; + var w = cscreenW - 50; + var h = cscreenH - 125; + if( w/h > aspectRatio ) + w = h*aspectRatio; + else + h = w/aspectRatio; + var minW = 640; + if( w < minW ){ + w = minW; + h = w/aspectRatio; + } + $('#gameobject').width( Math.floor(w) ); + $('#gameobject').height( Math.floor(h) ); + $('#main').width( Math.floor(w + 2) ); + var mygame = document.getElementById("MyGame"); + mygame.width = Math.floor(w); + mygame.height = Math.floor(h); +} + +$(window).resize( gameObjectResize ); + +$(document).ready(function(){ + if (pluginInstalled) + { + var mygame = document.getElementById("MyGame"); + // Let the game object know the page is all loaded + // This is important to register any TorqueScript <-> JavaScript callbacks, etc + mygame.startup(); + // Export the TorqueScript -> JavaScript bridge test function + mygame.exportFunction("bridgeCallback",3); + // Enable the bridge test button now that we're all set + var bridgetest = document.getElementById("bridgetest"); + bridgetest.disabled = false; + gameObjectResize(); + } +}); + +// Returns the version of Internet Explorer +// or -1 for non-IE browser +// or -2 for 64 bit IE browser +// (indicating the use of another browser). +function getInternetExplorerVersion() +{ + var rv = -1; // Return value for non-IE browser + + if (navigator.appName == 'Microsoft Internet Explorer') + { + var ua = navigator.userAgent; + + if (ua.search("Win64") != -1 || ua.search("x64") != -1) + return -2; // Return value for IE 64 bit + + var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})"); + if (re.exec(ua) != null) + rv = parseFloat( RegExp.$1 ); + } + return rv; +} + +// Checks whether the NPPlugin is installed (under Firefox/Chrome/Safari) +function nppluginIsInstalled() { + + if (!navigator || !navigator.mimeTypes) { + return -1; + } + + var mt = navigator.mimeTypes[mimeType]; + if (mt && mt.enabledPlugin) + { + var desc = mt.enabledPlugin.description; + var descArray = desc.split(" "); + var version = descArray[descArray.length - 1] + return Number(version); + } + return -1; +} + +function nppluginReload () { + navigator.plugins.refresh(); + if (nppluginIsInstalled() < 0) + window.location.reload(); + setTimeout('nppluginReload()', 500); +} + +function activexReload () { + + if (activexIsInstalled() < 0) + window.location.reload(); + setTimeout('activexReload()', 500); +} + +function onTestBridge() +{ + var mygame = document.getElementById("MyGame"); + + // set/get console variables test + // variables are automatically stored Torque 3D side in the Javascript:: namespace + // for security reasons. + mygame.setVariable("$TestBridge", 42); + var everything = mygame.getVariable("$TestBridge"); + + // this tests bidirectional calling of JavaScript <-> TorqueScript including arguments and return values + // note that testJavaScriptBridge must be specified in webConfig.h as a secure function + var result = mygame.callScript("testJavaScriptBridge('one', 'two', 'three');"); + if (parseInt(everything) != 42) + alert("JavaScript <-> TorqueScript: Failed, get/set console variable doesn't match"); + else if (result == "0") + alert("JavaScript <-> TorqueScript: All Tests Passed!"); + else if (result == "1") + alert("JavaScript -> TorqueScript: Failed, incorrect number of arguments"); + else if (result == "2") + alert("JavaScript -> TorqueScript: Failed, incorrect argument"); + else if (result == "3") + alert("TorqueScript -> JavaScript: Failed, incorrect return"); + else + alert("JavaScript -> TorqueScript: Failed, unknown error"); +} + +// Called from TorqueScript console -> JavaScript during bridge test +function bridgeCallback(arg1, arg2, arg3) +{ + if (arg1 != "one" || arg2 != "two" || arg3 != "three") + { + alert("TorqueScript -> JavaScript: Failed, incorrect argument"); + return "0"; + } + return "42"; +} +</script> + +<script language='VBScript'> +function activexIsInstalled() + on error resume next + dim gameControl + dim version + version = -1 + set gameControl = CreateObject(projId) + if IsObject(gameControl) then + version = CDbl(gameControl.getVariable("$version")) + end if + activexIsInstalled = version +end function +</script> + +</head> +<body> +<img id = "torqueLogo" src = "./torque3D_logo.jpg"> +<div id="main"> + <div style = "height: 20px;"></div> + <center>Web Game Template</center> + <div id="gameobject"> + <script type="text/javascript" language="javascript"> + + // ActiveX + var ie = getInternetExplorerVersion(); + + if ( ie == -2) { + document.write('<center><h3>This plugin is not currently supported on Internet Explorer 64 bit<br><br>Please use Internet Explorer 32 bit to access this site.</h3><centre>'); + } + else if ( ie != -1) { + if (activexIsInstalled() >= minimumPluginVersion) { + pluginInstalled = true; + document.write('<OBJECT ID="MyGame" CLASSID="CLSID:'+clsId+'" WIDTH="100%" HEIGHT="100%"></OBJECT>'); + } + else { + document.write('<center><a href="'+installerPath+'"><img src="getplugin.jpg" /></a></center>'); + if (autoReload) + activexReload(); + } + } + // Firefox/Chrome/Safari + else { + + //we do an initial refresh in case the plugin information has changed (new DLL location, newly installed, etc) + navigator.plugins.refresh(); + + if (nppluginIsInstalled() >= minimumPluginVersion) { + pluginInstalled = true; + document.write('<object id="MyGame" type="'+mimeType+'" width="100% height="100%" ></object>'); + } + else { + document.write('<center><a href="'+installerPath+'"><img src="getplugin.jpg" /></a></center>'); + if (autoReload) + nppluginReload(); + } + } + </script> + </div> + <center>(Press ESC to show the mouse cursor if hidden)</center> + <center><button id="bridgetest" disabled="true" onclick="onTestBridge();">Test JavaScript <-> TorqueScript Bridge</button></center> +</div> +</body> +</html> \ No newline at end of file diff --git a/Templates/Empty/game/web/styles.css b/Templates/Empty/game/web/styles.css new file mode 100644 index 000000000..4cabf802e --- /dev/null +++ b/Templates/Empty/game/web/styles.css @@ -0,0 +1,35 @@ +body { + background-position: top center; + background-color: White; + margin: 0px; + text-align: center; /* for IE */ + font-size: 18px; + color: #FFFFFF; +} + +#torqueLogo { + position: absolute; + left: 0px; + margin-top: 2px; +} + +div#main { + width: 802px; + margin: 0px auto; + color: black; + font-weight: bold; + font-size: 22px; + font-family: Arial; + text-align: left; /* counter the body center */ +} + +div#gameobject { + margin: 18px 0px 18px; + border:1px solid #393E42; + width: 800px; + height: 600px; +} + + + + diff --git a/Templates/Empty/game/web/torque3D_logo.jpg b/Templates/Empty/game/web/torque3D_logo.jpg new file mode 100644 index 000000000..15d259de5 Binary files /dev/null and b/Templates/Empty/game/web/torque3D_logo.jpg differ diff --git a/Templates/Empty/generateProjects.bat b/Templates/Empty/generateProjects.bat new file mode 100644 index 000000000..9e43263dd --- /dev/null +++ b/Templates/Empty/generateProjects.bat @@ -0,0 +1,19 @@ +@echo off +setlocal + +SET TORQUEDIR=%2 +IF NOT DEFINED TORQUEDIR SET TORQUEDIR=..\.. + +%TORQUEDIR%\engine\bin\php\php %TORQUEDIR%\Tools\projectGenerator\projectGenerator.php buildFiles/config/project.conf %TORQUEDIR% + +endlocal + +if X%1 == X ( + + echo. + echo REMEMBER: Restart VisualStudio if you are running it to be sure the new + echo project files are loaded! See docs for more info! + echo. + + pause +) diff --git a/Templates/Empty/generateProjects.command b/Templates/Empty/generateProjects.command new file mode 100644 index 000000000..a1ee36056 --- /dev/null +++ b/Templates/Empty/generateProjects.command @@ -0,0 +1,6 @@ +#!/bin/sh + +cd "`dirname "$0"`" + +/usr/bin/php ../../Tools/projectGenerator/projectGenerator.php buildFiles/config/project.mac.conf + diff --git a/Templates/Empty/source/readme.txt b/Templates/Empty/source/readme.txt new file mode 100644 index 000000000..e79addd05 --- /dev/null +++ b/Templates/Empty/source/readme.txt @@ -0,0 +1,7 @@ +Your project specific source files and subfolders go into this directory. + +Simply add them to this folder and then regenerate your project +Visual Studio Solution/XCode workspace with the Torque Toolbox. + + + diff --git a/Templates/Empty/source/torqueConfig.h b/Templates/Empty/source/torqueConfig.h new file mode 100644 index 000000000..1281cc825 --- /dev/null +++ b/Templates/Empty/source/torqueConfig.h @@ -0,0 +1,222 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#ifndef _TORQUECONFIG_H_ +#define _TORQUECONFIG_H_ + +//----------------------------------------------------------------------------- +//Hi, and welcome to the Torque Config file. +// +//This file is a central reference for the various configuration flags that +//you'll be using when controlling what sort of a Torque build you have. In +//general, the information here is global for your entire codebase, applying +//not only to your game proper, but also to all of your tools. + +/// Since we can build different engine "products" out of the same +/// base engine source we need a way to differentiate which product +/// this particular game is using. +/// +/// TGE 0001 +/// TGEA 0002 +/// TGB 0003 +/// TGEA 360 0004 +/// TGE WII 0005 +/// Torque 3D 0006 +/// +#define TORQUE_ENGINE_PRODUCT 0006 + +/// What's the name of your application? Used in a variety of places. +#define TORQUE_APP_NAME "Empty" + +/// What version of the application specific source code is this? +/// +/// Version number is major * 1000 + minor * 100 + revision * 10. +#define TORQUE_APP_VERSION 2009 + +/// Human readable application version string. +#define TORQUE_APP_VERSION_STRING "2009" + +/// Define me if you want to enable multithreading support. +#ifndef TORQUE_MULTITHREAD +#define TORQUE_MULTITHREAD +#endif + +/// Define me if you want to disable Torque memory manager. +#ifndef TORQUE_DISABLE_MEMORY_MANAGER +#define TORQUE_DISABLE_MEMORY_MANAGER +#endif + +/// Define me if you want to disable the virtual mount system. +//#define TORQUE_DISABLE_VIRTUAL_MOUNT_SYSTEM + +/// Define me if you want to disable looking for the root of a given path +/// within a zip file. This means that the zip file name itself must be +/// the root of the path. Requires the virtual mount system to be active. +//#define TORQUE_DISABLE_FIND_ROOT_WITHIN_ZIP + +/// Define me if you don't want Torque to compile dso's +#define TORQUE_NO_DSO_GENERATION + +// Define me if this build is a tools build + +#ifndef TORQUE_PLAYER +# define TORQUE_TOOLS +#else +# undef TORQUE_TOOLS +#endif + +/// Define me if you want to enable the profiler. +/// See also the TORQUE_SHIPPING block below +//#define TORQUE_ENABLE_PROFILER + +/// Define me to enable debug mode; enables a great number of additional +/// sanity checks, as well as making AssertFatal and AssertWarn do something. +/// This is usually defined by the build target. +//#define TORQUE_DEBUG + +/// Define me if this is a shipping build; if defined I will instruct Torque +/// to batten down some hatches and generally be more "final game" oriented. +/// Notably this disables a liberal resource manager file searching, and +/// console help strings. +//#define TORQUE_SHIPPING + +/// Define me to enable a variety of network debugging aids. +/// +/// - NetConnection packet logging. +/// - DebugChecksum guards to detect mismatched pack/unpacks. +/// - Detection of invalid destination ghosts. +/// +//#define TORQUE_DEBUG_NET + +/// Define me to enable detailed console logging of net moves. +//#define TORQUE_DEBUG_NET_MOVES + +/// Enable this define to change the default Net::MaxPacketDataSize +/// Do this at your own risk since it has the potential to cause packets +/// to be split up by old routers and Torque does not have a mechanism to +/// stitch split packets back together. Using this define can be very useful +/// in controlled network hardware environments (like a LAN) or for singleplayer +/// games (like BArricade and its large paths) +//#define MAXPACKETSIZE 1500 + +/// Modify me to enable metric gathering code in the renderers. +/// +/// 0 does nothing; higher numbers enable higher levels of metric gathering. +//#define TORQUE_GATHER_METRICS 0 + +/// Define me if you want to enable debug guards in the memory manager. +/// +/// Debug guards are known values placed before and after every block of +/// allocated memory. They are checked periodically by Memory::validate(), +/// and if they are modified (indicating an access to memory the app doesn't +/// "own"), an error is flagged (ie, you'll see a crash in the memory +/// manager's validate code). Using this and a debugger, you can track down +/// memory corruption issues quickly. +//#define TORQUE_DEBUG_GUARD + +/// Define me if you want to enable instanced-static behavior +//#define TORQUE_ENABLE_THREAD_STATICS + +/// Define me if you want to gather static-usage metrics +//#define TORQUE_ENABLE_THREAD_STATIC_METRICS + +/// Define me if you want to enable debug guards on the FrameAllocator. +/// +/// This is similar to the above memory manager guards, but applies only to the +/// fast FrameAllocator temporary pool memory allocations. The guards are only +/// checked when the FrameAllocator frees memory (when it's water mark changes). +/// This is most useful for detecting buffer overruns when using FrameTemp<> . +/// A buffer overrun in the FrameAllocator is unlikely to cause a crash, but may +/// still result in unexpected behavior, if other FrameTemp's are stomped. +//#define FRAMEALLOCATOR_DEBUG_GUARD + +/// This #define is used by the FrameAllocator to set the size of the frame. +/// +/// It was previously set to 3MB but I've increased it to 16MB due to the +/// FrameAllocator being used as temporary storage for bitmaps in the D3D9 +/// texture manager. +#define TORQUE_FRAME_SIZE 16 << 20 + +// Finally, we define some dependent #defines. This enables some subsidiary +// functionality to get automatically turned on in certain configurations. + +#ifdef TORQUE_DEBUG + + #define TORQUE_GATHER_METRICS 0 + #define TORQUE_ENABLE_PROFILE_PATH + #ifndef TORQUE_DEBUG_GUARD + #define TORQUE_DEBUG_GUARD + #endif + #ifndef TORQUE_NET_STATS + #define TORQUE_NET_STATS + #endif + + // Enables the C++ assert macros AssertFatal, AssertWarn, etc. + #define TORQUE_ENABLE_ASSERTS + +#endif + +#ifdef TORQUE_RELEASE + // If it's not DEBUG, it's a RELEASE build, put appropriate things here. +#endif + +#ifdef TORQUE_SHIPPING + + // TORQUE_SHIPPING flags here. + +#else + + // Enable the profiler by default, if we're not doing a shipping build. + #define TORQUE_ENABLE_PROFILER + + // Enable the TorqueScript assert() instruction if not shipping. + #define TORQUE_ENABLE_SCRIPTASSERTS + + // We also enable GFX debug events for use in Pix and other graphics + // debugging tools. + #define TORQUE_ENABLE_GFXDEBUGEVENTS + +#endif + +#ifdef TORQUE_TOOLS +# define TORQUE_INSTANCE_EXCLUSION "TorqueToolsTest" +#else +# define TORQUE_INSTANCE_EXCLUSION "TorqueTest" +#endif + +// Someday, it might make sense to do some pragma magic here so we error +// on inconsistent flags. + +// The Xbox360 has it's own profiling tools, the Torque Profiler should not be used +#ifdef TORQUE_OS_XENON +# ifdef TORQUE_ENABLE_PROFILER +# undef TORQUE_ENABLE_PROFILER +# endif +# +# ifdef TORQUE_ENABLE_PROFILE_PATH +# undef TORQUE_ENABLE_PROFILE_PATH +#endif +#endif + + +#endif // _TORQUECONFIG_H_ + diff --git a/Templates/Empty/thumb.png b/Templates/Empty/thumb.png new file mode 100644 index 000000000..739b71ef0 Binary files /dev/null and b/Templates/Empty/thumb.png differ diff --git a/Templates/Empty/web/source/activex/IEWebGameCtrl.bmp b/Templates/Empty/web/source/activex/IEWebGameCtrl.bmp new file mode 100644 index 000000000..122976492 Binary files /dev/null and b/Templates/Empty/web/source/activex/IEWebGameCtrl.bmp differ diff --git a/Templates/Empty/web/source/activex/IEWebGameCtrl.cpp b/Templates/Empty/web/source/activex/IEWebGameCtrl.cpp new file mode 100644 index 000000000..2229e33bf --- /dev/null +++ b/Templates/Empty/web/source/activex/IEWebGameCtrl.cpp @@ -0,0 +1,482 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "stdafx.h" +#include "IEWebGameCtrl.h" + +#include "../common/webCommon.h" + +// CIEWebGameCtrl (one and only one instance please) +CIEWebGameCtrl* CIEWebGameCtrl::sInstance = NULL; + +// Javascript accessible methods + +// plugin.getVariable("$MyVariable"); - get a Torque 3D console variable +STDMETHODIMP CIEWebGameCtrl::getVariable(BSTR name, BSTR* value) +{ + std::wstring wstr; + std::string sstr; + const char* astr; + + wstr.assign(name); + sstr = WebCommon::WStringToString(wstr); + astr = sstr.c_str(); + + const char* avalue = NULL; + char vinfo[256]; + vinfo[0] = 0; + + // requesting the version information + if (!_stricmp(astr, "$version")) + { + char plugin[4096]; + + GetModuleFileNameA(WebCommon::gPluginModule, plugin, 4096); + DWORD dwHandle = 0; + DWORD dwSize = GetFileVersionInfoSizeA(plugin, &dwHandle); + if (dwSize >= 0) + { + LPBYTE lpInfo = new BYTE[dwSize]; + ZeroMemory(lpInfo, dwSize); + if(GetFileVersionInfoA(plugin, 0, dwSize, lpInfo)) + { + UINT valLen = MAX_PATH; + LPVOID valPtr = NULL; + if(::VerQueryValue(lpInfo, + TEXT("\\"), + &valPtr, + &valLen)) + { + VS_FIXEDFILEINFO* pFinfo = (VS_FIXEDFILEINFO*)valPtr; + + sprintf(vinfo, "%i.%i", (pFinfo->dwProductVersionMS >> 16) & 0xFF, (pFinfo->dwFileVersionMS) & 0xFF); + + } + } + delete[] lpInfo; + } + + if (!vinfo[0]) + strcpy(vinfo, "-1"); + + + avalue = vinfo; + + } + else + avalue = WebCommon::GetVariable(astr); + + sstr = avalue; + wstr = WebCommon::StringToWString(sstr); + + *value = SysAllocString(wstr.c_str()); + + return S_OK; +} + + +// plugin.setVariable("$MyVariable", 42); - set a Torque 3D console variable +STDMETHODIMP CIEWebGameCtrl::setVariable(BSTR name, BSTR value) +{ + std::wstring wstr; + std::string nstr, vstr; + const char* vname; + const char* vvalue; + + wstr.assign(name); + nstr = WebCommon::WStringToString(wstr); + vname = nstr.c_str(); + + wstr.assign(value); + vstr = WebCommon::WStringToString(wstr); + vvalue = vstr.c_str(); + + WebCommon::SetVariable(vname, vvalue); + + return S_OK; +} + + +// plugin.startup(); - called once web page is fully loaded and plugin (including Torque 3D) is initialized +STDMETHODIMP CIEWebGameCtrl::startup() +{ + + mInitialized = true; + std::vector<JavasScriptExport>::iterator i; + for (i = mJavaScriptExports.begin(); i != mJavaScriptExports.end();i++) + { + internalExportFunction(*i); + } + + WebCommon::AddSecureFunctions(); + + return S_OK; +} + +// var result = plugin.callScript("mySecureFunction('one', 'two', 'three');"); - call a TorqueScript function marked as secure in webConfig.h with supplied arguments +// includes function parser +STDMETHODIMP CIEWebGameCtrl::callScript(BSTR code, BSTR* value) +{ + std::wstring wcode; + std::string scode; + wcode.assign(code); + scode = WebCommon::WStringToString(wcode); + const char* sig = scode.c_str(); + + // do not allow large strings which could be used maliciously + if (scode.length() > 255 || !mInitialized) + { + *value = SysAllocString(L""); + return E_INVALIDARG; + } + + // data buffers for laying out data in a Torque 3D console friendly manner + char nameSpace[256]; + char fname[256]; + char argv[256][256]; + char* argvv[256]; + int argc = 0; + unsigned int argBegin = 0; + + memset(nameSpace, 0, 256); + memset(fname, 0, 256); + memset(argv, 0, 256 * 256); + + for (unsigned int i = 0; i < scode.length(); i++) + { + if (sig[i] == ')' || sig[i] == ';') + { + //scan out last arg is any + char dummy[256]; + memset(dummy, 0, 256); + + WebCommon::StringCopy(dummy, &sig[argBegin], i - argBegin); + + if (strlen(dummy)) + { + strcpy_s(argv[argc], dummy); + argvv[argc] = argv[argc]; + argc++; + } + + break; // done + } + + // namespace + if (sig[i]==':') + { + if (nameSpace[0] || fname[0]) + { + *value = SysAllocString(L""); + return E_INVALIDARG; + } + + if (i > 0 && sig[i-1] == ':') + { + if (i - 2 > 0) + WebCommon::StringCopy(nameSpace, sig, i - 1); + } + + continue; + } + + // args begin + if (sig[i] == '(' ) + { + if (fname[0] || i < 1) + { + *value = SysAllocString(L""); + return E_INVALIDARG; + } + + //everything before this is function name, minus nameSpace + if (nameSpace[0]) + { + int nlen = strlen(nameSpace); + WebCommon::StringCopy(fname, &sig[nlen + 2], i - nlen - 2); + } + else + { + WebCommon::StringCopy(fname, sig, i); + } + + WebCommon::StringCopy(argv[0], fname, strlen(fname)+1); + argvv[0] = argv[0]; + argc++; + + argBegin = i + 1; + } + + // args + if (sig[i] == ',' ) + { + if (argBegin >= i || argc == 255) + { + *value = SysAllocString(L""); + return E_INVALIDARG; + } + + WebCommon::StringCopy(argv[argc], &sig[argBegin], i - argBegin); + argvv[argc] = argv[argc]; + + argc++; + argBegin = i + 1; + } + + } + + const char* retVal; + std::string sretVal; + std::wstring wretVal; + + if (fname[0]) + { + // call into the Torque 3D shared library (console system) and get return value + retVal = torque_callsecurefunction(nameSpace, fname, argc, (const char **) argvv); + + sretVal= retVal; + wretVal = WebCommon::StringToWString(sretVal); + + *value = SysAllocString(wretVal.c_str()); + } + else + { + *value = SysAllocString(L""); + return E_INVALIDARG; + } + + return S_OK; +} + +// the sole entry point for Torque 3D console system into our browser plugin (handed over as a function pointer) +static const char * MyStringCallback(void *obj, int argc, const char* argv[]) +{ + static char ret[4096]; + strcpy_s(ret,CIEWebGameCtrl::sInstance->callFunction(argv[0], argc, argv)); + return ret; +} + +// Get the location we're loading the plugin from (http://, file://) including address +// this is used by the domain locking feature to ensure that your plugin is only +// being used from your web site +bool CIEWebGameCtrl::checkDomain() +{ + HRESULT hrResult = S_FALSE; + IMoniker* pMoniker = NULL; + LPOLESTR sDisplayName; + + hrResult = m_spClientSite->GetMoniker(OLEGETMONIKER_TEMPFORUSER, + OLEWHICHMK_CONTAINER, + &pMoniker); + + if(SUCCEEDED(hrResult)) + { + hrResult = pMoniker->GetDisplayName(NULL, + NULL, + &sDisplayName); + pMoniker->Release(); + + std::wstring wstr; + std::string sstr; + + wstr.assign(sDisplayName); + sstr = WebCommon::WStringToString(wstr); + + return WebCommon::CheckDomain(sstr.c_str()); + } + + return false; +} + +// handles TorqueScript -> Javascript calling including return value +const char* CIEWebGameCtrl::callFunction(const char* name, LONG numArguments, const char* argv[]) +{ + + //sanity + if (numArguments > 200) + return ""; + + // A bunch of COM'esque stuff to which ultimately boils down to finding a Javascript function on the page + + HRESULT hr; + + LPOLECONTAINER pContainer; + IHTMLDocument* pHTML = NULL; + CComPtr<IDispatch> pScript; + CComQIPtr<IHTMLWindow2> pWin; + + + if (!m_spClientSite) + return ""; + + hr = m_spClientSite->GetContainer(&pContainer); + + if (FAILED(hr)) + { + return ""; + } + + hr = pContainer->QueryInterface(IID_IHTMLDocument, (void + **)&pHTML); + + if (FAILED(hr)) + { + pContainer->Release(); + return ""; + } + + hr = pHTML->get_Script(&pScript); + + if (FAILED(hr)) + { + pContainer->Release(); + pHTML->Release(); + return ""; + } + + DISPID idMethod = 0; + std::string smethod = name; + std::wstring wmethod = WebCommon::StringToWString(smethod); + OLECHAR FAR* sMethod = (OLECHAR FAR*)wmethod.c_str(); + hr = pScript->GetIDsOfNames(IID_NULL, &sMethod, 1, LOCALE_SYSTEM_DEFAULT,&idMethod); + + if (FAILED(hr)) + { + pContainer->Release(); + pHTML->Release(); + return ""; + } + + // setup arguments and return value variants + + VARIANT pVarRet = {0}; + + VariantInit(&pVarRet); + + if (numArguments <= 1) + { + DISPPARAMS dpNoArgs = {NULL, NULL, 0, 0}; + hr = pScript->Invoke(idMethod, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, + &dpNoArgs, &pVarRet, NULL, NULL); + } + else + { + DISPPARAMS params; + VARIANTARG args[256]; + std::wstring wargs[256]; + + for (LONG i = 0; i < numArguments - 1; i++ ) + { + VariantInit(&args[i]); + // Invoke wants these in reverse order + std::string s = argv[numArguments - i - 1]; + wargs[i] = WebCommon::StringToWString(s); + args[i].vt = VT_BSTR; + args[i].bstrVal = SysAllocString(wargs[i].c_str()); + } + + params.cArgs = numArguments - 1; + params.rgdispidNamedArgs = NULL; + params.cNamedArgs = 0; + params.rgvarg = args; + + // whew, actually call the Javascript + hr = pScript->Invoke(idMethod, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, + ¶ms, &pVarRet, NULL, NULL); + + for (LONG i = 0; i < numArguments - 1; i++ ) + { + SysFreeString(args[i].bstrVal); + } + + } + + if (FAILED(hr)) + { + pContainer->Release(); + pHTML->Release(); + return ""; + } + + VariantChangeType(&pVarRet, &pVarRet, 0, VT_BSTR); + + std::wstring wstr; + std::string sstr; + static char ret[4096]; + + wstr.assign(pVarRet.bstrVal); + sstr = WebCommon::WStringToString(wstr); + strcpy_s(ret, sstr.c_str()); + + pContainer->Release(); + pHTML->Release(); + + return ret; + +} + +// handle the actual export (once we're actually all ready to go) +void CIEWebGameCtrl::internalExportFunction(const JavasScriptExport& jsexport) +{ + torque_exportstringcallback(MyStringCallback,"JS",jsexport.jsCallback.c_str(),"",jsexport.numArguments,jsexport.numArguments); +} + +// plugin.exportFunction("MyJavascriptFunction",3); - export a Javascript function to the Torque 3D console system via its name and argument count +// If we haven't initialized Torque 3D yet, cache it +STDMETHODIMP CIEWebGameCtrl::exportFunction(BSTR callback, LONG numArguments) +{ + JavasScriptExport jsexport; + std::wstring wstr; + + wstr.assign(callback); + jsexport.jsCallback = WebCommon::WStringToString(wstr); + jsexport.numArguments = numArguments; + + if (!mInitialized) + { + //queue it up + mJavaScriptExports.push_back(jsexport); + } + else + { + internalExportFunction(jsexport); + } + + return S_OK; +} + + +// Our web deployment is installer based, no code signing necessary +STDMETHODIMP CIEWebGameCtrl::GetInterfaceSafetyOptions(REFIID riid, + DWORD *pdwSupportedOptions,DWORD *pdwEnabledOptions) +{ + return S_OK; +} + +STDMETHODIMP CIEWebGameCtrl::SetInterfaceSafetyOptions(REFIID riid, + DWORD dwOptionSetMask,DWORD dwEnabledOptions) +{ + return S_OK; +} + + + diff --git a/Templates/Empty/web/source/activex/IEWebGameCtrl.h b/Templates/Empty/web/source/activex/IEWebGameCtrl.h new file mode 100644 index 000000000..801f6743c --- /dev/null +++ b/Templates/Empty/web/source/activex/IEWebGameCtrl.h @@ -0,0 +1,177 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Torque 3D web deployment for Internet Explorer (ActiveX) + +#pragma once +#include "resource.h" // main symbols +#include <atlctl.h> +#include "IEWebGamePlugin_i.h" +#include "IEWebGameWindow.h" + +#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA) +#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms." +#endif + +// The heavy lifting is done by our game control (which inherits from WebGameWindow) + +// CIEWebGameCtrl +class ATL_NO_VTABLE CIEWebGameCtrl : + public CComObjectRootEx<CComSingleThreadModel>, + public CStockPropImpl<CIEWebGameCtrl, IIEWebGameCtrl>, + public IPersistStreamInitImpl<CIEWebGameCtrl>, + public IOleControlImpl<CIEWebGameCtrl>, + public IOleObjectImpl<CIEWebGameCtrl>, + public IOleInPlaceActiveObjectImpl<CIEWebGameCtrl>, + public IViewObjectExImpl<CIEWebGameCtrl>, + public IOleInPlaceObjectWindowlessImpl<CIEWebGameCtrl>, + public IObjectSafetyImpl<CIEWebGameCtrl, INTERFACESAFE_FOR_UNTRUSTED_CALLER>, + public CComCoClass<CIEWebGameCtrl, &CLSID_IEWebGameCtrl>, + public CComControl<CIEWebGameCtrl, WebGameWindow> +{ +public: + + + + DECLARE_OLEMISC_STATUS(OLEMISC_RECOMPOSEONRESIZE | + OLEMISC_CANTLINKINSIDE | + OLEMISC_INSIDEOUT | + OLEMISC_ACTIVATEWHENVISIBLE | + OLEMISC_SETCLIENTSITEFIRST + ) + + DECLARE_REGISTRY_RESOURCEID(IDR_IEWEBGAMECTRL) + + + BEGIN_COM_MAP(CIEWebGameCtrl) + COM_INTERFACE_ENTRY(IIEWebGameCtrl) + COM_INTERFACE_ENTRY(IDispatch) + COM_INTERFACE_ENTRY(IViewObjectEx) + COM_INTERFACE_ENTRY(IViewObject2) + COM_INTERFACE_ENTRY(IViewObject) + COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless) + COM_INTERFACE_ENTRY(IOleInPlaceObject) + COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless) + COM_INTERFACE_ENTRY(IOleInPlaceActiveObject) + COM_INTERFACE_ENTRY(IOleControl) + COM_INTERFACE_ENTRY(IOleObject) + COM_INTERFACE_ENTRY(IPersistStreamInit) + COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit) + COM_INTERFACE_ENTRY_IID(IID_IObjectSafety, IObjectSafety) + + END_COM_MAP() + + BEGIN_PROP_MAP(CIEWebGameCtrl) + PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4) + PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4) + // Example entries + // PROP_ENTRY_TYPE("Property Name", dispid, clsid, vtType) + // PROP_PAGE(CLSID_StockColorPage) + END_PROP_MAP() + + + BEGIN_MSG_MAP(WebGameWindow) + CHAIN_MSG_MAP(WebGameWindow) + DEFAULT_REFLECTION_HANDLER() + END_MSG_MAP() + + // Handler prototypes: + // LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + // LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); + // LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled); + + // IViewObjectEx + DECLARE_VIEW_STATUS(0) + + // IIEWebGameCtrl +public: + + static CIEWebGameCtrl* sInstance; + + CIEWebGameCtrl() + { + m_bWindowOnly = TRUE; + sInstance = this; + mInitialized = false; + } + + DECLARE_PROTECT_FINAL_CONSTRUCT() + + HRESULT FinalConstruct() + { + return S_OK; + } + + void FinalRelease() + { + } + + // the javascript accessible methods which can be called our on plugin object + + // plugin.getVariable("$MyVariable"); - get a Torque 3D console variable + STDMETHOD(getVariable)(BSTR name, BSTR* value); + + // plugin.setVariable("$MyVariable", 42); - set a Torque 3D console variable + STDMETHOD(setVariable)(BSTR name, BSTR value); + + // var result = plugin.callScript("mySecureFunction('one', 'two', 'three');"); - call a TorqueScript function marked as secure in webConfig.h with supplied arguments + STDMETHOD(callScript)(BSTR code, BSTR* retValue); + + // plugin.exportFunction("MyJavascriptFunction",3); - export a Javascript function to the Torque 3D console system via its name and argument count + STDMETHOD(exportFunction)(BSTR name, LONG numArguments); + + // plugin.startup(); - called once web page is fully loaded and plugin (including Torque 3D) is initialized + STDMETHOD(startup)(); + + // TorqueScript -> Javascript call handling + const char* callFunction(const char* name, LONG numArguments, const char* argv[]); + + // our plugin requires no signing as it is installer based + STDMETHOD(GetInterfaceSafetyOptions)(REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions); + STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions); + + +protected: + + // these can be added on the page before we're initialized, so we cache them at startup + typedef struct JavasScriptExport + { + std::string jsCallback; //javascript function name + UINT numArguments; //the number of arguments it takes + }; + + std::vector<JavasScriptExport> mJavaScriptExports; + + // actually handle the export (once Torque 3D is fully initialized) + void internalExportFunction(const JavasScriptExport& jsexport); + + + BOOL mInitialized; + + // checks a given domain against the allowed domains in webConfig.h + bool checkDomain(); + + +}; + + +OBJECT_ENTRY_AUTO(__uuidof(IEWebGameCtrl), CIEWebGameCtrl) diff --git a/Templates/Empty/web/source/activex/IEWebGameCtrl.rgs b/Templates/Empty/web/source/activex/IEWebGameCtrl.rgs new file mode 100644 index 000000000..b33ef937b --- /dev/null +++ b/Templates/Empty/web/source/activex/IEWebGameCtrl.rgs @@ -0,0 +1,34 @@ +HKCR +{ + IEEmptyPlugin.IEWebGameCtrl.1 = s 'IEWebGameCtrl Class' + { + CLSID = s '{D62D1B36-253D-4218-B033-5ACE0B42B8BF}' + } + IEEmptyPlugin.IEWebGameCtrl = s 'IEWebGameCtrl Class' + { + CLSID = s '{D62D1B36-253D-4218-B033-5ACE0B42B8BF}' + CurVer = s 'IEEmptyPlugin.IEWebGameCtrl.1' + } + NoRemove CLSID + { + ForceRemove {D62D1B36-253D-4218-B033-5ACE0B42B8BF} = s 'IEWebGameCtrl Class' + { + ProgID = s 'IEEmptyPlugin.IEWebGameCtrl.1' + VersionIndependentProgID = s 'IEEmptyPlugin.IEWebGameCtrl' + ForceRemove 'Programmable' + InprocServer32 = s '%MODULE%' + { + val ThreadingModel = s 'Apartment' + } + val AppID = s '%APPID%' + ForceRemove 'Control' + ForceRemove 'ToolboxBitmap32' = s '%MODULE%, 102' + 'MiscStatus' = s '0' + { + '1' = s '%OLEMISC%' + } + 'TypeLib' = s '{5240D24D-FBCE-4AF2-99FC-4C7AD4318E91}' + 'Version' = s '1.0' + } + } +} diff --git a/Templates/Empty/web/source/activex/IEWebGamePlugin.cpp b/Templates/Empty/web/source/activex/IEWebGamePlugin.cpp new file mode 100644 index 000000000..c2f03cda9 --- /dev/null +++ b/Templates/Empty/web/source/activex/IEWebGamePlugin.cpp @@ -0,0 +1,91 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "stdafx.h" +#include "resource.h" +#include "IEWebGamePlugin_i.h" +#include "dllmain.h" + +// Used to determine whether the DLL can be unloaded by OLE +STDAPI DllCanUnloadNow(void) +{ + return _AtlModule.DllCanUnloadNow(); +} + + +// Returns a class factory to create an object of the requested type +STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) +{ + return _AtlModule.DllGetClassObject(rclsid, riid, ppv); +} + + +// DllRegisterServer - Adds entries to the system registry +STDAPI DllRegisterServer(void) +{ + // registers object, typelib and all interfaces in typelib + HRESULT hr = _AtlModule.DllRegisterServer(); + return hr; +} + + +// DllUnregisterServer - Removes entries from the system registry +STDAPI DllUnregisterServer(void) +{ + HRESULT hr = _AtlModule.DllUnregisterServer(); + return hr; +} + +// DllInstall - Adds/Removes entries to the system registry per user +// per machine. +STDAPI DllInstall(BOOL bInstall, LPCWSTR pszCmdLine) +{ + HRESULT hr = E_FAIL; + static const wchar_t szUserSwitch[] = _T("user"); + + if (pszCmdLine != NULL) + { + if (_wcsnicmp(pszCmdLine, szUserSwitch, _countof(szUserSwitch)) == 0) + { +#if (_MSC_VER >= 1500) //vs2008 or higher + AtlSetPerUserRegistration(true); +#endif + } + } + + if (bInstall) + { + hr = DllRegisterServer(); + if (FAILED(hr)) + { + DllUnregisterServer(); + } + } + else + { + hr = DllUnregisterServer(); + } + + return hr; +} + + diff --git a/Templates/Empty/web/source/activex/IEWebGamePlugin.def b/Templates/Empty/web/source/activex/IEWebGamePlugin.def new file mode 100644 index 000000000..a411e8436 --- /dev/null +++ b/Templates/Empty/web/source/activex/IEWebGamePlugin.def @@ -0,0 +1,8 @@ +; IEWebGamePlugin.def : Declares the module parameters. + +EXPORTS + DllCanUnloadNow PRIVATE + DllGetClassObject PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE + DllInstall PRIVATE diff --git a/Templates/Empty/web/source/activex/IEWebGamePlugin.idl b/Templates/Empty/web/source/activex/IEWebGamePlugin.idl new file mode 100644 index 000000000..17ab7087d --- /dev/null +++ b/Templates/Empty/web/source/activex/IEWebGamePlugin.idl @@ -0,0 +1,46 @@ +// IEWebGamePlugin.idl : IDL source for IEWebGamePlugin +// + +// This file will be processed by the MIDL tool to +// produce the type library (IEWebGamePlugin.tlb) and marshalling code. + +#include "olectl.h" +import "oaidl.idl"; +import "ocidl.idl"; + +[ + object, + uuid(5240D24D-FBCE-4AF2-99FC-4C7AD4318E91), + dual, + nonextensible, + helpstring("IIEWebGameCtrl Interface"), + pointer_default(unique) +] +interface IIEWebGameCtrl : IDispatch{ + [propget, bindable, requestedit, id(DISPID_HWND)] + HRESULT HWND([out, retval]LONG_PTR* pHWND); + [id(1), helpstring("method getVariable")] HRESULT getVariable([in] BSTR name, [out, retval] BSTR* value); + [id(2), helpstring("method setVariable")] HRESULT setVariable([in] BSTR name, [in] BSTR value); + [id(3), helpstring("method export")] HRESULT exportFunction([in] BSTR callback, [in] LONG numArguments); + [id(4), helpstring("method callScript")] HRESULT callScript([in] BSTR code, [out, retval] BSTR* retValue); + [id(5), helpstring("method startup")] HRESULT startup(); +}; + +[ + uuid(FC143328-E29C-4BC4-8C83-618FEB562532), + version(1.0), + helpstring("IEEmptyPlugin 1.0 Type Library") +] +library IEEmptyPluginLib +{ + importlib("stdole2.tlb"); + [ + uuid(D62D1B36-253D-4218-B033-5ACE0B42B8BF), + control, + helpstring("IEWebGameCtrl Class") + ] + coclass IEWebGameCtrl + { + [default] interface IIEWebGameCtrl; + }; +}; diff --git a/Templates/Empty/web/source/activex/IEWebGamePlugin.rc b/Templates/Empty/web/source/activex/IEWebGamePlugin.rc new file mode 100644 index 000000000..493d95046 --- /dev/null +++ b/Templates/Empty/web/source/activex/IEWebGamePlugin.rc @@ -0,0 +1,135 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#ifndef APSTUDIO_INVOKED +#include "targetver.h" +#endif +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#ifndef APSTUDIO_INVOKED\r\n" + "#include ""targetver.h""\r\n" + "#endif\r\n" + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "1 TYPELIB ""IEWebGamePlugin.tlb""\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "PluginType", "ActiveX" + VALUE "CompanyName", "My Game Company" + VALUE "FileDescription", "ActiveX Web Game Plugin" + VALUE "FileVersion", "1.0.0.1" + VALUE "LegalCopyright", "(c) My Game Company. All rights reserved." + VALUE "InternalName", "IE Empty Plugin.dll" + VALUE "OriginalFilename", "IE Empty Plugin.dll" + VALUE "ProductName", "My Web Game" + VALUE "ProductVersion", "1.0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// REGISTRY +// + +IDR_IEWEBGAMEPLUGIN REGISTRY "IEWebGamePlugin.rgs" +IDR_IEWEBGAMECTRL REGISTRY "IEWebGameCtrl.rgs" + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_IEWEBGAMECTRL BITMAP "IEWebGameCtrl.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_PROJNAME "IEEmptyPlugin" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +1 TYPELIB "IEWebGamePlugin.tlb" + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Templates/Empty/web/source/activex/IEWebGamePlugin.rgs b/Templates/Empty/web/source/activex/IEWebGamePlugin.rgs new file mode 100644 index 000000000..085569d71 --- /dev/null +++ b/Templates/Empty/web/source/activex/IEWebGamePlugin.rgs @@ -0,0 +1,11 @@ +HKCR +{ + NoRemove AppID + { + '%APPID%' = s 'IEEmptyPlugin' + 'IEEmptyPlugin.DLL' + { + val AppID = s '%APPID%' + } + } +} diff --git a/Templates/Empty/web/source/activex/IEWebGameWindow.cpp b/Templates/Empty/web/source/activex/IEWebGameWindow.cpp new file mode 100644 index 000000000..7096a1bbc --- /dev/null +++ b/Templates/Empty/web/source/activex/IEWebGameWindow.cpp @@ -0,0 +1,182 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "StdAfx.h" +#include <shlobj.h> +#include "IEWebGameWindow.h" +#include "../common/webCommon.h" + + +// We hook the keyboard at application level so we TAB, Backspace, other accelerator combos +// are captured and don't cause us grief +static HHOOK hHook = NULL; + +// Hook procedure for WH_GETMESSAGE hook type. +LRESULT CALLBACK GetMessageProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + // If this is a keystrokes message, translate it in controls' + LPMSG lpMsg = (LPMSG) lParam; + if( (nCode >= 0) && + PM_REMOVE == wParam && + (lpMsg->message >= WM_KEYFIRST && lpMsg->message <= WM_KEYLAST) ) + { + if (torque_directmessage) + { + // call directly into the Torque 3D message queue, bypassing the windows event queue + // as we're hooking into the application level processing, this would cause a hang + torque_directmessage(lpMsg->message, lpMsg->wParam, lpMsg->lParam); + + // The value returned from this hookproc is ignored, and it cannot + // be used to tell Windows the message has been handled. To avoid + // further processing, convert the message to WM_NULL before + // returning. + lpMsg->message = WM_NULL; + lpMsg->lParam = 0L; + lpMsg->wParam = 0; + } + } + + // Passes the hook information to the next hook procedure in + // the current hook chain. + return ::CallNextHookEx(hHook, nCode, wParam, lParam); +} + + + + +WebGameWindow::WebGameWindow(void) +{ + mTimer = false; + mInitialized = false; +} + +WebGameWindow::~WebGameWindow(void) +{ + //handling threads in event callbacks (onDestroy for instance) seems to cause loads of problems (deadlocks, etc) + if (mInitialized) + WebCommon::ShutdownTorque3D(); +} + +// we use a timer to update the Torque 3D game loop (tick) and handle rendering +VOID CALLBACK MyTimerProc( + HWND hwnd, // handle to window for timer messages + UINT message, // WM_TIMER message + UINT idTimer, // timer identifier + DWORD dwTime) // current system time +{ + static bool reentrant = false; + + if (!reentrant) + { + reentrant = true; + torque_enginetick(); + reentrant = false; + } +} + +LRESULT +WebGameWindow::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + + bHandled = TRUE; + + // check that the domain we're loading the plugin from is allowed + if (!checkDomain()) + { + return -1; + } + + // load up the Torque 3D shared library and initialize it + if (!WebCommon::InitTorque3D(this->m_hWnd)) + { + return -1; + } + + mTimer = true; + mInitialized = true; + + // fire up timer for ticking Torque 3D update + SetTimer( 1, // timer identifier + 1, // 1 millisecond + (TIMERPROC) MyTimerProc); // timer callback + + hHook = ::SetWindowsHookEx( + WH_GETMESSAGE, + GetMessageProc, + WebCommon::gPluginModule, + GetCurrentThreadId()); + + return 0; +} + +//------------------------------------------------------------------------------ +/** +*/ +LRESULT +WebGameWindow::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + // let the default handler run + bHandled = FALSE; + + // kill update timer + if (mTimer) + KillTimer( 1); + mTimer = false; + + if (hHook) + ::UnhookWindowsHookEx (hHook); + + hHook = NULL; + + return 0; +} + +//------------------------------------------------------------------------------ +/** +*/ + +LRESULT +WebGameWindow::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + // let the default handler run + bHandled = FALSE; + + // resize the Torque 3D child window depending on our browser's parent window + if (mInitialized && torque_resizewindow) + { + int width = (int) LOWORD( lParam ); + int height = (int) HIWORD( lParam ); + torque_resizewindow(width,height); + } + return 0; +} + + +//------------------------------------------------------------------------------ +/** +*/ +LRESULT +WebGameWindow::OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + return MA_ACTIVATE; +} + diff --git a/Templates/Empty/web/source/activex/IEWebGameWindow.h b/Templates/Empty/web/source/activex/IEWebGameWindow.h new file mode 100644 index 000000000..6c30ee68b --- /dev/null +++ b/Templates/Empty/web/source/activex/IEWebGameWindow.h @@ -0,0 +1,65 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#pragma once + +#include "stdafx.h" +#include <vector> +#include <string> + +// "Platform" window specifics to keep IE plugin consistent with Safari/Firefox/Chrome + +class WebGameWindow : public CWindowImpl<WebGameWindow> +{ +public: + WebGameWindow(); + virtual ~WebGameWindow(); + + DECLARE_WND_CLASS(_T("WebGameCtrl:WebGameWindow")) + + BEGIN_MSG_MAP(WebGameWindow) + MESSAGE_HANDLER(WM_CREATE, OnCreate) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) + MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate); + MESSAGE_HANDLER(WM_SIZE, OnSize); + END_MSG_MAP() + +public: + + // message handlers (all window based) + LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + +protected: + + // // checks a given domain against the allowed domains in webConfig.h (defined in IEWebGamePlugin) + virtual bool checkDomain() = 0; + +private: + + bool mTimer; + bool mInitialized; + +}; + diff --git a/Templates/Empty/web/source/activex/dllmain.cpp b/Templates/Empty/web/source/activex/dllmain.cpp new file mode 100644 index 000000000..fb5281900 --- /dev/null +++ b/Templates/Empty/web/source/activex/dllmain.cpp @@ -0,0 +1,38 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// dllmain.cpp : Implementation of DllMain. + +#include "stdafx.h" +#include "resource.h" +#include "IEWebGamePlugin_i.h" +#include "dllmain.h" +#include "../common/webCommon.h" + +CIEWebGamePluginModule _AtlModule; + +// DLL Entry Point +extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) +{ + WebCommon::gPluginModule = (HMODULE) hInstance; + return _AtlModule.DllMain(dwReason, lpReserved); +} diff --git a/Templates/Empty/web/source/activex/dllmain.h b/Templates/Empty/web/source/activex/dllmain.h new file mode 100644 index 000000000..7e929ae25 --- /dev/null +++ b/Templates/Empty/web/source/activex/dllmain.h @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// dllmain.h : Declaration of module class. + +class CIEWebGamePluginModule : public CAtlDllModuleT< CIEWebGamePluginModule > +{ +public : + DECLARE_LIBID(LIBID_IEEmptyPluginLib) + DECLARE_REGISTRY_APPID_RESOURCEID(IDR_IEWEBGAMEPLUGIN, "{AB7615A3-A918-488B-B128-96DD62D0AE36}") +}; + +extern class CIEWebGamePluginModule _AtlModule; diff --git a/Templates/Empty/web/source/activex/resource.h b/Templates/Empty/web/source/activex/resource.h new file mode 100644 index 000000000..6fb015195 --- /dev/null +++ b/Templates/Empty/web/source/activex/resource.h @@ -0,0 +1,19 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by IEWebGamePlugin.rc +// +#define IDS_PROJNAME 100 +#define IDR_IEWEBGAMEPLUGIN 101 +#define IDB_IEWEBGAMECTRL 102 +#define IDR_IEWEBGAMECTRL 103 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 201 +#define _APS_NEXT_COMMAND_VALUE 32768 +#define _APS_NEXT_CONTROL_VALUE 201 +#define _APS_NEXT_SYMED_VALUE 104 +#endif +#endif diff --git a/Templates/Empty/web/source/activex/stdafx.cpp b/Templates/Empty/web/source/activex/stdafx.cpp new file mode 100644 index 000000000..bea35e638 --- /dev/null +++ b/Templates/Empty/web/source/activex/stdafx.cpp @@ -0,0 +1,27 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// stdafx.cpp : source file that includes just the standard includes +// IEWebGamePlugin.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" diff --git a/Templates/Empty/web/source/activex/stdafx.h b/Templates/Empty/web/source/activex/stdafx.h new file mode 100644 index 000000000..fc7d0946a --- /dev/null +++ b/Templates/Empty/web/source/activex/stdafx.h @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, +// but are changed infrequently + +#pragma once + +#ifndef STRICT +#define STRICT +#endif + +#include "targetver.h" + +#define _ATL_APARTMENT_THREADED +#define _ATL_NO_AUTOMATIC_NAMESPACE + +#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit + +#include "resource.h" +#include <atlbase.h> +#include <atlcom.h> +#include <atlctl.h> + +using namespace ATL; \ No newline at end of file diff --git a/Templates/Empty/web/source/activex/targetver.h b/Templates/Empty/web/source/activex/targetver.h new file mode 100644 index 000000000..8ff0a6f4d --- /dev/null +++ b/Templates/Empty/web/source/activex/targetver.h @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#pragma once + +// The following macros define the minimum required platform. The minimum required platform +// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run +// your application. The macros work by enabling all features available on platform versions up to and +// including the version specified. + +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef WINVER // Specifies that the minimum required platform is Windows Vista. +#define WINVER 0x0600 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista. +#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINDOWS // Specifies that the minimum required platform is Windows 98. +#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. +#endif + +#ifndef _WIN32_IE // Specifies that the minimum required platform is Internet Explorer 7.0. +#define _WIN32_IE 0x0700 // Change this to the appropriate value to target other versions of IE. +#endif + diff --git a/Templates/Empty/web/source/common/webCommon.cpp b/Templates/Empty/web/source/common/webCommon.cpp new file mode 100644 index 000000000..d2b65556d --- /dev/null +++ b/Templates/Empty/web/source/common/webCommon.cpp @@ -0,0 +1,727 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include "webConfig.h" +#include "webCommon.h" + +#include <string> +#include <vector> + +// Platform specific shared library handling + +#ifdef WIN32 + +#pragma warning( disable : 4996) + +#define TORQUE_OPEN LoadLibraryA +#define TORQUE_FUNCTION GetProcAddress +#define TORQUE_CLOSE FreeLibrary + +#define strncasecmp strnicmp +#define strcasecmp stricmp + +#else // Mac + +#define TORQUE_OPEN(path) dlopen(path, RTLD_LAZY | RTLD_LOCAL) +#define TORQUE_FUNCTION dlsym +#define TORQUE_CLOSE dlclose + +#endif + +// C Interface exported from the Torque 3D DLL (or Bundle on Mac) + +extern "C" +{ + // initialize Torque 3D including argument handling + bool (*torque_engineinit)(int argc, const char **argv) = NULL; + + // tick Torque 3D's main loop + int (*torque_enginetick)() = NULL; + + // set Torque 3D into web deployment mode (disable fullscreen exlusive mode, etc) + int (*torque_setwebdeployment)() = NULL; + + // shutdown the engine + bool (*torque_engineshutdown)() = NULL; + + // signal an engine shutdown (as with the quit(); console command) + void (*torque_enginesignalshutdown)() = NULL; + + // reset the engine, unloading any current level and returning to the main menu + void (*torque_reset)() = NULL; + + // Evaluate arbitrary TorqueScript (ONLY CALL torque_evaluate FROM TRUSTED CODE!!!) + const char* (*torque_evaluate)(const char* code) = NULL; + + // Get a console variable + const char* (*torque_getvariable)(const char* name) = NULL; + // Set a console variable + void (*torque_setvariable)(const char* name, const char* value) = NULL; + + // Export a function to the Torque 3D console system which matches the StringCallback function prototype + // specify the nameSpace, functionName, usage, min and max arguments + void (*torque_exportstringcallback)(StringCallback cb, const char *nameSpace, const char *funcName, const char* usage, int minArgs, int maxArgs) = NULL; + + // Set a TorqueScript console function as secure and available for JavaScript via the callScript plugin method + void (*torque_addsecurefunction)(const char* nameSpace, const char* fname) = NULL; + // Call a TorqueScript console function that has been marked as secure + const char* (*torque_callsecurefunction)(const char* nameSpace, const char* name, int argc, const char ** argv) = NULL; + + // resize the Torque 3D child window to the specified width and height + void (*torque_resizewindow)(int width, int height) = NULL; + +#ifndef WIN32 + // On Mac, handle the parent safari window + void (*torque_setsafariwindow)(NSWindow* window, int32 x, int32 y, int32 width, int32 height) = NULL; + // On Mac, sets the executable path + void (*torque_setexecutablepath)(const char *path) = NULL; +#else + // retrieve the render windows hwnd + void* (*torque_gethwnd)() = NULL; + + // directly add a message to the Torque 3D event queue, bypassing the Windows event queue + // this is useful in the case of the IE plugin, where we are hooking into an application + // level message, and posting to the windows queue would cause a hang + void (*torque_directmessage)(unsigned int message, unsigned int wparam, unsigned int lparam) = NULL; +#endif + +}; + +namespace WebCommon +{ + + std::string gPluginMIMEType; + +#ifdef WIN32 + + HMODULE gTorque3DModule = NULL; + HMODULE gPluginModule = 0; + + // bring up a platform specific message box (used for error reporting) + void MessageBox(void* parentWindow, const char* msg, const char* caption ) + { + ::MessageBoxA( (HWND) parentWindow, msg, caption, MB_OK|MB_ICONWARNING); + } + + // retrieve the game directory using the filename (which includes the full path) of the plugin DLL + const char* GetGameDirectory() + { + static char dir[4096]; + + GetModuleFileNameA(gPluginModule, dir, 4096); + + int i = strlen(dir) - 1; + while (i>=0) + { + if (dir[i] == '\\' || dir[i] == '/') + { + dir[i] = 0; + break; + } + + i--; + } + + return dir; + + } + + // retrieve the name of our game DLL (includes Torque 3D engine) based on naming convention + const char* GetGameLibrary() + { + char dir[4096]; + static char lib[4096]; + + lib[0] = 0; + + GetModuleFileNameA(gPluginModule, dir, 4096); + + int i = strlen(dir) - 1; + while (i>=0) + { + if (dir[i] == '\\' || dir[i] == '/') + { + // copy, minus the "NP " or "IE " of plugin name +#ifdef _DEBUG + sprintf(lib, "%s_DEBUG.dll", &dir[i+4]); +#else + sprintf(lib, "%s.dll", &dir[i+4]); +#endif + return lib; + } + + // strip off end + if (!strncmp(&dir[i], " Plugin", 7)) + dir[i] = 0; + + i--; + } + + return lib; + } + +#else + + void* gTorque3DModule = NULL; + NSBundle* gPluginBundle = NULL; + + // bring up a platform specific message box (used for error reporting) + void MessageBox(void* parentWindow, const char* msg, const char* caption ) + { + + // convert title and message to NSStrings + NSString *nsTitle = [NSString stringWithUTF8String:caption]; + NSString *nsMessage = [NSString stringWithUTF8String:msg]; + + + NSAlert *alert = [NSAlert alertWithMessageText:nsTitle +defaultButton:@"OK" +alternateButton:nil +otherButton:nil +informativeTextWithFormat:nsMessage]; + [alert runModal]; + } + + NSBundle* GetPluginBundle() + { + if (gPluginBundle) + return gPluginBundle; + + NSDictionary *mimeTypes; + NSString *mime; + NSEnumerator *f; + + NSArray *bundles = [NSBundle allBundles]; + for (int i = 0; i < [bundles count]; i++) { + NSBundle *b = [bundles objectAtIndex:i]; + + mimeTypes=[b objectForInfoDictionaryKey:@"WebPluginMIMETypes"]; + + if (!mimeTypes) + continue; + + f=[mimeTypes keyEnumerator]; + + while((mime=[f nextObject])) + { + if (gPluginMIMEType == std::string([mime UTF8String])) + { + gPluginBundle = b; + break; + } + } + } + + return gPluginBundle; + + } + + // retrieve the game's install folder based on entries from our plugin's Info.plist + const char* GetGameDirectory() + { + static char gamePath[2048] = {'\0'}; + + if (gamePath[0]) + return gamePath; + + NSBundle* pluginBundle = GetPluginBundle(); + + if (!pluginBundle) + return NULL; + + NSString *gameInstallPathKey = [NSString stringWithUTF8String:"GameInstallPath"]; + NSString *gameInstallPath = [pluginBundle objectForInfoDictionaryKey: gameInstallPathKey]; + + if (!gameInstallPath) + return NULL; + + strcpy(gamePath, [gameInstallPath UTF8String]); + + if (!gamePath[0]) + return NULL; + + return gamePath; + } + + // retrieve the game bundle (including Torque 3D engine) from the plugin Info.plist + const char* GetGameLibrary() + { + static char libPath[2048] = {'\0'}; + + if (libPath[0]) + return libPath; + + const char* gamePath = GetGameDirectory(); + + if (!gamePath) + return NULL; + + NSBundle* pluginBundle = GetPluginBundle(); + + if (!pluginBundle) + return NULL; + + // NSString* bundleIdentifier = [pluginBundle bundleIdentifier]; + + NSString *gameNameKey = [NSString stringWithUTF8String:"GameName"]; + NSString *gameName = [pluginBundle objectForInfoDictionaryKey: gameNameKey]; + + if (!gameName) + return NULL; + + const char* cgameName = [gameName UTF8String]; + + if (!cgameName[0]) + return NULL; + +#ifdef DEBUG + sprintf(libPath, "%s%s_DEBUG.app/Contents/Frameworks/%s Bundle.bundle/Contents/MacOS/%s Bundle", gamePath, cgameName, cgameName, cgameName); +#else + sprintf(libPath, "%s%s.app/Contents/Frameworks/%s Bundle.bundle/Contents/MacOS/%s Bundle", gamePath, cgameName, cgameName, cgameName); +#endif + + return libPath; + } + +#endif + + bool ChangeToGameDirectory() + { + const char* gameDir = GetGameDirectory(); + + if (!gameDir) + return false; + +#ifdef WIN32 + return SetCurrentDirectoryA(gameDir); +#else + return (chdir(gameDir) == 0); +#endif + + } + + // loads the Torque 3D shared library, sets web deployment mode, retrieves engine "C" interface + bool InitTorque3D(void* platformWindow, int clipLeft, int clipTop, int clipRight, int clipBottom) + { + const char* gameDir = GetGameDirectory(); + const char* gameLib = GetGameLibrary(); + + if (gTorque3DModule) + { + WebCommon::MessageBox( 0, "This plugin allows only one instance", "Error"); + return false; + } + + if (!gameDir || !gameLib) + { + WebCommon::MessageBox( 0, "Unable to get game plugin information", "Error"); + return false; + } + + if (!ChangeToGameDirectory()) + return false; + + std::string gameLibStr = gameLib; +#ifdef WIN32 + // We want to use an absolute path to the game library + gameLibStr = gameDir; + WebCommon::ConvertToWindowsPathSep(gameLibStr); + gameLibStr += "\\"; + gameLibStr += gameLib; +#endif + + gTorque3DModule = TORQUE_OPEN(gameLibStr.c_str()); + + if (!gTorque3DModule) + { + char error[4096]; +#ifdef WIN32 + sprintf(error, "Could not load game library: %s/%s. Please make sure you have the latest DirectX installed.", gameDir, gameLib); +#else + sprintf(error, "Could not load game library: %s/%s. ", gameDir, gameLib); +#endif + WebCommon::MessageBox( 0, error, "Error"); + return false; + } + + // snag all the exported functions of the "C" interface + + torque_engineinit = (bool (*)(int argc, const char **argv))TORQUE_FUNCTION(gTorque3DModule, "torque_engineinit"); + torque_enginetick = (int (*)())TORQUE_FUNCTION(gTorque3DModule, "torque_enginetick"); + torque_setwebdeployment = (int (*)())TORQUE_FUNCTION(gTorque3DModule, "torque_setwebdeployment"); + torque_engineshutdown = (bool (*)())TORQUE_FUNCTION(gTorque3DModule, "torque_engineshutdown"); + torque_enginesignalshutdown = (void (*)())TORQUE_FUNCTION(gTorque3DModule, "torque_enginesignalshutdown"); + torque_reset = (void (*)())TORQUE_FUNCTION(gTorque3DModule, "torque_reset"); + torque_evaluate = (const char* (*)(const char* code))TORQUE_FUNCTION(gTorque3DModule, "torque_evaluate"); + + torque_getvariable = (const char* (*)(const char* name))TORQUE_FUNCTION(gTorque3DModule, "torque_getvariable"); + torque_setvariable = (void (*)(const char* name, const char* value))TORQUE_FUNCTION(gTorque3DModule, "torque_setvariable"); + torque_exportstringcallback = (void (*)(StringCallback cb, const char *nameSpace, const char *funcName, const char* usage, int minArgs, int maxArgs))TORQUE_FUNCTION(gTorque3DModule, "torque_exportstringcallback"); + + torque_addsecurefunction = (void (*)(const char* nameSpace, const char* name))TORQUE_FUNCTION(gTorque3DModule, "torque_addsecurefunction"); + torque_callsecurefunction = (const char* (*)(const char* nameSpace, const char* name, int argc, const char ** argv))TORQUE_FUNCTION(gTorque3DModule, "torque_callsecurefunction"); + + torque_resizewindow = (void (*)(int width, int height))TORQUE_FUNCTION(gTorque3DModule, "torque_resizewindow"); + + // check that we got them all + + if (!torque_engineinit || + !torque_enginetick || + !torque_setwebdeployment || + !torque_engineshutdown || + !torque_enginesignalshutdown || + !torque_reset || + !torque_evaluate || + !torque_getvariable || + !torque_setvariable || + !torque_exportstringcallback || + !torque_addsecurefunction || + !torque_callsecurefunction || + !torque_resizewindow ) + { + WebCommon::MessageBox( platformWindow, "The plugin could not be initialized (missing function exports)", "Error"); + TORQUE_CLOSE(gTorque3DModule); + gTorque3DModule = NULL; + return false; + } + +#ifndef WIN32 + torque_setexecutablepath = (void (*)(const char *path)) dlsym(gTorque3DModule, "torque_setexecutablepath"); + torque_setsafariwindow = (void (*)(NSWindow* nswnd, int32, int32, int32, int32)) dlsym(gTorque3DModule, "torque_setsafariwindow"); + + if (!torque_setexecutablepath || !torque_setsafariwindow) + { + WebCommon::MessageBox( platformWindow, "The plugin could not be initialized (missing function exports)", "Error"); + TORQUE_CLOSE(gTorque3DModule); + gTorque3DModule = NULL; + return false; + } +#else + torque_gethwnd = (void* (*)())TORQUE_FUNCTION(gTorque3DModule, "torque_gethwnd"); + torque_directmessage = (void (*)(unsigned int message, unsigned int wparam, unsigned int lparam))TORQUE_FUNCTION(gTorque3DModule, "torque_directmessage"); + if (!torque_gethwnd || !torque_directmessage) + { + WebCommon::MessageBox( platformWindow, "The plugin could not be initialized (missing function exports)", "Error"); + TORQUE_CLOSE(gTorque3DModule); + gTorque3DModule = NULL; + return false; + } +#endif + + //tell Torque3D that we're a browser plugin + torque_setwebdeployment(); + + const char* args[3]; + int argc; + +#ifdef WIN32 + // windows uses a command line arg for parent window + char parentWindow[256]; + argc = 3; + sprintf(parentWindow, "%I64u", (unsigned __int64)platformWindow); + args[0] = "game.exe"; //just to satisfy command line parsing + args[1] = "-window"; + args[2] = parentWindow; +#else + + NSWindow* browserWindow = (NSWindow*) platformWindow; + + // tell Torque 3D about our parent browser window + // we initialize with zero size as the page hasn't completely loaded yet + // so, the plugin hasn't been resized by the page and it is better to not show + // anything than wrong extents + torque_setsafariwindow( browserWindow, 0, 0, 0, 0); + + argc = 1; + args[0] = gameDir; // just to satisfy command line parsing + +#endif + + // initialize Torque 3D! + if (!torque_engineinit(argc, args)) + { + WebCommon::MessageBox( platformWindow, "The plugin could not be initialized (internal initialization error)", "Error"); + return false; + } + + return true; + } + + // unloads the Torque 3D shared library (first signaling a shutdown for clean exit) + void ShutdownTorque3D() + { + if (gTorque3DModule) + { + ChangeToGameDirectory(); + torque_enginesignalshutdown(); + torque_enginetick(); + torque_engineshutdown(); + TORQUE_CLOSE(gTorque3DModule); + } + + gTorque3DModule = NULL; + + } + + // checks a given domain against the allowed domains in webConfig.h + bool CheckDomain(const char* url) + { + bool domainCheck = true; + +#ifndef WEBDEPLOY_DOMAIN_CHECK + domainCheck = false; +#endif + +#ifdef DEBUG +# ifdef WEBDEPLOY_DOMAIN_ALLOW_DEBUG + domainCheck = false; +# endif +#endif + + if (!domainCheck) + return true; // gets rid of "unreachable code" warning + + if (strlen(url) > 512) + return false; + + if (strlen(url) < 5) + return false; + + //do not allow file when using domain checking + if (!strncasecmp(url,"file",4)) + return false; + + char curl[512] = {0}; + + unsigned int begin = 0; + while(url[begin]) + { + if (url[begin] == ':') + { + if (begin + 3 > strlen(url)) + return false; + begin+=3; //skip :// + break; + } + begin++; + } + + unsigned int end = begin; + + while(end < strlen(url)) + { + if (url[end] == '/') + { + break; + } + + end++; + } + + strcpy(curl, &url[begin]); + curl[end-begin] = 0; + + // iterate checking against our allowed domains + for (int i = 0; gAllowedDomains[i]; i++) + if (!strcasecmp(curl, gAllowedDomains[i])) + return true; + + WebCommon::MessageBox( 0 , "This plugin cannot be executed from the domain specified", "Error"); + + return false; + } + + // exposes TorqueScript functions marked as secure in webConfig.h, these functions can then be called on the page via Javascript + void AddSecureFunctions() + { + char snamespace[256]; + char fname[256]; + + //define secure functions here + for (unsigned int i = 0; gSecureScript[i]; i++) + { + snamespace[0] = 0; + strcpy(fname, gSecureScript[i]); + + //scan through looking for namespace + for (unsigned int j = 1; j < strlen(fname)-2; j++) + { + if (fname[j] == ':' && fname[j+1] == ':') + { + strcpy(snamespace, gSecureScript[i]); + snamespace[j] = 0; + strcpy(fname,&gSecureScript[i][j+2]); + break; + + } + } + + torque_addsecurefunction(snamespace, fname); + + } + + } + + //simple string copy that eats white space + void StringCopy(char* dst, const char* src, int count) + { + int i, j; + bool eat = true; + for (i = 0, j = 0; i < count ; i++) + { + if (src[i] == 0) + { + dst[j] = 0; + return; + } + if (src[i] != '"' && src[i] != '\t' && src[i] != '\n' && src[i] != ')' && src[i] != '(') + { + if (eat && src[i] == ' ') + continue; + + if (src[i] == '\'') + { + eat = !eat; + continue; + } + + dst[j++] = src[i]; + } + } + } + + void SetVariable(const char* variable, const char* value) + { + char mvar[1024]; + char mvar2[1024]; + + if (strlen(variable) > 1023) + { + WebCommon::MessageBox( 0, "WebCommon::SetVariable - buffer overrun", "Error"); + return; + } + + // make local copies stripping off $ decorator is needed + if (variable[0] == '$') + strcpy(mvar, &variable[1]); + else + strcpy(mvar, variable); + + const char* js = "javascript::"; + + if (strncasecmp(js, mvar, 12)) + sprintf(mvar2, "Javascript::%s", mvar); + else + strcpy(mvar2, mvar); + + torque_setvariable(mvar2, value); + } + + const char* GetVariable(const char* variable) + { + char mvar[1024]; + char mvar2[1024]; + + if (strlen(variable) > 1023) + { + WebCommon::MessageBox( 0, "WebCommon::GetVariable - buffer overrun", "Error"); + return "0"; + } + + // make local copies stripping off $ decorator is needed + if (variable[0] == '$') + strcpy(mvar, &variable[1]); + else + strcpy(mvar, variable); + + const char* js = "javascript::"; + + if (strncasecmp(js, mvar, 12)) + sprintf(mvar2, "Javascript::%s", mvar); + else + strcpy(mvar2, mvar); + + return torque_getvariable(mvar2); + + } + + +#ifdef WIN32 + + // string conversion to/from wstring and string + std::wstring StringToWString( const std::string& str ) + { + size_t size = str.length(); + wchar_t* w = new wchar_t[size+1]; + + memset( w, 0, sizeof(wchar_t) * (size+1) ); + + MultiByteToWideChar( CP_ACP, + 0, + str.c_str(), + size, + w, + size ); + + std::wstring ws(w); + delete[] w; + return ws; + } + + std::string WStringToString( const std::wstring& wstr ) + { + size_t size = wstr.length(); + char* s = new char[size+1]; + + memset( s, 0, sizeof(char) * (size+1) ); + + WideCharToMultiByte( CP_ACP, + 0, + wstr.c_str(), + size, + s, + size, + NULL, + NULL ); + + std::string str(s); + delete[] s; + return str; + } + + void ConvertToWindowsPathSep(std::string& path) + { + size_t pos = 0; + while(pos < path.size() || pos != std::string::npos) + { + pos = path.find("/", pos); + if(pos != std::string::npos) + { + path.replace(pos, 1, "\\"); + ++pos; + } + } + } + +#endif + +} //namespace WebCommon \ No newline at end of file diff --git a/Templates/Empty/web/source/common/webCommon.h b/Templates/Empty/web/source/common/webCommon.h new file mode 100644 index 000000000..a04664c7e --- /dev/null +++ b/Templates/Empty/web/source/common/webCommon.h @@ -0,0 +1,166 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#ifndef _webcommon_h +#define _webcommon_h + +// Common web functionality between IE/Safari/Firefox/Chrome + +// Platform specific includes +#ifdef WIN32 + + #include <windows.h> + +#else // Mac + + #include <Cocoa/Cocoa.h> + #include <WebKit/npapi.h> + #include <WebKit/npfunctions.h> + #include <WebKit/npruntime.h> + #include <dlfcn.h> + + #define OSCALL + +#endif + +// common includes +#include <string> +#include <algorithm> +#include <vector> +#include <stdio.h> +#include <stdlib.h> + +// Function prototype matching Torque 3D console callback convention +typedef const char * (*StringCallback)(void *obj, int argc, const char *argv[]); + +namespace WebCommon +{ + // loads the Torque 3D shared library, sets web deployment mode, retrieves engine "C" interface + bool InitTorque3D(void *platformWindow, int clipLeft = 0, int clipTop= 0, int clipRight = 0, int clipBottom = 0); + + // sets the current directory to the game install path + bool ChangeToGameDirectory(); + + // unloads the Torque 3D shared library (first signaling a shutdown for clean exit) + void ShutdownTorque3D(); + + // checks a given domain against the allowed domains in webConfig.h + bool CheckDomain(const char* url); + + // exposes TorqueScript functions marked as secure in webConfig.h, these functions can then be called on the page via Javascript + void AddSecureFunctions(); + + // bring up a platform specific message box (used for error reporting) + void MessageBox(void* parentWindow, const char* msg, const char* caption); + + // a handy string function that eats white space + void StringCopy(char* dst, const char* src, int count); + + void SetVariable(const char* variable, const char* value); + const char* GetVariable(const char* variable); + + extern std::string gPluginMIMEType; + +#ifdef WIN32 + // the handle of our plugin's DLL + extern HMODULE gPluginModule; + // the handle of the Torque 3D DLL + extern HMODULE gTorque3DModule; + + //string conversion to/from wstring and string + std::string WStringToString( const std::wstring& wstr); + std::wstring StringToWString( const std::string& str); + + void ConvertToWindowsPathSep(std::string& path); +#else //Mac + // ptr to the Torque 3D Bundle + extern void* gTorque3DModule; +#endif + +}; + +// C Interface exported from the Torque 3D DLL (or Bundle on Mac) + +extern "C" +{ + // initialize Torque 3D including argument handling + extern bool (*torque_engineinit)(int argc, const char **argv); + + // tick Torque 3D's main loop + extern int (*torque_enginetick)(); + + // set Torque 3D into web deployment mode (disable fullscreen exlusive mode, etc) + extern int (*torque_setwebdeployment)(); + + // shutdown the engine + extern bool (*torque_engineshutdown)(); + + // signal an engine shutdown (as with the quit(); console command) + extern void (*torque_enginesignalshutdown)(); + + // reset the engine, unloading any current level and returning to the main menu + extern void (*torque_reset)(); + + // Evaluate arbitrary TorqueScript (ONLY CALL torque_evaluate FROM TRUSTED CODE!!!) + extern const char* (*torque_evaluate)(const char* code); + + // Get a console variable + // For security, restricted to "Javascript::" namespace + extern const char* (*torque_getvariable)(const char* name); + // Set a console variable + // For security, restricted to "Javascript::" namespace + extern void (*torque_setvariable)(const char* name, const char* value); + + // Export a function to the Torque 3D console system which matches the StringCallback function prototype + // specify the nameSpace, functionName, usage, min and max arguments + extern void (*torque_exportstringcallback)(StringCallback cb, const char *nameSpace, const char *funcName, const char* usage, int minArgs, int maxArgs); + + // Set a TorqueScript console function as secure and available for JavaScript via the callScript plugin method + extern void (*torque_addsecurefunction)(const char* nameSpace, const char* fname); + // Call a TorqueScript console function that has been marked as secure + extern const char* (*torque_callsecurefunction)(const char* nameSpace, const char* name, int argc, const char ** argv); + + // resize the Torque 3D child window to the specified width and height + extern void (*torque_resizewindow)(int width, int height); + +#ifndef WIN32 + // On Mac, handle the parent safari window + extern void (*torque_setsafariwindow)(NSWindow* window, int32 x, int32 y, int32 width, int32 height); + + // On Mac, sets the executable path + extern void (*torque_setexecutablepath)(const char *path); +#else + // retrieve the render windows hwnd + extern void* (*torque_gethwnd)(); + + // directly add a message to the Torque 3D event queue, bypassing the Windows event queue + // this is useful in the case of the IE plugin, where we are hooking into an application + // level message, and posting to the windows queue would cause a hang + extern void (*torque_directmessage)(unsigned int message, unsigned int wparam, unsigned int lparam); +#endif + +}; + + + + +#endif \ No newline at end of file diff --git a/Templates/Empty/web/source/common/webConfig.h b/Templates/Empty/web/source/common/webConfig.h new file mode 100644 index 000000000..b43609d58 --- /dev/null +++ b/Templates/Empty/web/source/common/webConfig.h @@ -0,0 +1,44 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Define secure TorqueScript calls by adding them here. +// This list defines the calls that can be made by JavaScript into your game, so be very careful. + +const char* gSecureScript[] = { + "echo", + "testJavaScriptBridge", + //"MyNamespace::myfunction", + 0 //SENTINEL +}; + +// Define the domains which are allowed to run your game via the web +// Your game plugin will refuse to run from any other domain for security reasons. +// You can turn this off during development and/or for debug builds + +//#define WEBDEPLOY_DOMAIN_CHECK +//#define WEBDEPLOY_DOMAIN_ALLOW_DEBUG + +const char* gAllowedDomains[] = { + //"www.mydomain.com", + //"games.myotherdomain.com", + 0 //SENTINEL +}; \ No newline at end of file diff --git a/Templates/Empty/web/source/npplugin/mac/English.lproj/InfoPlist.strings b/Templates/Empty/web/source/npplugin/mac/English.lproj/InfoPlist.strings new file mode 100644 index 000000000..587f21ea6 Binary files /dev/null and b/Templates/Empty/web/source/npplugin/mac/English.lproj/InfoPlist.strings differ diff --git a/Templates/Empty/web/source/npplugin/mac/WebGamePlugin_Prefix.pch b/Templates/Empty/web/source/npplugin/mac/WebGamePlugin_Prefix.pch new file mode 100644 index 000000000..d9c0295b2 --- /dev/null +++ b/Templates/Empty/web/source/npplugin/mac/WebGamePlugin_Prefix.pch @@ -0,0 +1,5 @@ +// +// Prefix header for all source files of the 'WebGamePlugin' target in the 'WebGamePlugin' project. +// + +#include <Carbon/Carbon.h> diff --git a/Templates/Empty/web/source/npplugin/mac/npWebGamePlugin.h b/Templates/Empty/web/source/npplugin/mac/npWebGamePlugin.h new file mode 100644 index 000000000..dda9759d4 --- /dev/null +++ b/Templates/Empty/web/source/npplugin/mac/npWebGamePlugin.h @@ -0,0 +1,44 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#pragma once + +#include "../../common/webCommon.h" + +class NPWebGamePlugin +{ +public: + + NPWebGamePlugin(NPP aInstance); + ~NPWebGamePlugin(); + + NPBool Open(NPWindow* aWindow); + void Close(); + NPBool IsOpen(); + + NPP mInstance; + bool mOpen; + + static NPWebGamePlugin* sInstance; +}; + + diff --git a/Templates/Empty/web/source/npplugin/mac/npWebGamePlugin.mm b/Templates/Empty/web/source/npplugin/mac/npWebGamePlugin.mm new file mode 100644 index 000000000..045209add --- /dev/null +++ b/Templates/Empty/web/source/npplugin/mac/npWebGamePlugin.mm @@ -0,0 +1,136 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include <string> +#include <vector> + +#include "npWebGamePlugin.h" + +// Timer which ticks/renders Torque3D +static CFRunLoopTimerRef gTimer = NULL; + +static bool gHidden = false; + +static void timer_callback(CFRunLoopRef timer, void *info) +{ + + if (gHidden) + return; + + if (!torque_enginetick()) + { + //TODO: undefined when get quit from Torque 3D under Safari + } + +} + +NPWebGamePlugin* NPWebGamePlugin::sInstance = NULL; + +NPWebGamePlugin::NPWebGamePlugin(NPP aInstance) +{ + mOpen = FALSE; + mInstance = aInstance; + sInstance = this; +} + +NPWebGamePlugin::~NPWebGamePlugin() +{ + Close(); + sInstance = NULL; +} + +NPBool NPWebGamePlugin::Open(NPWindow* aWindow) +{ + gHidden = false; + + WebCommon::ChangeToGameDirectory(); + + if (mOpen || WebCommon::gTorque3DModule) + { + NP_CGContext *npcontext = reinterpret_cast<NP_CGContext *> (aWindow->window); + NSWindow* browserWindow = [[NSWindow alloc] initWithWindowRef:npcontext->window]; + torque_setsafariwindow( browserWindow, aWindow->clipRect.left, aWindow->clipRect.top, aWindow->clipRect.right - aWindow->clipRect.left, aWindow->clipRect.bottom - aWindow->clipRect.top ); + [browserWindow release]; + + mOpen = TRUE; + + return TRUE; + } + if (!aWindow) + return FALSE; + + mOpen = true; + + NP_CGContext *npcontext = reinterpret_cast<NP_CGContext *> (aWindow->window); + + // You may want to resize the browser window or set minimum sizes here for your web content + NSWindow* browserWindow = [[NSWindow alloc] initWithWindowRef:npcontext->window]; + + if (!browserWindow) + { + WebCommon::MessageBox( 0, "Web plugin unable to get browser window", "Error"); + return false; + } + + if (!WebCommon::InitTorque3D(browserWindow, aWindow->clipRect.left, aWindow->clipRect.top, aWindow->clipRect.right - aWindow->clipRect.left, aWindow->clipRect.bottom - aWindow->clipRect.top)) + return false; + + //setup high speed timer to tick Torque 3D + CFAllocatorRef allocator = kCFAllocatorDefault; + CFAbsoluteTime fireDate = CFAbsoluteTimeGetCurrent() + .001; + CFTimeInterval interval = .001; + CFOptionFlags flags = 0; + CFIndex order = 0; + CFRunLoopTimerCallBack callback = (CFRunLoopTimerCallBack)timer_callback; + CFRunLoopTimerContext context = { 0, NULL, NULL, NULL, NULL }; + gTimer = CFRunLoopTimerCreate(allocator, fireDate, interval, flags, order, callback, &context); + CFRunLoopAddTimer(CFRunLoopGetCurrent(), gTimer, kCFRunLoopDefaultMode); + + [browserWindow release]; + + return mOpen; +} + +void NPWebGamePlugin::Close() +{ + + if (!mOpen) + return; + + if (WebCommon::gTorque3DModule) + { + gHidden = true; + torque_setsafariwindow(NULL, 0, 0, 0, 0); + torque_reset(); + } + + //WebCommon::ShutdownTorque3D(); + + mOpen = false; +} + +NPBool NPWebGamePlugin::IsOpen() +{ + return mOpen; +} + + diff --git a/Templates/Empty/web/source/npplugin/npPlugin.cpp b/Templates/Empty/web/source/npplugin/npPlugin.cpp new file mode 100644 index 000000000..5f22d73a6 --- /dev/null +++ b/Templates/Empty/web/source/npplugin/npPlugin.cpp @@ -0,0 +1,813 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include <string> +#include <vector> + +#include "npWebGamePlugin.h" +#include "../common/webCommon.h" + +// Functions exported from the browser to our plugin +static NPNetscapeFuncs NPNFuncs; + +// Set once both the web page and plugin are fully loaded (including any possible Javascript <-> TorqueScript exports/imports) +static BOOL gInitialized = false; + +#ifndef WIN32 +// Entry points into our plugin for Safari +extern "C" { + +#pragma GCC visibility push(default) + +NPError NP_Initialize (NPNetscapeFuncs *browser); +NPError NP_GetEntryPoints (NPPluginFuncs *plugin); +NPError NP_Shutdown(); + +#pragma GCC visibility pop + +} +#endif + +// Converts a NPVARIANT variable to a C string representation +const char* MY_NPVARIANT_TO_STRING(const NPVariant& f) +{ + static std::string result; + char r[1024] = {0}; + + if (NPVARIANT_IS_VOID(f) || NPVARIANT_IS_NULL(f)) + return ""; + + if (NPVARIANT_IS_STRING(f)) + { + NPString str = NPVARIANT_TO_STRING(f); + result = std::string(str.UTF8Characters, str.UTF8Length); + return result.c_str(); + } + + if (NPVARIANT_IS_BOOLEAN(f)) + { + if (NPVARIANT_TO_BOOLEAN(f)) + return "1"; + return "0"; + } + + if (NPVARIANT_IS_INT32(f)) + { + sprintf(r, "%i", NPVARIANT_TO_INT32(f)); + result = r; + return result.c_str(); + } + + if (NPVARIANT_IS_DOUBLE(f)) + { + sprintf(r, "%f", NPVARIANT_TO_DOUBLE(f)); + result = r; + return result.c_str(); + } + + return ""; + +} + +// Javascript -> TorqueScript function calling (with parser) +const char* CallScript(const char* code) +{ + std::string scode = code; + const char* sig = scode.c_str(); + + // do not allow large strings which could be used maliciously + if (scode.length() > 255 || !gInitialized) + { + return ""; + } + + // data buffers for laying out data in a Torque 3D console friendly manner + char nameSpace[256]; + char fname[256]; + char argv[256][256]; + char* argvv[256]; + int argc = 0; + int argBegin = 0; + + memset(nameSpace, 0, 256); + memset(fname, 0, 256); + memset(argv, 0, 256 * 256); + + for (int i = 0; i < scode.length(); i++) + { + if (sig[i] == ')' || sig[i] == ';') + { + //scan out last arg is any + char dummy[256]; + memset(dummy, 0, 256); + + WebCommon::StringCopy(dummy, &sig[argBegin], i - argBegin); + + if (strlen(dummy)) + { + strcpy(argv[argc], dummy); + argvv[argc] = argv[argc]; + argc++; + } + + break; // done + } + + // handle namespace + if (sig[i]==':') + { + if (nameSpace[0] || fname[0]) + { + return ""; + } + + if (i > 0 && sig[i-1] == ':') + { + if (i - 2 > 0) + WebCommon::StringCopy(nameSpace, sig, i - 1); + } + + continue; + } + + // arguments begin + if (sig[i] == '(' ) + { + if (fname[0] || i < 1) + { + return ""; + } + + //everything before this is function name, minus nameSpace + if (nameSpace[0]) + { + int nlen = strlen(nameSpace); + WebCommon::StringCopy(fname, &sig[nlen + 2], i - nlen - 2); + } + else + { + WebCommon::StringCopy(fname, sig, i); + } + + WebCommon::StringCopy(argv[0], fname, strlen(fname)+1); + argvv[0] = argv[0]; + argc++; + + argBegin = i + 1; + } + + // argument + if (sig[i] == ',' ) + { + if (argBegin >= i || argc == 255) + { + return ""; + } + + WebCommon::StringCopy(argv[argc], &sig[argBegin], i - argBegin); + argvv[argc] = argv[argc]; + + argc++; + argBegin = i + 1; + } + + } + + static std::string retVal; + + if (fname[0]) + { + // call into the Torque 3D shared library (console system) and get return value + retVal = torque_callsecurefunction(nameSpace, fname, argc, (const char **) argvv); + return retVal.c_str(); + } + + return ""; +} + + +// TorqueScript -> JavaScript +const char* CallJavaScriptFunction(const char* name, int numArguments, const char* argv[]) +{ + // our plugin instance + NPP pNPInstance = NPWebGamePlugin::sInstance->mInstance; + + // holds the generated Javascript encoded as a NPString + NPString npScript; + + // retrieve our plugin object from the browser + NPObject* pluginObject; + + if (NPERR_NO_ERROR != NPNFuncs.getvalue(pNPInstance, NPNVPluginElementNPObject, &pluginObject)) + { + return NULL; + } + + // generate Javascript to be evaluated + std::string script = name; + script += "("; + for (int i = 1; i < numArguments; i++) + { + script += "\""; + script += argv[i]; + script += "\""; + if ( i + 1 < numArguments) + script += ", "; + } + script += ");"; + + //encode as a NPString + npScript.UTF8Characters = script.c_str(); + npScript.UTF8Length = script.length(); + + // finally, have browser evaluate our script and get the return value + NPVariant result; + NPNFuncs.evaluate(pNPInstance,pluginObject,&npScript,&result); + + return MY_NPVARIANT_TO_STRING(result); + +} + +// the sole entry point for Torque 3D console system into our browser plugin (handed over as a function pointer) +static const char * MyStringCallback(void *obj, int argc, const char* argv[]) +{ + static char ret[4096]; + strcpy(ret,CallJavaScriptFunction(argv[0], argc, argv)); + return ret; +} + + +// these can be added on the page before we're initialized, so we cache until we're ready for them +typedef struct +{ + std::string jsCallback; //javascript function name + unsigned int numArguments; //the number of arguments it takes +} JavasScriptExport; + +static std::vector<JavasScriptExport> gJavaScriptExports; + +// this actually exports the function to the Torque 3D console system +// we do this in two steps as we can't guarantee that Torque 3D is initialized on web page +// before JavaScript calls are made +void ExportFunctionInternal(const JavasScriptExport& jsexport) +{ + torque_exportstringcallback(MyStringCallback,"JS",jsexport.jsCallback.c_str(),"",jsexport.numArguments,jsexport.numArguments); +} + +// invoked via the Javascript plugin object startup() method once the page/plugin are fully loaded +void Startup() +{ + if (gInitialized) + return; + + // actually do the export on any cached functions + gInitialized = true; + std::vector<JavasScriptExport>::iterator i; + for (i = gJavaScriptExports.begin(); i != gJavaScriptExports.end();i++) + { + ExportFunctionInternal(*i); + } + + // setup the secure TorqueScript function calls we can call from Javascript (see webConfig.h) + WebCommon::AddSecureFunctions(); +} + +// Export a Javascript function to the Torque 3D console system, possibly caching it +void ExportFunction(const char* callback, int numArguments) +{ + JavasScriptExport jsexport; + jsexport.jsCallback = callback; + jsexport.numArguments = numArguments; + + if (!gInitialized) + { + //queue it up + gJavaScriptExports.push_back(jsexport); + } + else + { + ExportFunctionInternal(jsexport); + } +} + +// NP Plugin Interface + + +// Our plugin object structure "inherited" from NPObject +typedef struct +{ + // NPObject fields + NPClass *_class; + uint32_t referenceCount; + + // Here begins our custom fields (well, field) + + // Platform specific game plugin class (handles refresh, sizing, initialization of Torque 3D, etc) + NPWebGamePlugin* webPlugin; + +} PluginObject; + +static PluginObject* gPluginObject = NULL; + +// interface exports for our plugin that are expected to the browser + +void pluginInvalidate (); +bool pluginHasProperty (NPClass *theClass, NPIdentifier name); +bool pluginHasMethod (NPObject *npobj, NPIdentifier name); +bool pluginGetProperty (PluginObject *obj, NPIdentifier name, NPVariant *variant); +bool pluginSetProperty (PluginObject *obj, NPIdentifier name, const NPVariant *variant); +bool pluginInvoke (PluginObject *obj, NPIdentifier name, NPVariant *args, uint32_t argCount, NPVariant *result); +bool pluginInvokeDefault (PluginObject *obj, NPVariant *args, uint32_t argCount, NPVariant *result); +NPObject *pluginAllocate (NPP npp, NPClass *theClass); +void pluginDeallocate (PluginObject *obj); + +static NPClass _pluginFunctionPtrs = { + NP_CLASS_STRUCT_VERSION, + (NPAllocateFunctionPtr) pluginAllocate, + (NPDeallocateFunctionPtr) pluginDeallocate, + (NPInvalidateFunctionPtr) pluginInvalidate, + (NPHasMethodFunctionPtr) pluginHasMethod, + (NPInvokeFunctionPtr) pluginInvoke, + (NPInvokeDefaultFunctionPtr) pluginInvokeDefault, + (NPHasPropertyFunctionPtr) pluginHasProperty, + (NPGetPropertyFunctionPtr) pluginGetProperty, + (NPSetPropertyFunctionPtr) pluginSetProperty, +}; + +// versioning information + +static bool identifiersInitialized = false; + +#define ID_VERSION_PROPERTY 0 +#define NUM_PROPERTY_IDENTIFIERS 1 + +static NPIdentifier pluginPropertyIdentifiers[NUM_PROPERTY_IDENTIFIERS]; +static const NPUTF8 *pluginPropertyIdentifierNames[NUM_PROPERTY_IDENTIFIERS] = { + "version", +}; + +// methods that are callable on the plugin from Javascript + +#define ID_SETVARIABLE_METHOD 0 +#define ID_GETVARIABLE_METHOD 1 +#define ID_EXPORTFUNCTION_METHOD 2 +#define ID_CALLSCRIPT_METHOD 3 +#define ID_STARTUP_METHOD 4 +#define NUM_METHOD_IDENTIFIERS 5 + +static NPIdentifier pluginMethodIdentifiers[NUM_METHOD_IDENTIFIERS]; +static const NPUTF8 *pluginMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = { + "setVariable", + "getVariable", + "exportFunction", + "callScript", + "startup", +}; + +NPClass *getPluginClass(void) +{ + return &_pluginFunctionPtrs; +} + +// Sets up the property and method identifier arrays used by the browser +// via the hasProperty and hasMethod fuction pointers +static void initializeIdentifiers() +{ + // fill the property identifier array + NPNFuncs.getstringidentifiers(pluginPropertyIdentifierNames, + NUM_PROPERTY_IDENTIFIERS, + pluginPropertyIdentifiers); + + // fill the method identifier array + NPNFuncs.getstringidentifiers(pluginMethodIdentifierNames, + NUM_METHOD_IDENTIFIERS, + pluginMethodIdentifiers); +}; + +bool pluginHasProperty (NPClass *theClass, NPIdentifier name) +{ + for (int i = 0; i < NUM_PROPERTY_IDENTIFIERS; i++) { + if (name == pluginPropertyIdentifiers[i]) { + return true; + } + } + return false; +} + +bool pluginHasMethod(NPObject *npobj, NPIdentifier name) +{ + for (int i = 0; i < NUM_METHOD_IDENTIFIERS; i++) { + if (name == pluginMethodIdentifiers[i]) { + return true; + } + } + return false; +} + +// utility function that sets up a NPVariant from a std::string +void FillString(const std::string& src, NPVariant* variant) +{ + variant->type = NPVariantType_String; + variant->value.stringValue.UTF8Length = static_cast<uint32_t>(src.length()); + variant->value.stringValue.UTF8Characters = reinterpret_cast<NPUTF8 *>(NPNFuncs.memalloc(src.size())); + memcpy((void*)variant->value.stringValue.UTF8Characters, src.c_str(), src.size()); +} + + +bool pluginGetProperty (PluginObject *obj, NPIdentifier name, NPVariant *variant) +{ + VOID_TO_NPVARIANT(*variant); + + if (name == pluginPropertyIdentifiers[ID_VERSION_PROPERTY]) { + FillString(std::string("1.0"), variant); + return true; + } + + //unknown property + return false; +} + +bool pluginSetProperty (PluginObject *obj, NPIdentifier name, const NPVariant *variant) +{ + + return false; +} + +// handle our plugin methods using standard np plugin conventions. +bool pluginInvoke (PluginObject *obj, NPIdentifier name, NPVariant *args, unsigned argCount, NPVariant *result) +{ + VOID_TO_NPVARIANT(*result); + + // sanity check + if (argCount > 16) + return false; + + // plugin.startup(); - called once web page is fully loaded and plugin (including Torque 3D) is initialized + if (name == pluginMethodIdentifiers[ID_STARTUP_METHOD]) { + result->type = NPVariantType_Void; + + Startup(); + return true; + } + // plugin.setVariable("$MyVariable", 42); - set a Torque 3D console variable + else if (name == pluginMethodIdentifiers[ID_SETVARIABLE_METHOD]) { + result->type = NPVariantType_Void; + if (argCount != 2) + return false; + + std::string arg0(MY_NPVARIANT_TO_STRING(args[0])); + std::string arg1(MY_NPVARIANT_TO_STRING(args[1])); + WebCommon::SetVariable(arg0.c_str(), arg1.c_str()); + return true; + } + // plugin.getVariable("$MyVariable"); - get a Torque 3D console variable + else if (name == pluginMethodIdentifiers[ID_GETVARIABLE_METHOD]) { + if (argCount != 1) + return false; + + std::string value; + std::string arg0(MY_NPVARIANT_TO_STRING(args[0])); + value = WebCommon::GetVariable(arg0.c_str()); + FillString(value, result); + + return true; + } + // plugin.exportFunction("MyJavascriptFunction",3); - export a Javascript function to the Torque 3D console system via its name and argument count + else if (name == pluginMethodIdentifiers[ID_EXPORTFUNCTION_METHOD]) { + result->type = NPVariantType_Void; + if (argCount != 2) + return false; + + std::string fname(MY_NPVARIANT_TO_STRING(args[0])); + + int argCount = 0; + + if (NPVARIANT_IS_DOUBLE(args[1])) + argCount = NPVARIANT_TO_DOUBLE(args[1]); + else + argCount = NPVARIANT_TO_INT32(args[1]); + + ExportFunction(fname.c_str(), argCount); + return true; + } + // var result = plugin.callScript("mySecureFunction('one', 'two', 'three');"); - call a TorqueScript function marked as secure in webConfig.h with supplied arguments + else if (name == pluginMethodIdentifiers[ID_CALLSCRIPT_METHOD]) { + + if (argCount != 1) + return false; + + std::string value; + std::string code(MY_NPVARIANT_TO_STRING(args[0])); + value = CallScript(code.c_str()); + FillString(value, result); + return true; + } + + + return false; +} + +bool pluginInvokeDefault (PluginObject *obj, NPVariant *args, unsigned argCount, NPVariant *result) +{ + VOID_TO_NPVARIANT(*result); + return false; +} + +void pluginInvalidate () +{ + // Make sure we've released any remaining references to JavaScript + // objects. +} + +NPObject *pluginAllocate (NPP npp, NPClass *theClass) +{ + + PluginObject *newInstance = new PluginObject; + + gPluginObject = newInstance; + + if (!identifiersInitialized) + { + identifiersInitialized = true; + initializeIdentifiers(); + } + + // platform specific NPWebGamePlugin instantiation + newInstance->webPlugin = new NPWebGamePlugin(npp); + + gInitialized = false; + gJavaScriptExports.clear(); + + return (NPObject *)newInstance; +} + +void pluginDeallocate (PluginObject *obj) +{ + delete obj; + gPluginObject = NULL; +} + +int32 NPP_Write (NPP instance, NPStream *stream, int32_t offset, int32_t len, void *buffer); + + +NPError OSCALL NP_GetEntryPoints(NPPluginFuncs* pFuncs) +{ + if (pFuncs == NULL) { + return NPERR_INVALID_FUNCTABLE_ERROR; + } + + // Safari sets the size field of pFuncs to 0 + if (pFuncs->size == 0) + pFuncs->size = sizeof(NPPluginFuncs); + if (pFuncs->size < sizeof(NPPluginFuncs)) { + return NPERR_INVALID_FUNCTABLE_ERROR; + } + + pFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; + pFuncs->newp = NPP_New; + pFuncs->destroy = NPP_Destroy; + pFuncs->setwindow = NPP_SetWindow; + pFuncs->newstream = NPP_NewStream; + pFuncs->destroystream = NPP_DestroyStream; + pFuncs->asfile = NPP_StreamAsFile; + pFuncs->writeready = NPP_WriteReady; + pFuncs->write = NPP_Write; + pFuncs->print = NPP_Print; + pFuncs->event = NPP_HandleEvent; + pFuncs->urlnotify = NPP_URLNotify; + pFuncs->getvalue = NPP_GetValue; + pFuncs->setvalue = NPP_SetValue; + pFuncs->javaClass = NULL; + + return NPERR_NO_ERROR; +} + +NPError OSCALL NP_Initialize(NPNetscapeFuncs* pFuncs) +{ + static bool _initialized = false; + if (!_initialized) { + _initialized = true; + } + + if (pFuncs == NULL) + return NPERR_INVALID_FUNCTABLE_ERROR; + + if ((pFuncs->version >> 8) > NP_VERSION_MAJOR) + return NPERR_INCOMPATIBLE_VERSION_ERROR; + + // Safari sets the pfuncs size to 0 + if (pFuncs->size == 0) + pFuncs->size = sizeof(NPNetscapeFuncs); + if (pFuncs->size < sizeof (NPNetscapeFuncs)) + return NPERR_INVALID_FUNCTABLE_ERROR; + + NPNFuncs = *pFuncs; + + return NPERR_NO_ERROR; +} + +NPError OSCALL NP_Shutdown() +{ + if (WebCommon::gTorque3DModule) + WebCommon::ShutdownTorque3D(); + + return NPERR_NO_ERROR; +} + + +NPError NPP_New(NPMIMEType pluginType, + NPP instance, uint16 mode, + int16 argc, char *argn[], + char *argv[], NPSavedData *saved) +{ + WebCommon::gPluginMIMEType = pluginType; + + if (gPluginObject) + { + WebCommon::MessageBox( 0, "This plugin allows only one instance", "Error"); + return NPERR_GENERIC_ERROR; + } + + // Get the location we're loading the plugin from (http://, file://) including address + // this is used by the domain locking feature to ensure that your plugin is only + // being used from your web site + + NPObject* windowObject = NULL; + NPNFuncs.getvalue( instance, NPNVWindowNPObject, &windowObject ); + + NPVariant variantValue; + NPIdentifier identifier = NPNFuncs.getstringidentifier( "location" ); + + if (!NPNFuncs.getproperty( instance, windowObject, identifier, &variantValue )) + return NPERR_GENERIC_ERROR; + + NPObject *locationObj = variantValue.value.objectValue; + + identifier = NPNFuncs.getstringidentifier( "href" ); + + if (!NPNFuncs.getproperty( instance, locationObj, identifier, &variantValue )) + return NPERR_GENERIC_ERROR; + + std::string url = MY_NPVARIANT_TO_STRING(variantValue); + + if (!WebCommon::CheckDomain(url.c_str())) + return NPERR_GENERIC_ERROR; + + // everything checks out, let's rock + + if (NPNFuncs.version >= 14) { + // this calls pluginAllocate + instance->pdata = NPNFuncs.createobject(instance, getPluginClass()); + } + +#ifndef WIN32 + // On Mac, make sure we're using CoreGraphics (otherwise 3D rendering fails) + NPNFuncs.setvalue(instance, (NPPVariable)NPNVpluginDrawingModel, (void *) NPDrawingModelCoreGraphics); +#endif + + //PluginObject *plugin = (PluginObject*)instance->pdata; + + return NPERR_NO_ERROR; +} + +// here is the place to clean up and destroy the object +NPError NPP_Destroy (NPP instance, NPSavedData** save) +{ + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + if (instance->pdata != NULL) { + PluginObject *plugin = (PluginObject *)instance->pdata; + delete plugin->webPlugin; + + NPNFuncs.releaseobject((NPObject*) instance->pdata); + instance->pdata = NULL; + } + return NPERR_NO_ERROR; +} + +NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) +{ + if (variable == NPPVpluginScriptableNPObject) { + + if (instance->pdata == NULL) { + instance->pdata = NPNFuncs.createobject(instance, getPluginClass()); + } + + NPObject* obj = reinterpret_cast<NPObject*>(instance->pdata); + NPNFuncs.retainobject(obj); + void **v = (void **)value; + *v = obj; + return NPERR_NO_ERROR; + } + + return NPERR_GENERIC_ERROR; +} + +NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value) +{ + return NPERR_GENERIC_ERROR; +} + +NPError NPP_NewStream(NPP instance, + NPMIMEType type, + NPStream* stream, + NPBool seekable, + uint16* stype) +{ + if(instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + return NPERR_NO_ERROR; +} + +int32 NPP_WriteReady (NPP instance, NPStream *stream) +{ + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + return 0x0fffffff; +} + +int32 NPP_Write (NPP instance, NPStream *stream, int32_t offset, int32_t len, void *buffer) +{ + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + return NPERR_NO_ERROR; +} + +NPError NPP_DestroyStream (NPP instance, NPStream *stream, NPError reason) +{ + if(instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + return NPERR_NO_ERROR; +} + + +void NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData) +{ + +} + +void NPP_StreamAsFile (NPP instance, NPStream* stream, const char* fname) +{ +} + +void NPP_Print (NPP instance, NPPrint* printInfo) +{ +} + +int16 NPP_HandleEvent(NPP instance, void* event) +{ + return 0; +} +// browser communicated window changes (creation, etc) here +NPError NPP_SetWindow(NPP instance, NPWindow* window) +{ + // strange... + if (!window || !window->window) + return NPERR_GENERIC_ERROR; + // strange... + if (!instance) + return NPERR_INVALID_INSTANCE_ERROR; + + // get back the plugin instance object + PluginObject *plugin = (PluginObject *)instance->pdata; + NPWebGamePlugin* webPlugin = plugin->webPlugin; + if (webPlugin) { + if (!window->window) { + + } + else { + + // handle platform specific window and Torque 3D initialization + webPlugin->Open(window); + } + + return NPERR_NO_ERROR; + } + + // return an error if no object defined + return NPERR_GENERIC_ERROR; +} diff --git a/Templates/Empty/web/source/npplugin/windows/NPWebGamePlugin.rc b/Templates/Empty/web/source/npplugin/windows/NPWebGamePlugin.rc new file mode 100644 index 000000000..46f308fca --- /dev/null +++ b/Templates/Empty/web/source/npplugin/windows/NPWebGamePlugin.rc @@ -0,0 +1,106 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "windows.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0 + PRODUCTVERSION 1,0 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "PluginType", "Mozilla" + VALUE "FileDescription", "My Web Game Plugin 1.0" + VALUE "FileExtents", "*" + VALUE "FileVersion", "1,0" + VALUE "InternalName", "My Web Game" + VALUE "MIMEType", "application/x-emptytemplateplugin" + VALUE "OriginalFilename", "NP Empty Plugin.dll" + VALUE "ProductName", "My Web Game" + VALUE "ProductVersion", "1,0" + VALUE "CompanyName", "My Game Company" + VALUE "CompanyKey", "mygamecompany" + VALUE "Plugin", "WebEmptyTemplate" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""windows.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Templates/Empty/web/source/npplugin/windows/jni.h b/Templates/Empty/web/source/npplugin/windows/jni.h new file mode 100644 index 000000000..6105e030b --- /dev/null +++ b/Templates/Empty/web/source/npplugin/windows/jni.h @@ -0,0 +1,1973 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Java Runtime Interface. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation and Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1993-1996 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef JNI_H +#define JNI_H + +#include <stdio.h> +#include <stdarg.h> + +/* jni_md.h contains the machine-dependent typedefs for jbyte, jint + and jlong */ + +#include "jni_md.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * JNI Types + */ + +typedef unsigned char jboolean; +typedef unsigned short jchar; +typedef short jshort; +typedef float jfloat; +typedef double jdouble; + +typedef jint jsize; + +#ifdef __cplusplus + +class _jobject {}; +class _jclass : public _jobject {}; +class _jthrowable : public _jobject {}; +class _jstring : public _jobject {}; +class _jarray : public _jobject {}; +class _jbooleanArray : public _jarray {}; +class _jbyteArray : public _jarray {}; +class _jcharArray : public _jarray {}; +class _jshortArray : public _jarray {}; +class _jintArray : public _jarray {}; +class _jlongArray : public _jarray {}; +class _jfloatArray : public _jarray {}; +class _jdoubleArray : public _jarray {}; +class _jobjectArray : public _jarray {}; + +typedef _jobject *jobject; +typedef _jclass *jclass; +typedef _jthrowable *jthrowable; +typedef _jstring *jstring; +typedef _jarray *jarray; +typedef _jbooleanArray *jbooleanArray; +typedef _jbyteArray *jbyteArray; +typedef _jcharArray *jcharArray; +typedef _jshortArray *jshortArray; +typedef _jintArray *jintArray; +typedef _jlongArray *jlongArray; +typedef _jfloatArray *jfloatArray; +typedef _jdoubleArray *jdoubleArray; +typedef _jobjectArray *jobjectArray; + +#else + +struct _jobject; + +typedef struct _jobject *jobject; +typedef jobject jclass; +typedef jobject jthrowable; +typedef jobject jstring; +typedef jobject jarray; +typedef jarray jbooleanArray; +typedef jarray jbyteArray; +typedef jarray jcharArray; +typedef jarray jshortArray; +typedef jarray jintArray; +typedef jarray jlongArray; +typedef jarray jfloatArray; +typedef jarray jdoubleArray; +typedef jarray jobjectArray; + +#endif + +typedef jobject jweak; + +#if 0 /* moved to jri_md.h */ +typedef jobject jref; /* For transition---not meant to be part of public + API anymore.*/ +#endif + +typedef union jvalue { + jboolean z; + jbyte b; + jchar c; + jshort s; + jint i; + jlong j; + jfloat f; + jdouble d; + jobject l; +} jvalue; + +struct _jfieldID; +typedef struct _jfieldID *jfieldID; + +struct _jmethodID; +typedef struct _jmethodID *jmethodID; + +/* + * jboolean constants + */ + +#define JNI_FALSE 0 +#define JNI_TRUE 1 + +/* + * possible return values for JNI functions. + */ + +#define JNI_OK 0 /* success */ +#define JNI_ERR (-1) /* unknown error */ +#define JNI_EDETACHED (-2) /* thread detached from the VM */ +#define JNI_EVERSION (-3) /* JNI version error */ +#define JNI_ENOMEM (-4) /* not enough memory */ +#define JNI_EEXIST (-5) /* VM already created */ +#define JNI_EINVAL (-6) /* invalid arguments */ + +/* + * used in ReleaseScalarArrayElements + */ + +#define JNI_COMMIT 1 +#define JNI_ABORT 2 + +/* + * used in RegisterNatives to describe native method name, signature, + * and function pointer. + */ + +typedef struct { + char *name; + char *signature; + void *fnPtr; +} JNINativeMethod; + +/* + * JNI Native Method Interface. + */ + +struct JNINativeInterface_; + +struct JNIEnv_; + +#ifdef __cplusplus +typedef JNIEnv_ JNIEnv; +#else +typedef const struct JNINativeInterface_ *JNIEnv; +#endif + +/* + * JNI Invocation Interface. + */ + +struct JNIInvokeInterface_; + +struct JavaVM_; + +#ifdef __cplusplus +typedef JavaVM_ JavaVM; +#else +typedef const struct JNIInvokeInterface_ *JavaVM; +#endif + +struct JNINativeInterface_ { + void *reserved0; + void *reserved1; + void *reserved2; + + void *reserved3; + jint (JNICALL *GetVersion)(JNIEnv *env); + + jclass (JNICALL *DefineClass) + (JNIEnv *env, const char *name, jobject loader, const jbyte *buf, + jsize len); + jclass (JNICALL *FindClass) + (JNIEnv *env, const char *name); + + jmethodID (JNICALL *FromReflectedMethod) + (JNIEnv *env, jobject method); + jfieldID (JNICALL *FromReflectedField) + (JNIEnv *env, jobject field); + + jobject (JNICALL *ToReflectedMethod) + (JNIEnv *env, jclass cls, jmethodID methodID, jboolean isStatic); + + jclass (JNICALL *GetSuperclass) + (JNIEnv *env, jclass sub); + jboolean (JNICALL *IsAssignableFrom) + (JNIEnv *env, jclass sub, jclass sup); + + jobject (JNICALL *ToReflectedField) + (JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic); + + jint (JNICALL *Throw) + (JNIEnv *env, jthrowable obj); + jint (JNICALL *ThrowNew) + (JNIEnv *env, jclass clazz, const char *msg); + jthrowable (JNICALL *ExceptionOccurred) + (JNIEnv *env); + void (JNICALL *ExceptionDescribe) + (JNIEnv *env); + void (JNICALL *ExceptionClear) + (JNIEnv *env); + void (JNICALL *FatalError) + (JNIEnv *env, const char *msg); + + jint (JNICALL *PushLocalFrame) + (JNIEnv *env, jint capacity); + jobject (JNICALL *PopLocalFrame) + (JNIEnv *env, jobject result); + + jobject (JNICALL *NewGlobalRef) + (JNIEnv *env, jobject lobj); + void (JNICALL *DeleteGlobalRef) + (JNIEnv *env, jobject gref); + void (JNICALL *DeleteLocalRef) + (JNIEnv *env, jobject obj); + jboolean (JNICALL *IsSameObject) + (JNIEnv *env, jobject obj1, jobject obj2); + jobject (JNICALL *NewLocalRef) + (JNIEnv *env, jobject ref); + jint (JNICALL *EnsureLocalCapacity) + (JNIEnv *env, jint capacity); + + jobject (JNICALL *AllocObject) + (JNIEnv *env, jclass clazz); + jobject (JNICALL *NewObject) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *NewObjectV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jobject (JNICALL *NewObjectA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + jclass (JNICALL *GetObjectClass) + (JNIEnv *env, jobject obj); + jboolean (JNICALL *IsInstanceOf) + (JNIEnv *env, jobject obj, jclass clazz); + + jmethodID (JNICALL *GetMethodID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *CallObjectMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jobject (JNICALL *CallObjectMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jobject (JNICALL *CallObjectMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args); + + jboolean (JNICALL *CallBooleanMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jboolean (JNICALL *CallBooleanMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jboolean (JNICALL *CallBooleanMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args); + + jbyte (JNICALL *CallByteMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jbyte (JNICALL *CallByteMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jbyte (JNICALL *CallByteMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); + + jchar (JNICALL *CallCharMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jchar (JNICALL *CallCharMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jchar (JNICALL *CallCharMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); + + jshort (JNICALL *CallShortMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jshort (JNICALL *CallShortMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jshort (JNICALL *CallShortMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); + + jint (JNICALL *CallIntMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jint (JNICALL *CallIntMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jint (JNICALL *CallIntMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); + + jlong (JNICALL *CallLongMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jlong (JNICALL *CallLongMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jlong (JNICALL *CallLongMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); + + jfloat (JNICALL *CallFloatMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jfloat (JNICALL *CallFloatMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jfloat (JNICALL *CallFloatMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); + + jdouble (JNICALL *CallDoubleMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jdouble (JNICALL *CallDoubleMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jdouble (JNICALL *CallDoubleMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); + + void (JNICALL *CallVoidMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + void (JNICALL *CallVoidMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + void (JNICALL *CallVoidMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args); + + jobject (JNICALL *CallNonvirtualObjectMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *CallNonvirtualObjectMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jobject (JNICALL *CallNonvirtualObjectMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue * args); + + jboolean (JNICALL *CallNonvirtualBooleanMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jboolean (JNICALL *CallNonvirtualBooleanMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jboolean (JNICALL *CallNonvirtualBooleanMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue * args); + + jbyte (JNICALL *CallNonvirtualByteMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jbyte (JNICALL *CallNonvirtualByteMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jbyte (JNICALL *CallNonvirtualByteMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args); + + jchar (JNICALL *CallNonvirtualCharMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jchar (JNICALL *CallNonvirtualCharMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jchar (JNICALL *CallNonvirtualCharMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args); + + jshort (JNICALL *CallNonvirtualShortMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jshort (JNICALL *CallNonvirtualShortMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jshort (JNICALL *CallNonvirtualShortMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args); + + jint (JNICALL *CallNonvirtualIntMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jint (JNICALL *CallNonvirtualIntMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jint (JNICALL *CallNonvirtualIntMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args); + + jlong (JNICALL *CallNonvirtualLongMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jlong (JNICALL *CallNonvirtualLongMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jlong (JNICALL *CallNonvirtualLongMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args); + + jfloat (JNICALL *CallNonvirtualFloatMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jfloat (JNICALL *CallNonvirtualFloatMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jfloat (JNICALL *CallNonvirtualFloatMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args); + + jdouble (JNICALL *CallNonvirtualDoubleMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jdouble (JNICALL *CallNonvirtualDoubleMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jdouble (JNICALL *CallNonvirtualDoubleMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args); + + void (JNICALL *CallNonvirtualVoidMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + void (JNICALL *CallNonvirtualVoidMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + void (JNICALL *CallNonvirtualVoidMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue * args); + + jfieldID (JNICALL *GetFieldID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *GetObjectField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jboolean (JNICALL *GetBooleanField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jbyte (JNICALL *GetByteField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jchar (JNICALL *GetCharField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jshort (JNICALL *GetShortField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jint (JNICALL *GetIntField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jlong (JNICALL *GetLongField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jfloat (JNICALL *GetFloatField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jdouble (JNICALL *GetDoubleField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + + void (JNICALL *SetObjectField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val); + void (JNICALL *SetBooleanField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val); + void (JNICALL *SetByteField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val); + void (JNICALL *SetCharField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val); + void (JNICALL *SetShortField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val); + void (JNICALL *SetIntField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jint val); + void (JNICALL *SetLongField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val); + void (JNICALL *SetFloatField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val); + void (JNICALL *SetDoubleField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val); + + jmethodID (JNICALL *GetStaticMethodID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *CallStaticObjectMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *CallStaticObjectMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jobject (JNICALL *CallStaticObjectMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + jboolean (JNICALL *CallStaticBooleanMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jboolean (JNICALL *CallStaticBooleanMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jboolean (JNICALL *CallStaticBooleanMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + jbyte (JNICALL *CallStaticByteMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jbyte (JNICALL *CallStaticByteMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jbyte (JNICALL *CallStaticByteMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + jchar (JNICALL *CallStaticCharMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jchar (JNICALL *CallStaticCharMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jchar (JNICALL *CallStaticCharMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + jshort (JNICALL *CallStaticShortMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jshort (JNICALL *CallStaticShortMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jshort (JNICALL *CallStaticShortMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + jint (JNICALL *CallStaticIntMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jint (JNICALL *CallStaticIntMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jint (JNICALL *CallStaticIntMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + jlong (JNICALL *CallStaticLongMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jlong (JNICALL *CallStaticLongMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jlong (JNICALL *CallStaticLongMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + jfloat (JNICALL *CallStaticFloatMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jfloat (JNICALL *CallStaticFloatMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jfloat (JNICALL *CallStaticFloatMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + jdouble (JNICALL *CallStaticDoubleMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jdouble (JNICALL *CallStaticDoubleMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jdouble (JNICALL *CallStaticDoubleMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + void (JNICALL *CallStaticVoidMethod) + (JNIEnv *env, jclass cls, jmethodID methodID, ...); + void (JNICALL *CallStaticVoidMethodV) + (JNIEnv *env, jclass cls, jmethodID methodID, va_list args); + void (JNICALL *CallStaticVoidMethodA) + (JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args); + + jfieldID (JNICALL *GetStaticFieldID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + jobject (JNICALL *GetStaticObjectField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jboolean (JNICALL *GetStaticBooleanField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jbyte (JNICALL *GetStaticByteField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jchar (JNICALL *GetStaticCharField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jshort (JNICALL *GetStaticShortField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jint (JNICALL *GetStaticIntField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jlong (JNICALL *GetStaticLongField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jfloat (JNICALL *GetStaticFloatField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jdouble (JNICALL *GetStaticDoubleField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + + void (JNICALL *SetStaticObjectField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value); + void (JNICALL *SetStaticBooleanField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value); + void (JNICALL *SetStaticByteField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value); + void (JNICALL *SetStaticCharField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value); + void (JNICALL *SetStaticShortField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value); + void (JNICALL *SetStaticIntField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value); + void (JNICALL *SetStaticLongField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value); + void (JNICALL *SetStaticFloatField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value); + void (JNICALL *SetStaticDoubleField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value); + + jstring (JNICALL *NewString) + (JNIEnv *env, const jchar *unicode, jsize len); + jsize (JNICALL *GetStringLength) + (JNIEnv *env, jstring str); + const jchar *(JNICALL *GetStringChars) + (JNIEnv *env, jstring str, jboolean *isCopy); + void (JNICALL *ReleaseStringChars) + (JNIEnv *env, jstring str, const jchar *chars); + + jstring (JNICALL *NewStringUTF) + (JNIEnv *env, const char *utf); + jsize (JNICALL *GetStringUTFLength) + (JNIEnv *env, jstring str); + const char* (JNICALL *GetStringUTFChars) + (JNIEnv *env, jstring str, jboolean *isCopy); + void (JNICALL *ReleaseStringUTFChars) + (JNIEnv *env, jstring str, const char* chars); + + + jsize (JNICALL *GetArrayLength) + (JNIEnv *env, jarray array); + + jobjectArray (JNICALL *NewObjectArray) + (JNIEnv *env, jsize len, jclass clazz, jobject init); + jobject (JNICALL *GetObjectArrayElement) + (JNIEnv *env, jobjectArray array, jsize index); + void (JNICALL *SetObjectArrayElement) + (JNIEnv *env, jobjectArray array, jsize index, jobject val); + + jbooleanArray (JNICALL *NewBooleanArray) + (JNIEnv *env, jsize len); + jbyteArray (JNICALL *NewByteArray) + (JNIEnv *env, jsize len); + jcharArray (JNICALL *NewCharArray) + (JNIEnv *env, jsize len); + jshortArray (JNICALL *NewShortArray) + (JNIEnv *env, jsize len); + jintArray (JNICALL *NewIntArray) + (JNIEnv *env, jsize len); + jlongArray (JNICALL *NewLongArray) + (JNIEnv *env, jsize len); + jfloatArray (JNICALL *NewFloatArray) + (JNIEnv *env, jsize len); + jdoubleArray (JNICALL *NewDoubleArray) + (JNIEnv *env, jsize len); + + jboolean * (JNICALL *GetBooleanArrayElements) + (JNIEnv *env, jbooleanArray array, jboolean *isCopy); + jbyte * (JNICALL *GetByteArrayElements) + (JNIEnv *env, jbyteArray array, jboolean *isCopy); + jchar * (JNICALL *GetCharArrayElements) + (JNIEnv *env, jcharArray array, jboolean *isCopy); + jshort * (JNICALL *GetShortArrayElements) + (JNIEnv *env, jshortArray array, jboolean *isCopy); + jint * (JNICALL *GetIntArrayElements) + (JNIEnv *env, jintArray array, jboolean *isCopy); + jlong * (JNICALL *GetLongArrayElements) + (JNIEnv *env, jlongArray array, jboolean *isCopy); + jfloat * (JNICALL *GetFloatArrayElements) + (JNIEnv *env, jfloatArray array, jboolean *isCopy); + jdouble * (JNICALL *GetDoubleArrayElements) + (JNIEnv *env, jdoubleArray array, jboolean *isCopy); + + void (JNICALL *ReleaseBooleanArrayElements) + (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode); + void (JNICALL *ReleaseByteArrayElements) + (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode); + void (JNICALL *ReleaseCharArrayElements) + (JNIEnv *env, jcharArray array, jchar *elems, jint mode); + void (JNICALL *ReleaseShortArrayElements) + (JNIEnv *env, jshortArray array, jshort *elems, jint mode); + void (JNICALL *ReleaseIntArrayElements) + (JNIEnv *env, jintArray array, jint *elems, jint mode); + void (JNICALL *ReleaseLongArrayElements) + (JNIEnv *env, jlongArray array, jlong *elems, jint mode); + void (JNICALL *ReleaseFloatArrayElements) + (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode); + void (JNICALL *ReleaseDoubleArrayElements) + (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode); + + void (JNICALL *GetBooleanArrayRegion) + (JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf); + void (JNICALL *GetByteArrayRegion) + (JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf); + void (JNICALL *GetCharArrayRegion) + (JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf); + void (JNICALL *GetShortArrayRegion) + (JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf); + void (JNICALL *GetIntArrayRegion) + (JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf); + void (JNICALL *GetLongArrayRegion) + (JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf); + void (JNICALL *GetFloatArrayRegion) + (JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf); + void (JNICALL *GetDoubleArrayRegion) + (JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf); + + void (JNICALL *SetBooleanArrayRegion) + (JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf); + void (JNICALL *SetByteArrayRegion) + (JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf); + void (JNICALL *SetCharArrayRegion) + (JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf); + void (JNICALL *SetShortArrayRegion) + (JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf); + void (JNICALL *SetIntArrayRegion) + (JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf); + void (JNICALL *SetLongArrayRegion) + (JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf); + void (JNICALL *SetFloatArrayRegion) + (JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf); + void (JNICALL *SetDoubleArrayRegion) + (JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf); + + jint (JNICALL *RegisterNatives) + (JNIEnv *env, jclass clazz, const JNINativeMethod *methods, + jint nMethods); + jint (JNICALL *UnregisterNatives) + (JNIEnv *env, jclass clazz); + + jint (JNICALL *MonitorEnter) + (JNIEnv *env, jobject obj); + jint (JNICALL *MonitorExit) + (JNIEnv *env, jobject obj); + + jint (JNICALL *GetJavaVM) + (JNIEnv *env, JavaVM **vm); + + void (JNICALL *GetStringRegion) + (JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf); + void (JNICALL *GetStringUTFRegion) + (JNIEnv *env, jstring str, jsize start, jsize len, char *buf); + + void * (JNICALL *GetPrimitiveArrayCritical) + (JNIEnv *env, jarray array, jboolean *isCopy); + void (JNICALL *ReleasePrimitiveArrayCritical) + (JNIEnv *env, jarray array, void *carray, jint mode); + + const jchar * (JNICALL *GetStringCritical) + (JNIEnv *env, jstring string, jboolean *isCopy); + void (JNICALL *ReleaseStringCritical) + (JNIEnv *env, jstring string, const jchar *cstring); + + jweak (JNICALL *NewWeakGlobalRef) + (JNIEnv *env, jobject obj); + void (JNICALL *DeleteWeakGlobalRef) + (JNIEnv *env, jweak ref); + + jboolean (JNICALL *ExceptionCheck) + (JNIEnv *env); + + jobject (JNICALL *NewDirectByteBuffer) + (JNIEnv* env, void* address, jlong capacity); + void* (JNICALL *GetDirectBufferAddress) + (JNIEnv* env, jobject buf); + jlong (JNICALL *GetDirectBufferCapacity) + (JNIEnv* env, jobject buf); +}; + +/* + * We use inlined functions for C++ so that programmers can write: + * + * env->FindClass("java/lang/String") + * + * in C++ rather than: + * + * (*env)->FindClass(env, "java/lang/String") + * + * in C. + */ + +struct JNIEnv_ { + const struct JNINativeInterface_ *functions; +#ifdef __cplusplus + + jint GetVersion() { + return functions->GetVersion(this); + } + jclass DefineClass(const char *name, jobject loader, const jbyte *buf, + jsize len) { + return functions->DefineClass(this, name, loader, buf, len); + } + jclass FindClass(const char *name) { + return functions->FindClass(this, name); + } + jmethodID FromReflectedMethod(jobject method) { + return functions->FromReflectedMethod(this,method); + } + jfieldID FromReflectedField(jobject field) { + return functions->FromReflectedField(this,field); + } + + jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic) { + return functions->ToReflectedMethod(this, cls, methodID, isStatic); + } + + jclass GetSuperclass(jclass sub) { + return functions->GetSuperclass(this, sub); + } + jboolean IsAssignableFrom(jclass sub, jclass sup) { + return functions->IsAssignableFrom(this, sub, sup); + } + + jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic) { + return functions->ToReflectedField(this,cls,fieldID,isStatic); + } + + jint Throw(jthrowable obj) { + return functions->Throw(this, obj); + } + jint ThrowNew(jclass clazz, const char *msg) { + return functions->ThrowNew(this, clazz, msg); + } + jthrowable ExceptionOccurred() { + return functions->ExceptionOccurred(this); + } + void ExceptionDescribe() { + functions->ExceptionDescribe(this); + } + void ExceptionClear() { + functions->ExceptionClear(this); + } + void FatalError(const char *msg) { + functions->FatalError(this, msg); + } + + jint PushLocalFrame(jint capacity) { + return functions->PushLocalFrame(this,capacity); + } + jobject PopLocalFrame(jobject result) { + return functions->PopLocalFrame(this,result); + } + + jobject NewGlobalRef(jobject lobj) { + return functions->NewGlobalRef(this,lobj); + } + void DeleteGlobalRef(jobject gref) { + functions->DeleteGlobalRef(this,gref); + } + void DeleteLocalRef(jobject obj) { + functions->DeleteLocalRef(this, obj); + } + + jboolean IsSameObject(jobject obj1, jobject obj2) { + return functions->IsSameObject(this,obj1,obj2); + } + + jobject NewLocalRef(jobject ref) { + return functions->NewLocalRef(this,ref); + } + jint EnsureLocalCapacity(jint capacity) { + return functions->EnsureLocalCapacity(this,capacity); + } + + jobject AllocObject(jclass clazz) { + return functions->AllocObject(this,clazz); + } + jobject NewObject(jclass clazz, jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args, methodID); + result = functions->NewObjectV(this,clazz,methodID,args); + va_end(args); + return result; + } + jobject NewObjectV(jclass clazz, jmethodID methodID, + va_list args) { + return functions->NewObjectV(this,clazz,methodID,args); + } + jobject NewObjectA(jclass clazz, jmethodID methodID, + jvalue *args) { + return functions->NewObjectA(this,clazz,methodID,args); + } + + jclass GetObjectClass(jobject obj) { + return functions->GetObjectClass(this,obj); + } + jboolean IsInstanceOf(jobject obj, jclass clazz) { + return functions->IsInstanceOf(this,obj,clazz); + } + + jmethodID GetMethodID(jclass clazz, const char *name, + const char *sig) { + return functions->GetMethodID(this,clazz,name,sig); + } + + jobject CallObjectMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallObjectMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jobject CallObjectMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallObjectMethodV(this,obj,methodID,args); + } + jobject CallObjectMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallObjectMethodA(this,obj,methodID,args); + } + + jboolean CallBooleanMethod(jobject obj, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallBooleanMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jboolean CallBooleanMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallBooleanMethodV(this,obj,methodID,args); + } + jboolean CallBooleanMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallBooleanMethodA(this,obj,methodID, args); + } + + jbyte CallByteMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallByteMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jbyte CallByteMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallByteMethodV(this,obj,methodID,args); + } + jbyte CallByteMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallByteMethodA(this,obj,methodID,args); + } + + jchar CallCharMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallCharMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jchar CallCharMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallCharMethodV(this,obj,methodID,args); + } + jchar CallCharMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallCharMethodA(this,obj,methodID,args); + } + + jshort CallShortMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallShortMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jshort CallShortMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallShortMethodV(this,obj,methodID,args); + } + jshort CallShortMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallShortMethodA(this,obj,methodID,args); + } + + jint CallIntMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallIntMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jint CallIntMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallIntMethodV(this,obj,methodID,args); + } + jint CallIntMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallIntMethodA(this,obj,methodID,args); + } + + jlong CallLongMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallLongMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jlong CallLongMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallLongMethodV(this,obj,methodID,args); + } + jlong CallLongMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallLongMethodA(this,obj,methodID,args); + } + + jfloat CallFloatMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallFloatMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jfloat CallFloatMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallFloatMethodV(this,obj,methodID,args); + } + jfloat CallFloatMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallFloatMethodA(this,obj,methodID,args); + } + + jdouble CallDoubleMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallDoubleMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jdouble CallDoubleMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallDoubleMethodV(this,obj,methodID,args); + } + jdouble CallDoubleMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallDoubleMethodA(this,obj,methodID,args); + } + + void CallVoidMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallVoidMethodV(this,obj,methodID,args); + va_end(args); + } + void CallVoidMethodV(jobject obj, jmethodID methodID, + va_list args) { + functions->CallVoidMethodV(this,obj,methodID,args); + } + void CallVoidMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + functions->CallVoidMethodA(this,obj,methodID,args); + } + + jobject CallNonvirtualObjectMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallNonvirtualObjectMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jobject CallNonvirtualObjectMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualObjectMethodV(this,obj,clazz, + methodID,args); + } + jobject CallNonvirtualObjectMethodA(jobject obj, jclass clazz, + jmethodID methodID, jvalue * args) { + return functions->CallNonvirtualObjectMethodA(this,obj,clazz, + methodID,args); + } + + jboolean CallNonvirtualBooleanMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallNonvirtualBooleanMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jboolean CallNonvirtualBooleanMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualBooleanMethodV(this,obj,clazz, + methodID,args); + } + jboolean CallNonvirtualBooleanMethodA(jobject obj, jclass clazz, + jmethodID methodID, jvalue * args) { + return functions->CallNonvirtualBooleanMethodA(this,obj,clazz, + methodID, args); + } + + jbyte CallNonvirtualByteMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallNonvirtualByteMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jbyte CallNonvirtualByteMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualByteMethodV(this,obj,clazz, + methodID,args); + } + jbyte CallNonvirtualByteMethodA(jobject obj, jclass clazz, + jmethodID methodID, jvalue * args) { + return functions->CallNonvirtualByteMethodA(this,obj,clazz, + methodID,args); + } + + jchar CallNonvirtualCharMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallNonvirtualCharMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jchar CallNonvirtualCharMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualCharMethodV(this,obj,clazz, + methodID,args); + } + jchar CallNonvirtualCharMethodA(jobject obj, jclass clazz, + jmethodID methodID, jvalue * args) { + return functions->CallNonvirtualCharMethodA(this,obj,clazz, + methodID,args); + } + + jshort CallNonvirtualShortMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallNonvirtualShortMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jshort CallNonvirtualShortMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualShortMethodV(this,obj,clazz, + methodID,args); + } + jshort CallNonvirtualShortMethodA(jobject obj, jclass clazz, + jmethodID methodID, jvalue * args) { + return functions->CallNonvirtualShortMethodA(this,obj,clazz, + methodID,args); + } + + jint CallNonvirtualIntMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallNonvirtualIntMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jint CallNonvirtualIntMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualIntMethodV(this,obj,clazz, + methodID,args); + } + jint CallNonvirtualIntMethodA(jobject obj, jclass clazz, + jmethodID methodID, jvalue * args) { + return functions->CallNonvirtualIntMethodA(this,obj,clazz, + methodID,args); + } + + jlong CallNonvirtualLongMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallNonvirtualLongMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jlong CallNonvirtualLongMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualLongMethodV(this,obj,clazz, + methodID,args); + } + jlong CallNonvirtualLongMethodA(jobject obj, jclass clazz, + jmethodID methodID, jvalue * args) { + return functions->CallNonvirtualLongMethodA(this,obj,clazz, + methodID,args); + } + + jfloat CallNonvirtualFloatMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallNonvirtualFloatMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jfloat CallNonvirtualFloatMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + return functions->CallNonvirtualFloatMethodV(this,obj,clazz, + methodID,args); + } + jfloat CallNonvirtualFloatMethodA(jobject obj, jclass clazz, + jmethodID methodID, + jvalue * args) { + return functions->CallNonvirtualFloatMethodA(this,obj,clazz, + methodID,args); + } + + jdouble CallNonvirtualDoubleMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallNonvirtualDoubleMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jdouble CallNonvirtualDoubleMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + return functions->CallNonvirtualDoubleMethodV(this,obj,clazz, + methodID,args); + } + jdouble CallNonvirtualDoubleMethodA(jobject obj, jclass clazz, + jmethodID methodID, + jvalue * args) { + return functions->CallNonvirtualDoubleMethodA(this,obj,clazz, + methodID,args); + } + + void CallNonvirtualVoidMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args); + va_end(args); + } + void CallNonvirtualVoidMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args); + } + void CallNonvirtualVoidMethodA(jobject obj, jclass clazz, + jmethodID methodID, + jvalue * args) { + functions->CallNonvirtualVoidMethodA(this,obj,clazz,methodID,args); + } + + jfieldID GetFieldID(jclass clazz, const char *name, + const char *sig) { + return functions->GetFieldID(this,clazz,name,sig); + } + + jobject GetObjectField(jobject obj, jfieldID fieldID) { + return functions->GetObjectField(this,obj,fieldID); + } + jboolean GetBooleanField(jobject obj, jfieldID fieldID) { + return functions->GetBooleanField(this,obj,fieldID); + } + jbyte GetByteField(jobject obj, jfieldID fieldID) { + return functions->GetByteField(this,obj,fieldID); + } + jchar GetCharField(jobject obj, jfieldID fieldID) { + return functions->GetCharField(this,obj,fieldID); + } + jshort GetShortField(jobject obj, jfieldID fieldID) { + return functions->GetShortField(this,obj,fieldID); + } + jint GetIntField(jobject obj, jfieldID fieldID) { + return functions->GetIntField(this,obj,fieldID); + } + jlong GetLongField(jobject obj, jfieldID fieldID) { + return functions->GetLongField(this,obj,fieldID); + } + jfloat GetFloatField(jobject obj, jfieldID fieldID) { + return functions->GetFloatField(this,obj,fieldID); + } + jdouble GetDoubleField(jobject obj, jfieldID fieldID) { + return functions->GetDoubleField(this,obj,fieldID); + } + + void SetObjectField(jobject obj, jfieldID fieldID, jobject val) { + functions->SetObjectField(this,obj,fieldID,val); + } + void SetBooleanField(jobject obj, jfieldID fieldID, + jboolean val) { + functions->SetBooleanField(this,obj,fieldID,val); + } + void SetByteField(jobject obj, jfieldID fieldID, + jbyte val) { + functions->SetByteField(this,obj,fieldID,val); + } + void SetCharField(jobject obj, jfieldID fieldID, + jchar val) { + functions->SetCharField(this,obj,fieldID,val); + } + void SetShortField(jobject obj, jfieldID fieldID, + jshort val) { + functions->SetShortField(this,obj,fieldID,val); + } + void SetIntField(jobject obj, jfieldID fieldID, + jint val) { + functions->SetIntField(this,obj,fieldID,val); + } + void SetLongField(jobject obj, jfieldID fieldID, + jlong val) { + functions->SetLongField(this,obj,fieldID,val); + } + void SetFloatField(jobject obj, jfieldID fieldID, + jfloat val) { + functions->SetFloatField(this,obj,fieldID,val); + } + void SetDoubleField(jobject obj, jfieldID fieldID, + jdouble val) { + functions->SetDoubleField(this,obj,fieldID,val); + } + + jmethodID GetStaticMethodID(jclass clazz, const char *name, + const char *sig) { + return functions->GetStaticMethodID(this,clazz,name,sig); + } + + jobject CallStaticObjectMethod(jclass clazz, jmethodID methodID, + ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallStaticObjectMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jobject CallStaticObjectMethodV(jclass clazz, jmethodID methodID, + va_list args) { + return functions->CallStaticObjectMethodV(this,clazz,methodID,args); + } + jobject CallStaticObjectMethodA(jclass clazz, jmethodID methodID, + jvalue *args) { + return functions->CallStaticObjectMethodA(this,clazz,methodID,args); + } + + jboolean CallStaticBooleanMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallStaticBooleanMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jboolean CallStaticBooleanMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticBooleanMethodV(this,clazz,methodID,args); + } + jboolean CallStaticBooleanMethodA(jclass clazz, + jmethodID methodID, jvalue *args) { + return functions->CallStaticBooleanMethodA(this,clazz,methodID,args); + } + + jbyte CallStaticByteMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallStaticByteMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jbyte CallStaticByteMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticByteMethodV(this,clazz,methodID,args); + } + jbyte CallStaticByteMethodA(jclass clazz, + jmethodID methodID, jvalue *args) { + return functions->CallStaticByteMethodA(this,clazz,methodID,args); + } + + jchar CallStaticCharMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallStaticCharMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jchar CallStaticCharMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticCharMethodV(this,clazz,methodID,args); + } + jchar CallStaticCharMethodA(jclass clazz, + jmethodID methodID, jvalue *args) { + return functions->CallStaticCharMethodA(this,clazz,methodID,args); + } + + jshort CallStaticShortMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallStaticShortMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jshort CallStaticShortMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticShortMethodV(this,clazz,methodID,args); + } + jshort CallStaticShortMethodA(jclass clazz, + jmethodID methodID, jvalue *args) { + return functions->CallStaticShortMethodA(this,clazz,methodID,args); + } + + jint CallStaticIntMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallStaticIntMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jint CallStaticIntMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticIntMethodV(this,clazz,methodID,args); + } + jint CallStaticIntMethodA(jclass clazz, + jmethodID methodID, jvalue *args) { + return functions->CallStaticIntMethodA(this,clazz,methodID,args); + } + + jlong CallStaticLongMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallStaticLongMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jlong CallStaticLongMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticLongMethodV(this,clazz,methodID,args); + } + jlong CallStaticLongMethodA(jclass clazz, + jmethodID methodID, jvalue *args) { + return functions->CallStaticLongMethodA(this,clazz,methodID,args); + } + + jfloat CallStaticFloatMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallStaticFloatMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jfloat CallStaticFloatMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticFloatMethodV(this,clazz,methodID,args); + } + jfloat CallStaticFloatMethodA(jclass clazz, + jmethodID methodID, jvalue *args) { + return functions->CallStaticFloatMethodA(this,clazz,methodID,args); + } + + jdouble CallStaticDoubleMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallStaticDoubleMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jdouble CallStaticDoubleMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticDoubleMethodV(this,clazz,methodID,args); + } + jdouble CallStaticDoubleMethodA(jclass clazz, + jmethodID methodID, jvalue *args) { + return functions->CallStaticDoubleMethodA(this,clazz,methodID,args); + } + + void CallStaticVoidMethod(jclass cls, jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallStaticVoidMethodV(this,cls,methodID,args); + va_end(args); + } + void CallStaticVoidMethodV(jclass cls, jmethodID methodID, + va_list args) { + functions->CallStaticVoidMethodV(this,cls,methodID,args); + } + void CallStaticVoidMethodA(jclass cls, jmethodID methodID, + jvalue * args) { + functions->CallStaticVoidMethodA(this,cls,methodID,args); + } + + jfieldID GetStaticFieldID(jclass clazz, const char *name, + const char *sig) { + return functions->GetStaticFieldID(this,clazz,name,sig); + } + jobject GetStaticObjectField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticObjectField(this,clazz,fieldID); + } + jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticBooleanField(this,clazz,fieldID); + } + jbyte GetStaticByteField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticByteField(this,clazz,fieldID); + } + jchar GetStaticCharField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticCharField(this,clazz,fieldID); + } + jshort GetStaticShortField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticShortField(this,clazz,fieldID); + } + jint GetStaticIntField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticIntField(this,clazz,fieldID); + } + jlong GetStaticLongField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticLongField(this,clazz,fieldID); + } + jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticFloatField(this,clazz,fieldID); + } + jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticDoubleField(this,clazz,fieldID); + } + + void SetStaticObjectField(jclass clazz, jfieldID fieldID, + jobject value) { + functions->SetStaticObjectField(this,clazz,fieldID,value); + } + void SetStaticBooleanField(jclass clazz, jfieldID fieldID, + jboolean value) { + functions->SetStaticBooleanField(this,clazz,fieldID,value); + } + void SetStaticByteField(jclass clazz, jfieldID fieldID, + jbyte value) { + functions->SetStaticByteField(this,clazz,fieldID,value); + } + void SetStaticCharField(jclass clazz, jfieldID fieldID, + jchar value) { + functions->SetStaticCharField(this,clazz,fieldID,value); + } + void SetStaticShortField(jclass clazz, jfieldID fieldID, + jshort value) { + functions->SetStaticShortField(this,clazz,fieldID,value); + } + void SetStaticIntField(jclass clazz, jfieldID fieldID, + jint value) { + functions->SetStaticIntField(this,clazz,fieldID,value); + } + void SetStaticLongField(jclass clazz, jfieldID fieldID, + jlong value) { + functions->SetStaticLongField(this,clazz,fieldID,value); + } + void SetStaticFloatField(jclass clazz, jfieldID fieldID, + jfloat value) { + functions->SetStaticFloatField(this,clazz,fieldID,value); + } + void SetStaticDoubleField(jclass clazz, jfieldID fieldID, + jdouble value) { + functions->SetStaticDoubleField(this,clazz,fieldID,value); + } + + jstring NewString(const jchar *unicode, jsize len) { + return functions->NewString(this,unicode,len); + } + jsize GetStringLength(jstring str) { + return functions->GetStringLength(this,str); + } + const jchar *GetStringChars(jstring str, jboolean *isCopy) { + return functions->GetStringChars(this,str,isCopy); + } + void ReleaseStringChars(jstring str, const jchar *chars) { + functions->ReleaseStringChars(this,str,chars); + } + + jstring NewStringUTF(const char *utf) { + return functions->NewStringUTF(this,utf); + } + jsize GetStringUTFLength(jstring str) { + return functions->GetStringUTFLength(this,str); + } + const char* GetStringUTFChars(jstring str, jboolean *isCopy) { + return functions->GetStringUTFChars(this,str,isCopy); + } + void ReleaseStringUTFChars(jstring str, const char* chars) { + functions->ReleaseStringUTFChars(this,str,chars); + } + + jsize GetArrayLength(jarray array) { + return functions->GetArrayLength(this,array); + } + + jobjectArray NewObjectArray(jsize len, jclass clazz, + jobject init) { + return functions->NewObjectArray(this,len,clazz,init); + } + jobject GetObjectArrayElement(jobjectArray array, jsize index) { + return functions->GetObjectArrayElement(this,array,index); + } + void SetObjectArrayElement(jobjectArray array, jsize index, + jobject val) { + functions->SetObjectArrayElement(this,array,index,val); + } + + jbooleanArray NewBooleanArray(jsize len) { + return functions->NewBooleanArray(this,len); + } + jbyteArray NewByteArray(jsize len) { + return functions->NewByteArray(this,len); + } + jcharArray NewCharArray(jsize len) { + return functions->NewCharArray(this,len); + } + jshortArray NewShortArray(jsize len) { + return functions->NewShortArray(this,len); + } + jintArray NewIntArray(jsize len) { + return functions->NewIntArray(this,len); + } + jlongArray NewLongArray(jsize len) { + return functions->NewLongArray(this,len); + } + jfloatArray NewFloatArray(jsize len) { + return functions->NewFloatArray(this,len); + } + jdoubleArray NewDoubleArray(jsize len) { + return functions->NewDoubleArray(this,len); + } + + jboolean * GetBooleanArrayElements(jbooleanArray array, jboolean *isCopy) { + return functions->GetBooleanArrayElements(this,array,isCopy); + } + jbyte * GetByteArrayElements(jbyteArray array, jboolean *isCopy) { + return functions->GetByteArrayElements(this,array,isCopy); + } + jchar * GetCharArrayElements(jcharArray array, jboolean *isCopy) { + return functions->GetCharArrayElements(this,array,isCopy); + } + jshort * GetShortArrayElements(jshortArray array, jboolean *isCopy) { + return functions->GetShortArrayElements(this,array,isCopy); + } + jint * GetIntArrayElements(jintArray array, jboolean *isCopy) { + return functions->GetIntArrayElements(this,array,isCopy); + } + jlong * GetLongArrayElements(jlongArray array, jboolean *isCopy) { + return functions->GetLongArrayElements(this,array,isCopy); + } + jfloat * GetFloatArrayElements(jfloatArray array, jboolean *isCopy) { + return functions->GetFloatArrayElements(this,array,isCopy); + } + jdouble * GetDoubleArrayElements(jdoubleArray array, jboolean *isCopy) { + return functions->GetDoubleArrayElements(this,array,isCopy); + } + + void ReleaseBooleanArrayElements(jbooleanArray array, + jboolean *elems, + jint mode) { + functions->ReleaseBooleanArrayElements(this,array,elems,mode); + } + void ReleaseByteArrayElements(jbyteArray array, + jbyte *elems, + jint mode) { + functions->ReleaseByteArrayElements(this,array,elems,mode); + } + void ReleaseCharArrayElements(jcharArray array, + jchar *elems, + jint mode) { + functions->ReleaseCharArrayElements(this,array,elems,mode); + } + void ReleaseShortArrayElements(jshortArray array, + jshort *elems, + jint mode) { + functions->ReleaseShortArrayElements(this,array,elems,mode); + } + void ReleaseIntArrayElements(jintArray array, + jint *elems, + jint mode) { + functions->ReleaseIntArrayElements(this,array,elems,mode); + } + void ReleaseLongArrayElements(jlongArray array, + jlong *elems, + jint mode) { + functions->ReleaseLongArrayElements(this,array,elems,mode); + } + void ReleaseFloatArrayElements(jfloatArray array, + jfloat *elems, + jint mode) { + functions->ReleaseFloatArrayElements(this,array,elems,mode); + } + void ReleaseDoubleArrayElements(jdoubleArray array, + jdouble *elems, + jint mode) { + functions->ReleaseDoubleArrayElements(this,array,elems,mode); + } + + void GetBooleanArrayRegion(jbooleanArray array, + jsize start, jsize len, jboolean *buf) { + functions->GetBooleanArrayRegion(this,array,start,len,buf); + } + void GetByteArrayRegion(jbyteArray array, + jsize start, jsize len, jbyte *buf) { + functions->GetByteArrayRegion(this,array,start,len,buf); + } + void GetCharArrayRegion(jcharArray array, + jsize start, jsize len, jchar *buf) { + functions->GetCharArrayRegion(this,array,start,len,buf); + } + void GetShortArrayRegion(jshortArray array, + jsize start, jsize len, jshort *buf) { + functions->GetShortArrayRegion(this,array,start,len,buf); + } + void GetIntArrayRegion(jintArray array, + jsize start, jsize len, jint *buf) { + functions->GetIntArrayRegion(this,array,start,len,buf); + } + void GetLongArrayRegion(jlongArray array, + jsize start, jsize len, jlong *buf) { + functions->GetLongArrayRegion(this,array,start,len,buf); + } + void GetFloatArrayRegion(jfloatArray array, + jsize start, jsize len, jfloat *buf) { + functions->GetFloatArrayRegion(this,array,start,len,buf); + } + void GetDoubleArrayRegion(jdoubleArray array, + jsize start, jsize len, jdouble *buf) { + functions->GetDoubleArrayRegion(this,array,start,len,buf); + } + + void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, + jboolean *buf) { + functions->SetBooleanArrayRegion(this,array,start,len,buf); + } + void SetByteArrayRegion(jbyteArray array, jsize start, jsize len, + jbyte *buf) { + functions->SetByteArrayRegion(this,array,start,len,buf); + } + void SetCharArrayRegion(jcharArray array, jsize start, jsize len, + jchar *buf) { + functions->SetCharArrayRegion(this,array,start,len,buf); + } + void SetShortArrayRegion(jshortArray array, jsize start, jsize len, + jshort *buf) { + functions->SetShortArrayRegion(this,array,start,len,buf); + } + void SetIntArrayRegion(jintArray array, jsize start, jsize len, + jint *buf) { + functions->SetIntArrayRegion(this,array,start,len,buf); + } + void SetLongArrayRegion(jlongArray array, jsize start, jsize len, + jlong *buf) { + functions->SetLongArrayRegion(this,array,start,len,buf); + } + void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len, + jfloat *buf) { + functions->SetFloatArrayRegion(this,array,start,len,buf); + } + void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, + jdouble *buf) { + functions->SetDoubleArrayRegion(this,array,start,len,buf); + } + + jint RegisterNatives(jclass clazz, const JNINativeMethod *methods, + jint nMethods) { + return functions->RegisterNatives(this,clazz,methods,nMethods); + } + jint UnregisterNatives(jclass clazz) { + return functions->UnregisterNatives(this,clazz); + } + + jint MonitorEnter(jobject obj) { + return functions->MonitorEnter(this,obj); + } + jint MonitorExit(jobject obj) { + return functions->MonitorExit(this,obj); + } + + jint GetJavaVM(JavaVM **vm) { + return functions->GetJavaVM(this,vm); + } + + void GetStringRegion(jstring str, jsize start, jsize len, jchar *buf) { + functions->GetStringRegion(this,str,start,len,buf); + } + void GetStringUTFRegion(jstring str, jsize start, jsize len, char *buf) { + functions->GetStringUTFRegion(this,str,start,len,buf); + } + + void * GetPrimitiveArrayCritical(jarray array, jboolean *isCopy) { + return functions->GetPrimitiveArrayCritical(this,array,isCopy); + } + void ReleasePrimitiveArrayCritical(jarray array, void *carray, jint mode) { + functions->ReleasePrimitiveArrayCritical(this,array,carray,mode); + } + + const jchar * GetStringCritical(jstring string, jboolean *isCopy) { + return functions->GetStringCritical(this,string,isCopy); + } + void ReleaseStringCritical(jstring string, const jchar *cstring) { + functions->ReleaseStringCritical(this,string,cstring); + } + + jweak NewWeakGlobalRef(jobject obj) { + return functions->NewWeakGlobalRef(this,obj); + } + void DeleteWeakGlobalRef(jweak ref) { + functions->DeleteWeakGlobalRef(this,ref); + } + + jboolean ExceptionCheck() { + return functions->ExceptionCheck(this); + } + + jobject NewDirectByteBuffer(void* address, jlong capacity) { + return functions->NewDirectByteBuffer(this, address, capacity); + } + void* GetDirectBufferAddress(jobject buf) { + return functions->GetDirectBufferAddress(this, buf); + } + jlong GetDirectBufferCapacity(jobject buf) { + return functions->GetDirectBufferCapacity(this, buf); + } + +#endif /* __cplusplus */ +}; + +typedef struct JavaVMOption { + char *optionString; + void *extraInfo; +} JavaVMOption; + +typedef struct JavaVMInitArgs { + jint version; + + jint nOptions; + JavaVMOption *options; + jboolean ignoreUnrecognized; +} JavaVMInitArgs; + +typedef struct JavaVMAttachArgs { + jint version; + + char *name; + jobject group; +} JavaVMAttachArgs; + +/* These structures will be VM-specific. */ + +typedef struct JDK1_1InitArgs { + jint version; + + char **properties; + jint checkSource; + jint nativeStackSize; + jint javaStackSize; + jint minHeapSize; + jint maxHeapSize; + jint verifyMode; + char *classpath; + + jint (JNICALL *vfprintf)(FILE *fp, const char *format, va_list args); + void (JNICALL *exit)(jint code); + void (JNICALL *abort)(void); + + jint enableClassGC; + jint enableVerboseGC; + jint disableAsyncGC; + jint verbose; + jboolean debugging; + jint debugPort; +} JDK1_1InitArgs; + +typedef struct JDK1_1AttachArgs { + void * __padding; /* C compilers don't allow empty structures. */ +} JDK1_1AttachArgs; + +#define JDK1_2 +#define JDK1_4 + +/* End VM-specific. */ + +struct JNIInvokeInterface_ { + void *reserved0; + void *reserved1; + void *reserved2; + + jint (JNICALL *DestroyJavaVM)(JavaVM *vm); + + jint (JNICALL *AttachCurrentThread)(JavaVM *vm, void **penv, void *args); + + jint (JNICALL *DetachCurrentThread)(JavaVM *vm); + + jint (JNICALL *GetEnv)(JavaVM *vm, void **penv, jint version); + + jint (JNICALL *AttachCurrentThreadAsDaemon)(JavaVM *vm, void **penv, void *args); +}; + +struct JavaVM_ { + const struct JNIInvokeInterface_ *functions; +#ifdef __cplusplus + + jint DestroyJavaVM() { + return functions->DestroyJavaVM(this); + } + jint AttachCurrentThread(void **penv, void *args) { + return functions->AttachCurrentThread(this, penv, args); + } + jint DetachCurrentThread() { + return functions->DetachCurrentThread(this); + } + + jint GetEnv(void **penv, jint version) { + return functions->GetEnv(this, penv, version); + } + jint AttachCurrentThreadAsDaemon(void **penv, void *args) { + return functions->AttachCurrentThreadAsDaemon(this, penv, args); + } +#endif +}; + +#ifdef _JNI_IMPLEMENTATION_ +#define _JNI_IMPORT_OR_EXPORT_ JNIEXPORT +#else +#define _JNI_IMPORT_OR_EXPORT_ JNIIMPORT +#endif +_JNI_IMPORT_OR_EXPORT_ jint JNICALL +JNI_GetDefaultJavaVMInitArgs(void *args); + +_JNI_IMPORT_OR_EXPORT_ jint JNICALL +JNI_CreateJavaVM(JavaVM **pvm, void **penv, void *args); + +_JNI_IMPORT_OR_EXPORT_ jint JNICALL +JNI_GetCreatedJavaVMs(JavaVM **, jsize, jsize *); + +/* Defined by native libraries. */ +JNIEXPORT jint JNICALL +JNI_OnLoad(JavaVM *vm, void *reserved); + +JNIEXPORT void JNICALL +JNI_OnUnload(JavaVM *vm, void *reserved); + +#define JNI_VERSION_1_1 0x00010001 +#define JNI_VERSION_1_2 0x00010002 +#define JNI_VERSION_1_4 0x00010004 + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* JNI_H */ + + diff --git a/Templates/Empty/web/source/npplugin/windows/jni_md.h b/Templates/Empty/web/source/npplugin/windows/jni_md.h new file mode 100644 index 000000000..9e51692ef --- /dev/null +++ b/Templates/Empty/web/source/npplugin/windows/jni_md.h @@ -0,0 +1,215 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** + * + * + * This Original Code has been modified by IBM Corporation. + * Modifications made by IBM described herein are + * Copyright (c) International Business Machines + * Corporation, 2000 + * + * Modifications to Mozilla code or documentation + * identified per MPL Section 3.3 + * + * Date Modified by Description of modification + * 03/27/2000 IBM Corp. Set JNICALL to Optlink for + * use in OS2 + */ + +/******************************************************************************* + * Netscape version of jni_md.h -- depends on jri_md.h + ******************************************************************************/ + +#ifndef JNI_MD_H +#define JNI_MD_H + +#include "prtypes.h" /* needed for _declspec */ + +/******************************************************************************* + * WHAT'S UP WITH THIS FILE? + * + * This is where we define the mystical JNI_PUBLIC_API macro that works on all + * platforms. If you're running with Visual C++, Symantec C, or Borland's + * development environment on the PC, you're all set. Or if you're on the Mac + * with Metrowerks, Symantec or MPW with SC you're ok too. For UNIX it shouldn't + * matter. + + * Changes by sailesh on 9/26 + + * There are two symbols used in the declaration of the JNI functions + * and native code that uses the JNI: + * JNICALL - specifies the calling convention + * JNIEXPORT - specifies export status of the function + * + * The syntax to specify calling conventions is different in Win16 and + * Win32 - the brains at Micro$oft at work here. JavaSoft in their + * infinite wisdom cares for no platform other than Win32, and so they + * just define these two symbols as: + + #define JNIEXPORT __declspec(dllexport) + #define JNICALL __stdcall + + * We deal with this, in the way JRI defines the JRI_PUBLIC_API, by + * defining a macro called JNI_PUBLIC_API. Any of our developers who + * wish to use code for Win16 and Win32, _must_ use JNI_PUBLIC_API to + * be able to export functions properly. + + * Since we must also maintain compatibility with JavaSoft, we + * continue to define the symbol JNIEXPORT. However, use of this + * internally is deprecated, since it will cause a mess on Win16. + + * We _do not_ need a new symbol called JNICALL. Instead we + * redefine JNICALL in the same way JRI_CALLBACK was defined. + + ******************************************************************************/ + +/* DLL Entry modifiers... */ +/* Win32 */ +#if defined(XP_WIN) || defined(_WINDOWS) || defined(WIN32) || defined(_WIN32) +# include <windows.h> +# if defined(_MSC_VER) || defined(__GNUC__) +# if defined(WIN32) || defined(_WIN32) +# define JNI_PUBLIC_API(ResultType) _declspec(dllexport) ResultType __stdcall +# define JNI_PUBLIC_VAR(VarType) VarType +# define JNI_NATIVE_STUB(ResultType) _declspec(dllexport) ResultType +# define JNICALL __stdcall +# else /* !_WIN32 */ +# if defined(_WINDLL) +# define JNI_PUBLIC_API(ResultType) ResultType __cdecl __export __loadds +# define JNI_PUBLIC_VAR(VarType) VarType +# define JNI_NATIVE_STUB(ResultType) ResultType __cdecl __loadds +# define JNICALL __loadds +# else /* !WINDLL */ +# define JNI_PUBLIC_API(ResultType) ResultType __cdecl __export +# define JNI_PUBLIC_VAR(VarType) VarType +# define JNI_NATIVE_STUB(ResultType) ResultType __cdecl __export +# define JNICALL __export +# endif /* !WINDLL */ +# endif /* !_WIN32 */ +# elif defined(__BORLANDC__) +# if defined(WIN32) || defined(_WIN32) +# define JNI_PUBLIC_API(ResultType) __export ResultType +# define JNI_PUBLIC_VAR(VarType) VarType +# define JNI_NATIVE_STUB(ResultType) __export ResultType +# define JNICALL +# else /* !_WIN32 */ +# define JNI_PUBLIC_API(ResultType) ResultType _cdecl _export _loadds +# define JNI_PUBLIC_VAR(VarType) VarType +# define JNI_NATIVE_STUB(ResultType) ResultType _cdecl _loadds +# define JNICALL _loadds +# endif +# else +# error Unsupported PC development environment. +# endif +# ifndef IS_LITTLE_ENDIAN +# define IS_LITTLE_ENDIAN +# endif + /* This is the stuff inherited from JavaSoft .. */ +# define JNIEXPORT __declspec(dllexport) +# define JNIIMPORT __declspec(dllimport) + +/* OS/2 */ +#elif defined(XP_OS2) +# ifdef XP_OS2_VACPP +# define JNI_PUBLIC_API(ResultType) ResultType _System +# define JNI_PUBLIC_VAR(VarType) VarType +# define JNICALL _Optlink +# define JNIEXPORT +# define JNIIMPORT +# elif defined(__declspec) +# define JNI_PUBLIC_API(ResultType) __declspec(dllexport) ResultType +# define JNI_PUBLIC_VAR(VarType) VarType +# define JNI_NATIVE_STUB(ResultType) __declspec(dllexport) ResultType +# define JNICALL +# define JNIEXPORT +# define JNIIMPORT +# else +# define JNI_PUBLIC_API(ResultType) ResultType +# define JNI_PUBLIC_VAR(VarType) VarType +# define JNICALL +# define JNIEXPORT +# define JNIIMPORT +# endif +# ifndef IS_LITTLE_ENDIAN +# define IS_LITTLE_ENDIAN +# endif + +/* Mac */ +#elif macintosh || Macintosh || THINK_C +# if defined(__MWERKS__) /* Metrowerks */ +# if !__option(enumsalwaysint) +# error You need to define 'Enums Always Int' for your project. +# endif +# if defined(TARGET_CPU_68K) && !TARGET_RT_MAC_CFM +# if !__option(fourbyteints) +# error You need to define 'Struct Alignment: 68k' for your project. +# endif +# endif /* !GENERATINGCFM */ +# define JNI_PUBLIC_API(ResultType) __declspec(export) ResultType +# define JNI_PUBLIC_VAR(VarType) JNI_PUBLIC_API(VarType) +# define JNI_NATIVE_STUB(ResultType) JNI_PUBLIC_API(ResultType) +# elif defined(__SC__) /* Symantec */ +# error What are the Symantec defines? (warren@netscape.com) +# elif macintosh && applec /* MPW */ +# error Please upgrade to the latest MPW compiler (SC). +# else +# error Unsupported Mac development environment. +# endif +# define JNICALL + /* This is the stuff inherited from JavaSoft .. */ +# define JNIEXPORT +# define JNIIMPORT + +/* Unix or else */ +#else +# define JNI_PUBLIC_API(ResultType) ResultType +# define JNI_PUBLIC_VAR(VarType) VarType +# define JNI_NATIVE_STUB(ResultType) ResultType +# define JNICALL + /* This is the stuff inherited from JavaSoft .. */ +# define JNIEXPORT +# define JNIIMPORT +#endif + +#ifndef FAR /* for non-Win16 */ +#define FAR +#endif + +/* Get the rest of the stuff from jri_md.h */ +#include "jri_md.h" + +#endif /* JNI_MD_H */ diff --git a/Templates/Empty/web/source/npplugin/windows/jri.h b/Templates/Empty/web/source/npplugin/windows/jri.h new file mode 100644 index 000000000..866fc69aa --- /dev/null +++ b/Templates/Empty/web/source/npplugin/windows/jri.h @@ -0,0 +1,689 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/******************************************************************************* + * Java Runtime Interface + ******************************************************************************/ + +#ifndef JRI_H +#define JRI_H + +#include "jritypes.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************* + * JRIEnv + ******************************************************************************/ + +/* The type of the JRIEnv interface. */ +typedef struct JRIEnvInterface JRIEnvInterface; + +/* The type of a JRIEnv instance. */ +typedef const JRIEnvInterface* JRIEnv; + +/******************************************************************************* + * JRIEnv Operations + ******************************************************************************/ + +#define JRI_DefineClass(env, classLoader, buf, bufLen) \ + (((*(env))->DefineClass)(env, JRI_DefineClass_op, classLoader, buf, bufLen)) + +#define JRI_FindClass(env, name) \ + (((*(env))->FindClass)(env, JRI_FindClass_op, name)) + +#define JRI_Throw(env, obj) \ + (((*(env))->Throw)(env, JRI_Throw_op, obj)) + +#define JRI_ThrowNew(env, clazz, message) \ + (((*(env))->ThrowNew)(env, JRI_ThrowNew_op, clazz, message)) + +#define JRI_ExceptionOccurred(env) \ + (((*(env))->ExceptionOccurred)(env, JRI_ExceptionOccurred_op)) + +#define JRI_ExceptionDescribe(env) \ + (((*(env))->ExceptionDescribe)(env, JRI_ExceptionDescribe_op)) + +#define JRI_ExceptionClear(env) \ + (((*(env))->ExceptionClear)(env, JRI_ExceptionClear_op)) + +#define JRI_NewGlobalRef(env, ref) \ + (((*(env))->NewGlobalRef)(env, JRI_NewGlobalRef_op, ref)) + +#define JRI_DisposeGlobalRef(env, gref) \ + (((*(env))->DisposeGlobalRef)(env, JRI_DisposeGlobalRef_op, gref)) + +#define JRI_GetGlobalRef(env, gref) \ + (((*(env))->GetGlobalRef)(env, JRI_GetGlobalRef_op, gref)) + +#define JRI_SetGlobalRef(env, gref, ref) \ + (((*(env))->SetGlobalRef)(env, JRI_SetGlobalRef_op, gref, ref)) + +#define JRI_IsSameObject(env, a, b) \ + (((*(env))->IsSameObject)(env, JRI_IsSameObject_op, a, b)) + +#define JRI_NewObject(env) ((*(env))->NewObject) +#define JRI_NewObjectV(env, clazz, methodID, args) \ + (((*(env))->NewObjectV)(env, JRI_NewObject_op_va_list, clazz, methodID, args)) +#define JRI_NewObjectA(env, clazz, method, args) \ + (((*(env))->NewObjectA)(env, JRI_NewObject_op_array, clazz, methodID, args)) + +#define JRI_GetObjectClass(env, obj) \ + (((*(env))->GetObjectClass)(env, JRI_GetObjectClass_op, obj)) + +#define JRI_IsInstanceOf(env, obj, clazz) \ + (((*(env))->IsInstanceOf)(env, JRI_IsInstanceOf_op, obj, clazz)) + +#define JRI_GetMethodID(env, clazz, name, sig) \ + (((*(env))->GetMethodID)(env, JRI_GetMethodID_op, clazz, name, sig)) + +#define JRI_CallMethod(env) ((*(env))->CallMethod) +#define JRI_CallMethodV(env, obj, methodID, args) \ + (((*(env))->CallMethodV)(env, JRI_CallMethod_op_va_list, obj, methodID, args)) +#define JRI_CallMethodA(env, obj, methodID, args) \ + (((*(env))->CallMethodA)(env, JRI_CallMethod_op_array, obj, methodID, args)) + +#define JRI_CallMethodBoolean(env) ((*(env))->CallMethodBoolean) +#define JRI_CallMethodBooleanV(env, obj, methodID, args) \ + (((*(env))->CallMethodBooleanV)(env, JRI_CallMethodBoolean_op_va_list, obj, methodID, args)) +#define JRI_CallMethodBooleanA(env, obj, methodID, args) \ + (((*(env))->CallMethodBooleanA)(env, JRI_CallMethodBoolean_op_array, obj, methodID, args)) + +#define JRI_CallMethodByte(env) ((*(env))->CallMethodByte) +#define JRI_CallMethodByteV(env, obj, methodID, args) \ + (((*(env))->CallMethodByteV)(env, JRI_CallMethodByte_op_va_list, obj, methodID, args)) +#define JRI_CallMethodByteA(env, obj, methodID, args) \ + (((*(env))->CallMethodByteA)(env, JRI_CallMethodByte_op_array, obj, methodID, args)) + +#define JRI_CallMethodChar(env) ((*(env))->CallMethodChar) +#define JRI_CallMethodCharV(env, obj, methodID, args) \ + (((*(env))->CallMethodCharV)(env, JRI_CallMethodChar_op_va_list, obj, methodID, args)) +#define JRI_CallMethodCharA(env, obj, methodID, args) \ + (((*(env))->CallMethodCharA)(env, JRI_CallMethodChar_op_array, obj, methodID, args)) + +#define JRI_CallMethodShort(env) ((*(env))->CallMethodShort) +#define JRI_CallMethodShortV(env, obj, methodID, args) \ + (((*(env))->CallMethodShortV)(env, JRI_CallMethodShort_op_va_list, obj, methodID, args)) +#define JRI_CallMethodShortA(env, obj, methodID, args) \ + (((*(env))->CallMethodShortA)(env, JRI_CallMethodShort_op_array, obj, methodID, args)) + +#define JRI_CallMethodInt(env) ((*(env))->CallMethodInt) +#define JRI_CallMethodIntV(env, obj, methodID, args) \ + (((*(env))->CallMethodIntV)(env, JRI_CallMethodInt_op_va_list, obj, methodID, args)) +#define JRI_CallMethodIntA(env, obj, methodID, args) \ + (((*(env))->CallMethodIntA)(env, JRI_CallMethodInt_op_array, obj, methodID, args)) + +#define JRI_CallMethodLong(env) ((*(env))->CallMethodLong) +#define JRI_CallMethodLongV(env, obj, methodID, args) \ + (((*(env))->CallMethodLongV)(env, JRI_CallMethodLong_op_va_list, obj, methodID, args)) +#define JRI_CallMethodLongA(env, obj, methodID, args) \ + (((*(env))->CallMethodLongA)(env, JRI_CallMethodLong_op_array, obj, methodID, args)) + +#define JRI_CallMethodFloat(env) ((*(env))->CallMethodFloat) +#define JRI_CallMethodFloatV(env, obj, methodID, args) \ + (((*(env))->CallMethodFloatV)(env, JRI_CallMethodFloat_op_va_list, obj, methodID, args)) +#define JRI_CallMethodFloatA(env, obj, methodID, args) \ + (((*(env))->CallMethodFloatA)(env, JRI_CallMethodFloat_op_array, obj, methodID, args)) + +#define JRI_CallMethodDouble(env) ((*(env))->CallMethodDouble) +#define JRI_CallMethodDoubleV(env, obj, methodID, args) \ + (((*(env))->CallMethodDoubleV)(env, JRI_CallMethodDouble_op_va_list, obj, methodID, args)) +#define JRI_CallMethodDoubleA(env, obj, methodID, args) \ + (((*(env))->CallMethodDoubleA)(env, JRI_CallMethodDouble_op_array, obj, methodID, args)) + +#define JRI_GetFieldID(env, clazz, name, sig) \ + (((*(env))->GetFieldID)(env, JRI_GetFieldID_op, clazz, name, sig)) + +#define JRI_GetField(env, obj, fieldID) \ + (((*(env))->GetField)(env, JRI_GetField_op, obj, fieldID)) + +#define JRI_GetFieldBoolean(env, obj, fieldID) \ + (((*(env))->GetFieldBoolean)(env, JRI_GetFieldBoolean_op, obj, fieldID)) + +#define JRI_GetFieldByte(env, obj, fieldID) \ + (((*(env))->GetFieldByte)(env, JRI_GetFieldByte_op, obj, fieldID)) + +#define JRI_GetFieldChar(env, obj, fieldID) \ + (((*(env))->GetFieldChar)(env, JRI_GetFieldChar_op, obj, fieldID)) + +#define JRI_GetFieldShort(env, obj, fieldID) \ + (((*(env))->GetFieldShort)(env, JRI_GetFieldShort_op, obj, fieldID)) + +#define JRI_GetFieldInt(env, obj, fieldID) \ + (((*(env))->GetFieldInt)(env, JRI_GetFieldInt_op, obj, fieldID)) + +#define JRI_GetFieldLong(env, obj, fieldID) \ + (((*(env))->GetFieldLong)(env, JRI_GetFieldLong_op, obj, fieldID)) + +#define JRI_GetFieldFloat(env, obj, fieldID) \ + (((*(env))->GetFieldFloat)(env, JRI_GetFieldFloat_op, obj, fieldID)) + +#define JRI_GetFieldDouble(env, obj, fieldID) \ + (((*(env))->GetFieldDouble)(env, JRI_GetFieldDouble_op, obj, fieldID)) + +#define JRI_SetField(env, obj, fieldID, value) \ + (((*(env))->SetField)(env, JRI_SetField_op, obj, fieldID, value)) + +#define JRI_SetFieldBoolean(env, obj, fieldID, value) \ + (((*(env))->SetFieldBoolean)(env, JRI_SetFieldBoolean_op, obj, fieldID, value)) + +#define JRI_SetFieldByte(env, obj, fieldID, value) \ + (((*(env))->SetFieldByte)(env, JRI_SetFieldByte_op, obj, fieldID, value)) + +#define JRI_SetFieldChar(env, obj, fieldID, value) \ + (((*(env))->SetFieldChar)(env, JRI_SetFieldChar_op, obj, fieldID, value)) + +#define JRI_SetFieldShort(env, obj, fieldID, value) \ + (((*(env))->SetFieldShort)(env, JRI_SetFieldShort_op, obj, fieldID, value)) + +#define JRI_SetFieldInt(env, obj, fieldID, value) \ + (((*(env))->SetFieldInt)(env, JRI_SetFieldInt_op, obj, fieldID, value)) + +#define JRI_SetFieldLong(env, obj, fieldID, value) \ + (((*(env))->SetFieldLong)(env, JRI_SetFieldLong_op, obj, fieldID, value)) + +#define JRI_SetFieldFloat(env, obj, fieldID, value) \ + (((*(env))->SetFieldFloat)(env, JRI_SetFieldFloat_op, obj, fieldID, value)) + +#define JRI_SetFieldDouble(env, obj, fieldID, value) \ + (((*(env))->SetFieldDouble)(env, JRI_SetFieldDouble_op, obj, fieldID, value)) + +#define JRI_IsSubclassOf(env, a, b) \ + (((*(env))->IsSubclassOf)(env, JRI_IsSubclassOf_op, a, b)) + +#define JRI_GetStaticMethodID(env, clazz, name, sig) \ + (((*(env))->GetStaticMethodID)(env, JRI_GetStaticMethodID_op, clazz, name, sig)) + +#define JRI_CallStaticMethod(env) ((*(env))->CallStaticMethod) +#define JRI_CallStaticMethodV(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodV)(env, JRI_CallStaticMethod_op_va_list, clazz, methodID, args)) +#define JRI_CallStaticMethodA(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodA)(env, JRI_CallStaticMethod_op_array, clazz, methodID, args)) + +#define JRI_CallStaticMethodBoolean(env) ((*(env))->CallStaticMethodBoolean) +#define JRI_CallStaticMethodBooleanV(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodBooleanV)(env, JRI_CallStaticMethodBoolean_op_va_list, clazz, methodID, args)) +#define JRI_CallStaticMethodBooleanA(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodBooleanA)(env, JRI_CallStaticMethodBoolean_op_array, clazz, methodID, args)) + +#define JRI_CallStaticMethodByte(env) ((*(env))->CallStaticMethodByte) +#define JRI_CallStaticMethodByteV(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodByteV)(env, JRI_CallStaticMethodByte_op_va_list, clazz, methodID, args)) +#define JRI_CallStaticMethodByteA(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodByteA)(env, JRI_CallStaticMethodByte_op_array, clazz, methodID, args)) + +#define JRI_CallStaticMethodChar(env) ((*(env))->CallStaticMethodChar) +#define JRI_CallStaticMethodCharV(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodCharV)(env, JRI_CallStaticMethodChar_op_va_list, clazz, methodID, args)) +#define JRI_CallStaticMethodCharA(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodCharA)(env, JRI_CallStaticMethodChar_op_array, clazz, methodID, args)) + +#define JRI_CallStaticMethodShort(env) ((*(env))->CallStaticMethodShort) +#define JRI_CallStaticMethodShortV(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodShortV)(env, JRI_CallStaticMethodShort_op_va_list, clazz, methodID, args)) +#define JRI_CallStaticMethodShortA(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodShortA)(env, JRI_CallStaticMethodShort_op_array, clazz, methodID, args)) + +#define JRI_CallStaticMethodInt(env) ((*(env))->CallStaticMethodInt) +#define JRI_CallStaticMethodIntV(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodIntV)(env, JRI_CallStaticMethodInt_op_va_list, clazz, methodID, args)) +#define JRI_CallStaticMethodIntA(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodIntA)(env, JRI_CallStaticMethodInt_op_array, clazz, methodID, args)) + +#define JRI_CallStaticMethodLong(env) ((*(env))->CallStaticMethodLong) +#define JRI_CallStaticMethodLongV(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodLongV)(env, JRI_CallStaticMethodLong_op_va_list, clazz, methodID, args)) +#define JRI_CallStaticMethodLongA(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodLongA)(env, JRI_CallStaticMethodLong_op_array, clazz, methodID, args)) + +#define JRI_CallStaticMethodFloat(env) ((*(env))->CallStaticMethodFloat) +#define JRI_CallStaticMethodFloatV(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodFloatV)(env, JRI_CallStaticMethodFloat_op_va_list, clazz, methodID, args)) +#define JRI_CallStaticMethodFloatA(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodFloatA)(env, JRI_CallStaticMethodFloat_op_array, clazz, methodID, args)) + +#define JRI_CallStaticMethodDouble(env) ((*(env))->CallStaticMethodDouble) +#define JRI_CallStaticMethodDoubleV(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodDoubleV)(env, JRI_CallStaticMethodDouble_op_va_list, clazz, methodID, args)) +#define JRI_CallStaticMethodDoubleA(env, clazz, methodID, args) \ + (((*(env))->CallStaticMethodDoubleA)(env, JRI_CallStaticMethodDouble_op_array, clazz, methodID, args)) + +#define JRI_GetStaticFieldID(env, clazz, name, sig) \ + (((*(env))->GetStaticFieldID)(env, JRI_GetStaticFieldID_op, clazz, name, sig)) + +#define JRI_GetStaticField(env, clazz, fieldID) \ + (((*(env))->GetStaticField)(env, JRI_GetStaticField_op, clazz, fieldID)) + +#define JRI_GetStaticFieldBoolean(env, clazz, fieldID) \ + (((*(env))->GetStaticFieldBoolean)(env, JRI_GetStaticFieldBoolean_op, clazz, fieldID)) + +#define JRI_GetStaticFieldByte(env, clazz, fieldID) \ + (((*(env))->GetStaticFieldByte)(env, JRI_GetStaticFieldByte_op, clazz, fieldID)) + +#define JRI_GetStaticFieldChar(env, clazz, fieldID) \ + (((*(env))->GetStaticFieldChar)(env, JRI_GetStaticFieldChar_op, clazz, fieldID)) + +#define JRI_GetStaticFieldShort(env, clazz, fieldID) \ + (((*(env))->GetStaticFieldShort)(env, JRI_GetStaticFieldShort_op, clazz, fieldID)) + +#define JRI_GetStaticFieldInt(env, clazz, fieldID) \ + (((*(env))->GetStaticFieldInt)(env, JRI_GetStaticFieldInt_op, clazz, fieldID)) + +#define JRI_GetStaticFieldLong(env, clazz, fieldID) \ + (((*(env))->GetStaticFieldLong)(env, JRI_GetStaticFieldLong_op, clazz, fieldID)) + +#define JRI_GetStaticFieldFloat(env, clazz, fieldID) \ + (((*(env))->GetStaticFieldFloat)(env, JRI_GetStaticFieldFloat_op, clazz, fieldID)) + +#define JRI_GetStaticFieldDouble(env, clazz, fieldID) \ + (((*(env))->GetStaticFieldDouble)(env, JRI_GetStaticFieldDouble_op, clazz, fieldID)) + +#define JRI_SetStaticField(env, clazz, fieldID, value) \ + (((*(env))->SetStaticField)(env, JRI_SetStaticField_op, clazz, fieldID, value)) + +#define JRI_SetStaticFieldBoolean(env, clazz, fieldID, value) \ + (((*(env))->SetStaticFieldBoolean)(env, JRI_SetStaticFieldBoolean_op, clazz, fieldID, value)) + +#define JRI_SetStaticFieldByte(env, clazz, fieldID, value) \ + (((*(env))->SetStaticFieldByte)(env, JRI_SetStaticFieldByte_op, clazz, fieldID, value)) + +#define JRI_SetStaticFieldChar(env, clazz, fieldID, value) \ + (((*(env))->SetStaticFieldChar)(env, JRI_SetStaticFieldChar_op, clazz, fieldID, value)) + +#define JRI_SetStaticFieldShort(env, clazz, fieldID, value) \ + (((*(env))->SetStaticFieldShort)(env, JRI_SetStaticFieldShort_op, clazz, fieldID, value)) + +#define JRI_SetStaticFieldInt(env, clazz, fieldID, value) \ + (((*(env))->SetStaticFieldInt)(env, JRI_SetStaticFieldInt_op, clazz, fieldID, value)) + +#define JRI_SetStaticFieldLong(env, clazz, fieldID, value) \ + (((*(env))->SetStaticFieldLong)(env, JRI_SetStaticFieldLong_op, clazz, fieldID, value)) + +#define JRI_SetStaticFieldFloat(env, clazz, fieldID, value) \ + (((*(env))->SetStaticFieldFloat)(env, JRI_SetStaticFieldFloat_op, clazz, fieldID, value)) + +#define JRI_SetStaticFieldDouble(env, clazz, fieldID, value) \ + (((*(env))->SetStaticFieldDouble)(env, JRI_SetStaticFieldDouble_op, clazz, fieldID, value)) + +#define JRI_NewString(env, unicode, len) \ + (((*(env))->NewString)(env, JRI_NewString_op, unicode, len)) + +#define JRI_GetStringLength(env, string) \ + (((*(env))->GetStringLength)(env, JRI_GetStringLength_op, string)) + +#define JRI_GetStringChars(env, string) \ + (((*(env))->GetStringChars)(env, JRI_GetStringChars_op, string)) + +#define JRI_NewStringUTF(env, utf, len) \ + (((*(env))->NewStringUTF)(env, JRI_NewStringUTF_op, utf, len)) + +#define JRI_GetStringUTFLength(env, string) \ + (((*(env))->GetStringUTFLength)(env, JRI_GetStringUTFLength_op, string)) + +#define JRI_GetStringUTFChars(env, string) \ + (((*(env))->GetStringUTFChars)(env, JRI_GetStringUTFChars_op, string)) + +#define JRI_NewScalarArray(env, length, elementSig, initialElements) \ + (((*(env))->NewScalarArray)(env, JRI_NewScalarArray_op, length, elementSig, initialElements)) + +#define JRI_GetScalarArrayLength(env, array) \ + (((*(env))->GetScalarArrayLength)(env, JRI_GetScalarArrayLength_op, array)) + +#define JRI_GetScalarArrayElements(env, array) \ + (((*(env))->GetScalarArrayElements)(env, JRI_GetScalarArrayElements_op, array)) + +#define JRI_NewObjectArray(env, length, elementClass, initialElement) \ + (((*(env))->NewObjectArray)(env, JRI_NewObjectArray_op, length, elementClass, initialElement)) + +#define JRI_GetObjectArrayLength(env, array) \ + (((*(env))->GetObjectArrayLength)(env, JRI_GetObjectArrayLength_op, array)) + +#define JRI_GetObjectArrayElement(env, array, index) \ + (((*(env))->GetObjectArrayElement)(env, JRI_GetObjectArrayElement_op, array, index)) + +#define JRI_SetObjectArrayElement(env, array, index, value) \ + (((*(env))->SetObjectArrayElement)(env, JRI_SetObjectArrayElement_op, array, index, value)) + +#define JRI_RegisterNatives(env, clazz, nameAndSigArray, nativeProcArray) \ + (((*(env))->RegisterNatives)(env, JRI_RegisterNatives_op, clazz, nameAndSigArray, nativeProcArray)) + +#define JRI_UnregisterNatives(env, clazz) \ + (((*(env))->UnregisterNatives)(env, JRI_UnregisterNatives_op, clazz)) + +#define JRI_NewStringPlatform(env, string, len, encoding, encodingLength) \ + (((*(env))->NewStringPlatform)(env, JRI_NewStringPlatform_op, string, len, encoding, encodingLength)) + +#define JRI_GetStringPlatformChars(env, string, encoding, encodingLength) \ + (((*(env))->GetStringPlatformChars)(env, JRI_GetStringPlatformChars_op, string, encoding, encodingLength)) + + +/******************************************************************************* + * JRIEnv Interface + ******************************************************************************/ + +struct java_lang_ClassLoader; +struct java_lang_Class; +struct java_lang_Throwable; +struct java_lang_Object; +struct java_lang_String; + +struct JRIEnvInterface { + void* reserved0; + void* reserved1; + void* reserved2; + void* reserved3; + struct java_lang_Class* (*FindClass)(JRIEnv* env, jint op, const char* a); + void (*Throw)(JRIEnv* env, jint op, struct java_lang_Throwable* a); + void (*ThrowNew)(JRIEnv* env, jint op, struct java_lang_Class* a, const char* b); + struct java_lang_Throwable* (*ExceptionOccurred)(JRIEnv* env, jint op); + void (*ExceptionDescribe)(JRIEnv* env, jint op); + void (*ExceptionClear)(JRIEnv* env, jint op); + jglobal (*NewGlobalRef)(JRIEnv* env, jint op, void* a); + void (*DisposeGlobalRef)(JRIEnv* env, jint op, jglobal a); + void* (*GetGlobalRef)(JRIEnv* env, jint op, jglobal a); + void (*SetGlobalRef)(JRIEnv* env, jint op, jglobal a, void* b); + jbool (*IsSameObject)(JRIEnv* env, jint op, void* a, void* b); + void* (*NewObject)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); + void* (*NewObjectV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); + void* (*NewObjectA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); + struct java_lang_Class* (*GetObjectClass)(JRIEnv* env, jint op, void* a); + jbool (*IsInstanceOf)(JRIEnv* env, jint op, void* a, struct java_lang_Class* b); + jint (*GetMethodID)(JRIEnv* env, jint op, struct java_lang_Class* a, const char* b, const char* c); + void* (*CallMethod)(JRIEnv* env, jint op, void* a, jint b, ...); + void* (*CallMethodV)(JRIEnv* env, jint op, void* a, jint b, va_list c); + void* (*CallMethodA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); + jbool (*CallMethodBoolean)(JRIEnv* env, jint op, void* a, jint b, ...); + jbool (*CallMethodBooleanV)(JRIEnv* env, jint op, void* a, jint b, va_list c); + jbool (*CallMethodBooleanA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); + jbyte (*CallMethodByte)(JRIEnv* env, jint op, void* a, jint b, ...); + jbyte (*CallMethodByteV)(JRIEnv* env, jint op, void* a, jint b, va_list c); + jbyte (*CallMethodByteA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); + jchar (*CallMethodChar)(JRIEnv* env, jint op, void* a, jint b, ...); + jchar (*CallMethodCharV)(JRIEnv* env, jint op, void* a, jint b, va_list c); + jchar (*CallMethodCharA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); + jshort (*CallMethodShort)(JRIEnv* env, jint op, void* a, jint b, ...); + jshort (*CallMethodShortV)(JRIEnv* env, jint op, void* a, jint b, va_list c); + jshort (*CallMethodShortA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); + jint (*CallMethodInt)(JRIEnv* env, jint op, void* a, jint b, ...); + jint (*CallMethodIntV)(JRIEnv* env, jint op, void* a, jint b, va_list c); + jint (*CallMethodIntA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); + jlong (*CallMethodLong)(JRIEnv* env, jint op, void* a, jint b, ...); + jlong (*CallMethodLongV)(JRIEnv* env, jint op, void* a, jint b, va_list c); + jlong (*CallMethodLongA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); + jfloat (*CallMethodFloat)(JRIEnv* env, jint op, void* a, jint b, ...); + jfloat (*CallMethodFloatV)(JRIEnv* env, jint op, void* a, jint b, va_list c); + jfloat (*CallMethodFloatA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); + jdouble (*CallMethodDouble)(JRIEnv* env, jint op, void* a, jint b, ...); + jdouble (*CallMethodDoubleV)(JRIEnv* env, jint op, void* a, jint b, va_list c); + jdouble (*CallMethodDoubleA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); + jint (*GetFieldID)(JRIEnv* env, jint op, struct java_lang_Class* a, const char* b, const char* c); + void* (*GetField)(JRIEnv* env, jint op, void* a, jint b); + jbool (*GetFieldBoolean)(JRIEnv* env, jint op, void* a, jint b); + jbyte (*GetFieldByte)(JRIEnv* env, jint op, void* a, jint b); + jchar (*GetFieldChar)(JRIEnv* env, jint op, void* a, jint b); + jshort (*GetFieldShort)(JRIEnv* env, jint op, void* a, jint b); + jint (*GetFieldInt)(JRIEnv* env, jint op, void* a, jint b); + jlong (*GetFieldLong)(JRIEnv* env, jint op, void* a, jint b); + jfloat (*GetFieldFloat)(JRIEnv* env, jint op, void* a, jint b); + jdouble (*GetFieldDouble)(JRIEnv* env, jint op, void* a, jint b); + void (*SetField)(JRIEnv* env, jint op, void* a, jint b, void* c); + void (*SetFieldBoolean)(JRIEnv* env, jint op, void* a, jint b, jbool c); + void (*SetFieldByte)(JRIEnv* env, jint op, void* a, jint b, jbyte c); + void (*SetFieldChar)(JRIEnv* env, jint op, void* a, jint b, jchar c); + void (*SetFieldShort)(JRIEnv* env, jint op, void* a, jint b, jshort c); + void (*SetFieldInt)(JRIEnv* env, jint op, void* a, jint b, jint c); + void (*SetFieldLong)(JRIEnv* env, jint op, void* a, jint b, jlong c); + void (*SetFieldFloat)(JRIEnv* env, jint op, void* a, jint b, jfloat c); + void (*SetFieldDouble)(JRIEnv* env, jint op, void* a, jint b, jdouble c); + jbool (*IsSubclassOf)(JRIEnv* env, jint op, struct java_lang_Class* a, struct java_lang_Class* b); + jint (*GetStaticMethodID)(JRIEnv* env, jint op, struct java_lang_Class* a, const char* b, const char* c); + void* (*CallStaticMethod)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); + void* (*CallStaticMethodV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); + void* (*CallStaticMethodA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); + jbool (*CallStaticMethodBoolean)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); + jbool (*CallStaticMethodBooleanV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); + jbool (*CallStaticMethodBooleanA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); + jbyte (*CallStaticMethodByte)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); + jbyte (*CallStaticMethodByteV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); + jbyte (*CallStaticMethodByteA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); + jchar (*CallStaticMethodChar)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); + jchar (*CallStaticMethodCharV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); + jchar (*CallStaticMethodCharA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); + jshort (*CallStaticMethodShort)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); + jshort (*CallStaticMethodShortV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); + jshort (*CallStaticMethodShortA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); + jint (*CallStaticMethodInt)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); + jint (*CallStaticMethodIntV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); + jint (*CallStaticMethodIntA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); + jlong (*CallStaticMethodLong)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); + jlong (*CallStaticMethodLongV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); + jlong (*CallStaticMethodLongA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); + jfloat (*CallStaticMethodFloat)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); + jfloat (*CallStaticMethodFloatV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); + jfloat (*CallStaticMethodFloatA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); + jdouble (*CallStaticMethodDouble)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); + jdouble (*CallStaticMethodDoubleV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); + jdouble (*CallStaticMethodDoubleA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); + jint (*GetStaticFieldID)(JRIEnv* env, jint op, struct java_lang_Class* a, const char* b, const char* c); + void* (*GetStaticField)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); + jbool (*GetStaticFieldBoolean)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); + jbyte (*GetStaticFieldByte)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); + jchar (*GetStaticFieldChar)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); + jshort (*GetStaticFieldShort)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); + jint (*GetStaticFieldInt)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); + jlong (*GetStaticFieldLong)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); + jfloat (*GetStaticFieldFloat)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); + jdouble (*GetStaticFieldDouble)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); + void (*SetStaticField)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, void* c); + void (*SetStaticFieldBoolean)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jbool c); + void (*SetStaticFieldByte)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jbyte c); + void (*SetStaticFieldChar)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jchar c); + void (*SetStaticFieldShort)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jshort c); + void (*SetStaticFieldInt)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jint c); + void (*SetStaticFieldLong)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jlong c); + void (*SetStaticFieldFloat)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jfloat c); + void (*SetStaticFieldDouble)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jdouble c); + struct java_lang_String* (*NewString)(JRIEnv* env, jint op, const jchar* a, jint b); + jint (*GetStringLength)(JRIEnv* env, jint op, struct java_lang_String* a); + const jchar* (*GetStringChars)(JRIEnv* env, jint op, struct java_lang_String* a); + struct java_lang_String* (*NewStringUTF)(JRIEnv* env, jint op, const jbyte* a, jint b); + jint (*GetStringUTFLength)(JRIEnv* env, jint op, struct java_lang_String* a); + const jbyte* (*GetStringUTFChars)(JRIEnv* env, jint op, struct java_lang_String* a); + void* (*NewScalarArray)(JRIEnv* env, jint op, jint a, const char* b, const jbyte* c); + jint (*GetScalarArrayLength)(JRIEnv* env, jint op, void* a); + jbyte* (*GetScalarArrayElements)(JRIEnv* env, jint op, void* a); + void* (*NewObjectArray)(JRIEnv* env, jint op, jint a, struct java_lang_Class* b, void* c); + jint (*GetObjectArrayLength)(JRIEnv* env, jint op, void* a); + void* (*GetObjectArrayElement)(JRIEnv* env, jint op, void* a, jint b); + void (*SetObjectArrayElement)(JRIEnv* env, jint op, void* a, jint b, void* c); + void (*RegisterNatives)(JRIEnv* env, jint op, struct java_lang_Class* a, char** b, void** c); + void (*UnregisterNatives)(JRIEnv* env, jint op, struct java_lang_Class* a); + struct java_lang_Class* (*DefineClass)(JRIEnv* env, jint op, struct java_lang_ClassLoader* a, jbyte* b, jsize bLen); + struct java_lang_String* (*NewStringPlatform)(JRIEnv* env, jint op, const jbyte* a, jint b, const jbyte* c, jint d); + const jbyte* (*GetStringPlatformChars)(JRIEnv* env, jint op, struct java_lang_String* a, const jbyte* b, jint c); +}; + +/* +** **************************************************************************** +** JRIEnv Operation IDs +** *************************************************************************** +*/ + +typedef enum JRIEnvOperations { + JRI_Reserved0_op, + JRI_Reserved1_op, + JRI_Reserved2_op, + JRI_Reserved3_op, + JRI_FindClass_op, + JRI_Throw_op, + JRI_ThrowNew_op, + JRI_ExceptionOccurred_op, + JRI_ExceptionDescribe_op, + JRI_ExceptionClear_op, + JRI_NewGlobalRef_op, + JRI_DisposeGlobalRef_op, + JRI_GetGlobalRef_op, + JRI_SetGlobalRef_op, + JRI_IsSameObject_op, + JRI_NewObject_op, + JRI_NewObject_op_va_list, + JRI_NewObject_op_array, + JRI_GetObjectClass_op, + JRI_IsInstanceOf_op, + JRI_GetMethodID_op, + JRI_CallMethod_op, + JRI_CallMethod_op_va_list, + JRI_CallMethod_op_array, + JRI_CallMethodBoolean_op, + JRI_CallMethodBoolean_op_va_list, + JRI_CallMethodBoolean_op_array, + JRI_CallMethodByte_op, + JRI_CallMethodByte_op_va_list, + JRI_CallMethodByte_op_array, + JRI_CallMethodChar_op, + JRI_CallMethodChar_op_va_list, + JRI_CallMethodChar_op_array, + JRI_CallMethodShort_op, + JRI_CallMethodShort_op_va_list, + JRI_CallMethodShort_op_array, + JRI_CallMethodInt_op, + JRI_CallMethodInt_op_va_list, + JRI_CallMethodInt_op_array, + JRI_CallMethodLong_op, + JRI_CallMethodLong_op_va_list, + JRI_CallMethodLong_op_array, + JRI_CallMethodFloat_op, + JRI_CallMethodFloat_op_va_list, + JRI_CallMethodFloat_op_array, + JRI_CallMethodDouble_op, + JRI_CallMethodDouble_op_va_list, + JRI_CallMethodDouble_op_array, + JRI_GetFieldID_op, + JRI_GetField_op, + JRI_GetFieldBoolean_op, + JRI_GetFieldByte_op, + JRI_GetFieldChar_op, + JRI_GetFieldShort_op, + JRI_GetFieldInt_op, + JRI_GetFieldLong_op, + JRI_GetFieldFloat_op, + JRI_GetFieldDouble_op, + JRI_SetField_op, + JRI_SetFieldBoolean_op, + JRI_SetFieldByte_op, + JRI_SetFieldChar_op, + JRI_SetFieldShort_op, + JRI_SetFieldInt_op, + JRI_SetFieldLong_op, + JRI_SetFieldFloat_op, + JRI_SetFieldDouble_op, + JRI_IsSubclassOf_op, + JRI_GetStaticMethodID_op, + JRI_CallStaticMethod_op, + JRI_CallStaticMethod_op_va_list, + JRI_CallStaticMethod_op_array, + JRI_CallStaticMethodBoolean_op, + JRI_CallStaticMethodBoolean_op_va_list, + JRI_CallStaticMethodBoolean_op_array, + JRI_CallStaticMethodByte_op, + JRI_CallStaticMethodByte_op_va_list, + JRI_CallStaticMethodByte_op_array, + JRI_CallStaticMethodChar_op, + JRI_CallStaticMethodChar_op_va_list, + JRI_CallStaticMethodChar_op_array, + JRI_CallStaticMethodShort_op, + JRI_CallStaticMethodShort_op_va_list, + JRI_CallStaticMethodShort_op_array, + JRI_CallStaticMethodInt_op, + JRI_CallStaticMethodInt_op_va_list, + JRI_CallStaticMethodInt_op_array, + JRI_CallStaticMethodLong_op, + JRI_CallStaticMethodLong_op_va_list, + JRI_CallStaticMethodLong_op_array, + JRI_CallStaticMethodFloat_op, + JRI_CallStaticMethodFloat_op_va_list, + JRI_CallStaticMethodFloat_op_array, + JRI_CallStaticMethodDouble_op, + JRI_CallStaticMethodDouble_op_va_list, + JRI_CallStaticMethodDouble_op_array, + JRI_GetStaticFieldID_op, + JRI_GetStaticField_op, + JRI_GetStaticFieldBoolean_op, + JRI_GetStaticFieldByte_op, + JRI_GetStaticFieldChar_op, + JRI_GetStaticFieldShort_op, + JRI_GetStaticFieldInt_op, + JRI_GetStaticFieldLong_op, + JRI_GetStaticFieldFloat_op, + JRI_GetStaticFieldDouble_op, + JRI_SetStaticField_op, + JRI_SetStaticFieldBoolean_op, + JRI_SetStaticFieldByte_op, + JRI_SetStaticFieldChar_op, + JRI_SetStaticFieldShort_op, + JRI_SetStaticFieldInt_op, + JRI_SetStaticFieldLong_op, + JRI_SetStaticFieldFloat_op, + JRI_SetStaticFieldDouble_op, + JRI_NewString_op, + JRI_GetStringLength_op, + JRI_GetStringChars_op, + JRI_NewStringUTF_op, + JRI_GetStringUTFLength_op, + JRI_GetStringUTFChars_op, + JRI_NewScalarArray_op, + JRI_GetScalarArrayLength_op, + JRI_GetScalarArrayElements_op, + JRI_NewObjectArray_op, + JRI_GetObjectArrayLength_op, + JRI_GetObjectArrayElement_op, + JRI_SetObjectArrayElement_op, + JRI_RegisterNatives_op, + JRI_UnregisterNatives_op, + JRI_DefineClass_op, + JRI_NewStringPlatform_op, + JRI_GetStringPlatformChars_op +} JRIEnvOperations; + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* JRI_H */ +/******************************************************************************/ diff --git a/Templates/Empty/web/source/npplugin/windows/jri_md.h b/Templates/Empty/web/source/npplugin/windows/jri_md.h new file mode 100644 index 000000000..950481de3 --- /dev/null +++ b/Templates/Empty/web/source/npplugin/windows/jri_md.h @@ -0,0 +1,574 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/******************************************************************************* + * Java Runtime Interface - Machine Dependent Types + ******************************************************************************/ + +#ifndef JRI_MD_H +#define JRI_MD_H + +#include <assert.h> +#include "prtypes.h" /* Needed for HAS_LONG_LONG ifdefs */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * WHAT'S UP WITH THIS FILE? + * + * This is where we define the mystical JRI_PUBLIC_API macro that works on all + * platforms. If you're running with Visual C++, Symantec C, or Borland's + * development environment on the PC, you're all set. Or if you're on the Mac + * with Metrowerks, Symantec or MPW with SC you're ok too. For UNIX it shouldn't + * matter. + * + * On UNIX though you probably care about a couple of other symbols though: + * IS_LITTLE_ENDIAN must be defined for little-endian systems + * HAVE_LONG_LONG must be defined on systems that have 'long long' integers + * HAVE_ALIGNED_LONGLONGS must be defined if long-longs must be 8 byte aligned + * HAVE_ALIGNED_DOUBLES must be defined if doubles must be 8 byte aligned + * IS_64 must be defined on 64-bit machines (like Dec Alpha) + ******************************************************************************/ + +/* DLL Entry modifiers... */ + +/* Windows */ +#if defined(XP_WIN) || defined(_WINDOWS) || defined(WIN32) || defined(_WIN32) +# include <windows.h> +# if defined(_MSC_VER) || defined(__GNUC__) +# if defined(WIN32) || defined(_WIN32) +# define JRI_PUBLIC_API(ResultType) __declspec(dllexport) ResultType +# define JRI_PUBLIC_VAR(VarType) VarType +# define JRI_PUBLIC_VAR_EXP(VarType) __declspec(dllexport) VarType +# define JRI_PUBLIC_VAR_IMP(VarType) __declspec(dllimport) VarType +# define JRI_NATIVE_STUB(ResultType) __declspec(dllexport) ResultType +# define JRI_CALLBACK +# else /* !_WIN32 */ +# if defined(_WINDLL) +# define JRI_PUBLIC_API(ResultType) ResultType __cdecl __export __loadds +# define JRI_PUBLIC_VAR(VarType) VarType +# define JRI_PUBLIC_VAR_EXP(VarType) JRI_PUBLIC_VAR(VarType) +# define JRI_PUBLIC_VAR_IMP(VarType) JRI_PUBLIC_VAR(VarType) +# define JRI_NATIVE_STUB(ResultType) ResultType __cdecl __loadds +# define JRI_CALLBACK __loadds +# else /* !WINDLL */ +# define JRI_PUBLIC_API(ResultType) ResultType __cdecl __export +# define JRI_PUBLIC_VAR(VarType) VarType +# define JRI_PUBLIC_VAR_EXP(VarType) JRI_PUBLIC_VAR(VarType) +# define JRI_PUBLIC_VAR_IMP(VarType) JRI_PUBLIC_VAR(VarType) +# define JRI_NATIVE_STUB(ResultType) ResultType __cdecl __export +# define JRI_CALLBACK __export +# endif /* !WINDLL */ +# endif /* !_WIN32 */ +# elif defined(__BORLANDC__) +# if defined(WIN32) || defined(_WIN32) +# define JRI_PUBLIC_API(ResultType) __export ResultType +# define JRI_PUBLIC_VAR(VarType) VarType +# define JRI_PUBLIC_VAR_EXP(VarType) __export VarType +# define JRI_PUBLIC_VAR_IMP(VarType) __import VarType +# define JRI_NATIVE_STUB(ResultType) __export ResultType +# define JRI_CALLBACK +# else /* !_WIN32 */ +# define JRI_PUBLIC_API(ResultType) ResultType _cdecl _export _loadds +# define JRI_PUBLIC_VAR(VarType) VarType +# define JRI_PUBLIC_VAR_EXP(VarType) __cdecl __export VarType +# define JRI_PUBLIC_VAR_IMP(VarType) __cdecl __import VarType +# define JRI_NATIVE_STUB(ResultType) ResultType _cdecl _loadds +# define JRI_CALLBACK _loadds +# endif +# else +# error Unsupported PC development environment. +# endif +# ifndef IS_LITTLE_ENDIAN +# define IS_LITTLE_ENDIAN +# endif + +/* OS/2 */ +#elif defined(XP_OS2) +# ifdef XP_OS2_VACPP +# define JRI_PUBLIC_API(ResultType) ResultType _Optlink +# define JRI_PUBLIC_VAR(VarType) VarType +# define JRI_CALLBACK +# elif defined(__declspec) +# define JRI_PUBLIC_API(ResultType) __declspec(dllexport) ResultType +# define JRI_PUBLIC_VAR(VarType) VarType +# define JRI_PUBLIC_VAR_EXP(VarType) __declspec(dllexport) VarType +# define JRI_PUBLIC_VAR_IMP(VarType) __declspec(dllimport) VarType +# define JRI_NATIVE_STUB(ResultType) __declspec(dllexport) ResultType +# define JRI_CALLBACK +# else +# define JRI_PUBLIC_API(ResultType) ResultType +# define JRI_PUBLIC_VAR(VarType) VarType +# define JRI_CALLBACK +# endif + +/* Mac */ +#elif defined (macintosh) || Macintosh || THINK_C +# if defined(__MWERKS__) /* Metrowerks */ +# if !__option(enumsalwaysint) +# error You need to define 'Enums Always Int' for your project. +# endif +# if defined(TARGET_CPU_68K) && !TARGET_RT_MAC_CFM +# if !__option(fourbyteints) +# error You need to define 'Struct Alignment: 68k' for your project. +# endif +# endif /* !GENERATINGCFM */ +# define JRI_PUBLIC_API(ResultType) __declspec(export) ResultType +# define JRI_PUBLIC_VAR(VarType) JRI_PUBLIC_API(VarType) +# define JRI_PUBLIC_VAR_EXP(VarType) JRI_PUBLIC_API(VarType) +# define JRI_PUBLIC_VAR_IMP(VarType) JRI_PUBLIC_API(VarType) +# define JRI_NATIVE_STUB(ResultType) JRI_PUBLIC_API(ResultType) +# elif defined(__SC__) /* Symantec */ +# error What are the Symantec defines? (warren@netscape.com) +# elif macintosh && applec /* MPW */ +# error Please upgrade to the latest MPW compiler (SC). +# else +# error Unsupported Mac development environment. +# endif +# define JRI_CALLBACK + +/* Unix or else */ +#else +# define JRI_PUBLIC_API(ResultType) ResultType +# define JRI_PUBLIC_VAR(VarType) VarType +# define JRI_PUBLIC_VAR_EXP(VarType) JRI_PUBLIC_VAR(VarType) +# define JRI_PUBLIC_VAR_IMP(VarType) JRI_PUBLIC_VAR(VarType) +# define JRI_NATIVE_STUB(ResultType) ResultType +# define JRI_CALLBACK +#endif + +#ifndef FAR /* for non-Win16 */ +#define FAR +#endif + +/******************************************************************************/ + +/* Java Scalar Types */ + +#if 0 /* now in jni.h */ +typedef short jchar; +typedef short jshort; +typedef float jfloat; +typedef double jdouble; +typedef juint jsize; +#endif + +/* moved from jni.h -- Sun's new jni.h doesn't have this anymore */ +#ifdef __cplusplus +typedef class _jobject *jref; +#else +typedef struct _jobject *jref; +#endif + +typedef unsigned char jbool; +typedef signed char jbyte; +#ifdef IS_64 /* XXX ok for alpha, but not right on all 64-bit architectures */ +typedef unsigned int juint; +typedef int jint; +#else +typedef unsigned long juint; +typedef long jint; +#endif + +/******************************************************************************* + * jlong : long long (64-bit signed integer type) support. + ******************************************************************************/ + +/* +** Bit masking macros. (n must be <= 31 to be portable) +*/ +#define JRI_BIT(n) ((juint)1 << (n)) +#define JRI_BITMASK(n) (JRI_BIT(n) - 1) + +#ifdef HAVE_LONG_LONG + +#ifdef OSF1 + +/* long is default 64-bit on OSF1, -std1 does not allow long long */ +typedef long jlong; +typedef unsigned long julong; +#define jlong_MAXINT 0x7fffffffffffffffL +#define jlong_MININT 0x8000000000000000L +#define jlong_ZERO 0x0L + +#elif (defined(WIN32) || defined(_WIN32)) + +typedef LONGLONG jlong; +typedef DWORDLONG julong; +#define jlong_MAXINT 0x7fffffffffffffffi64 +#define jlong_MININT 0x8000000000000000i64 +#define jlong_ZERO 0x0i64 + +#else + +typedef long long jlong; +typedef unsigned long long julong; +#define jlong_MAXINT 0x7fffffffffffffffLL +#define jlong_MININT 0x8000000000000000LL +#define jlong_ZERO 0x0LL + +#endif + +#define jlong_IS_ZERO(a) ((a) == 0) +#define jlong_EQ(a, b) ((a) == (b)) +#define jlong_NE(a, b) ((a) != (b)) +#define jlong_GE_ZERO(a) ((a) >= 0) +#define jlong_CMP(a, op, b) ((a) op (b)) + +#define jlong_AND(r, a, b) ((r) = (a) & (b)) +#define jlong_OR(r, a, b) ((r) = (a) | (b)) +#define jlong_XOR(r, a, b) ((r) = (a) ^ (b)) +#define jlong_OR2(r, a) ((r) = (r) | (a)) +#define jlong_NOT(r, a) ((r) = ~(a)) + +#define jlong_NEG(r, a) ((r) = -(a)) +#define jlong_ADD(r, a, b) ((r) = (a) + (b)) +#define jlong_SUB(r, a, b) ((r) = (a) - (b)) + +#define jlong_MUL(r, a, b) ((r) = (a) * (b)) +#define jlong_DIV(r, a, b) ((r) = (a) / (b)) +#define jlong_MOD(r, a, b) ((r) = (a) % (b)) + +#define jlong_SHL(r, a, b) ((r) = (a) << (b)) +#define jlong_SHR(r, a, b) ((r) = (a) >> (b)) +#define jlong_USHR(r, a, b) ((r) = (julong)(a) >> (b)) +#define jlong_ISHL(r, a, b) ((r) = ((jlong)(a)) << (b)) + +#define jlong_L2I(i, l) ((i) = (int)(l)) +#define jlong_L2UI(ui, l) ((ui) =(unsigned int)(l)) +#define jlong_L2F(f, l) ((f) = (l)) +#define jlong_L2D(d, l) ((d) = (l)) + +#define jlong_I2L(l, i) ((l) = (i)) +#define jlong_UI2L(l, ui) ((l) = (ui)) +#define jlong_F2L(l, f) ((l) = (f)) +#define jlong_D2L(l, d) ((l) = (d)) + +#define jlong_UDIVMOD(qp, rp, a, b) \ + (*(qp) = ((julong)(a) / (b)), \ + *(rp) = ((julong)(a) % (b))) + +#else /* !HAVE_LONG_LONG */ + +typedef struct { +#ifdef IS_LITTLE_ENDIAN + juint lo, hi; +#else + juint hi, lo; +#endif +} jlong; +typedef jlong julong; + +extern jlong jlong_MAXINT, jlong_MININT, jlong_ZERO; + +#define jlong_IS_ZERO(a) (((a).hi == 0) && ((a).lo == 0)) +#define jlong_EQ(a, b) (((a).hi == (b).hi) && ((a).lo == (b).lo)) +#define jlong_NE(a, b) (((a).hi != (b).hi) || ((a).lo != (b).lo)) +#define jlong_GE_ZERO(a) (((a).hi >> 31) == 0) + +/* + * NB: jlong_CMP and jlong_UCMP work only for strict relationals (<, >). + */ +#define jlong_CMP(a, op, b) (((int32)(a).hi op (int32)(b).hi) || \ + (((a).hi == (b).hi) && ((a).lo op (b).lo))) +#define jlong_UCMP(a, op, b) (((a).hi op (b).hi) || \ + (((a).hi == (b).hi) && ((a).lo op (b).lo))) + +#define jlong_AND(r, a, b) ((r).lo = (a).lo & (b).lo, \ + (r).hi = (a).hi & (b).hi) +#define jlong_OR(r, a, b) ((r).lo = (a).lo | (b).lo, \ + (r).hi = (a).hi | (b).hi) +#define jlong_XOR(r, a, b) ((r).lo = (a).lo ^ (b).lo, \ + (r).hi = (a).hi ^ (b).hi) +#define jlong_OR2(r, a) ((r).lo = (r).lo | (a).lo, \ + (r).hi = (r).hi | (a).hi) +#define jlong_NOT(r, a) ((r).lo = ~(a).lo, \ + (r).hi = ~(a).hi) + +#define jlong_NEG(r, a) ((r).lo = -(int32)(a).lo, \ + (r).hi = -(int32)(a).hi - ((r).lo != 0)) +#define jlong_ADD(r, a, b) { \ + jlong _a, _b; \ + _a = a; _b = b; \ + (r).lo = _a.lo + _b.lo; \ + (r).hi = _a.hi + _b.hi + ((r).lo < _b.lo); \ +} + +#define jlong_SUB(r, a, b) { \ + jlong _a, _b; \ + _a = a; _b = b; \ + (r).lo = _a.lo - _b.lo; \ + (r).hi = _a.hi - _b.hi - (_a.lo < _b.lo); \ +} \ + +/* + * Multiply 64-bit operands a and b to get 64-bit result r. + * First multiply the low 32 bits of a and b to get a 64-bit result in r. + * Then add the outer and inner products to r.hi. + */ +#define jlong_MUL(r, a, b) { \ + jlong _a, _b; \ + _a = a; _b = b; \ + jlong_MUL32(r, _a.lo, _b.lo); \ + (r).hi += _a.hi * _b.lo + _a.lo * _b.hi; \ +} + +/* XXX _jlong_lo16(a) = ((a) << 16 >> 16) is better on some archs (not on mips) */ +#define _jlong_lo16(a) ((a) & JRI_BITMASK(16)) +#define _jlong_hi16(a) ((a) >> 16) + +/* + * Multiply 32-bit operands a and b to get 64-bit result r. + * Use polynomial expansion based on primitive field element (1 << 16). + */ +#define jlong_MUL32(r, a, b) { \ + juint _a1, _a0, _b1, _b0, _y0, _y1, _y2, _y3; \ + _a1 = _jlong_hi16(a), _a0 = _jlong_lo16(a); \ + _b1 = _jlong_hi16(b), _b0 = _jlong_lo16(b); \ + _y0 = _a0 * _b0; \ + _y1 = _a0 * _b1; \ + _y2 = _a1 * _b0; \ + _y3 = _a1 * _b1; \ + _y1 += _jlong_hi16(_y0); /* can't carry */ \ + _y1 += _y2; /* might carry */ \ + if (_y1 < _y2) _y3 += 1 << 16; /* propagate */ \ + (r).lo = (_jlong_lo16(_y1) << 16) + _jlong_lo16(_y0); \ + (r).hi = _y3 + _jlong_hi16(_y1); \ +} + +/* + * Divide 64-bit unsigned operand a by 64-bit unsigned operand b, setting *qp + * to the 64-bit unsigned quotient, and *rp to the 64-bit unsigned remainder. + * Minimize effort if one of qp and rp is null. + */ +#define jlong_UDIVMOD(qp, rp, a, b) jlong_udivmod(qp, rp, a, b) + +extern JRI_PUBLIC_API(void) +jlong_udivmod(julong *qp, julong *rp, julong a, julong b); + +#define jlong_DIV(r, a, b) { \ + jlong _a, _b; \ + juint _negative = (int32)(a).hi < 0; \ + if (_negative) { \ + jlong_NEG(_a, a); \ + } else { \ + _a = a; \ + } \ + if ((int32)(b).hi < 0) { \ + _negative ^= 1; \ + jlong_NEG(_b, b); \ + } else { \ + _b = b; \ + } \ + jlong_UDIVMOD(&(r), 0, _a, _b); \ + if (_negative) \ + jlong_NEG(r, r); \ +} + +#define jlong_MOD(r, a, b) { \ + jlong _a, _b; \ + juint _negative = (int32)(a).hi < 0; \ + if (_negative) { \ + jlong_NEG(_a, a); \ + } else { \ + _a = a; \ + } \ + if ((int32)(b).hi < 0) { \ + jlong_NEG(_b, b); \ + } else { \ + _b = b; \ + } \ + jlong_UDIVMOD(0, &(r), _a, _b); \ + if (_negative) \ + jlong_NEG(r, r); \ +} + +/* + * NB: b is a juint, not jlong or julong, for the shift ops. + */ +#define jlong_SHL(r, a, b) { \ + if (b) { \ + jlong _a; \ + _a = a; \ + if ((b) < 32) { \ + (r).lo = _a.lo << (b); \ + (r).hi = (_a.hi << (b)) | (_a.lo >> (32 - (b))); \ + } else { \ + (r).lo = 0; \ + (r).hi = _a.lo << ((b) & 31); \ + } \ + } else { \ + (r) = (a); \ + } \ +} + +/* a is an int32, b is int32, r is jlong */ +#define jlong_ISHL(r, a, b) { \ + if (b) { \ + jlong _a; \ + _a.lo = (a); \ + _a.hi = 0; \ + if ((b) < 32) { \ + (r).lo = (a) << (b); \ + (r).hi = ((a) >> (32 - (b))); \ + } else { \ + (r).lo = 0; \ + (r).hi = (a) << ((b) & 31); \ + } \ + } else { \ + (r).lo = (a); \ + (r).hi = 0; \ + } \ +} + +#define jlong_SHR(r, a, b) { \ + if (b) { \ + jlong _a; \ + _a = a; \ + if ((b) < 32) { \ + (r).lo = (_a.hi << (32 - (b))) | (_a.lo >> (b)); \ + (r).hi = (int32)_a.hi >> (b); \ + } else { \ + (r).lo = (int32)_a.hi >> ((b) & 31); \ + (r).hi = (int32)_a.hi >> 31; \ + } \ + } else { \ + (r) = (a); \ + } \ +} + +#define jlong_USHR(r, a, b) { \ + if (b) { \ + jlong _a; \ + _a = a; \ + if ((b) < 32) { \ + (r).lo = (_a.hi << (32 - (b))) | (_a.lo >> (b)); \ + (r).hi = _a.hi >> (b); \ + } else { \ + (r).lo = _a.hi >> ((b) & 31); \ + (r).hi = 0; \ + } \ + } else { \ + (r) = (a); \ + } \ +} + +#define jlong_L2I(i, l) ((i) = (l).lo) +#define jlong_L2UI(ui, l) ((ui) = (l).lo) +#define jlong_L2F(f, l) { double _d; jlong_L2D(_d, l); (f) = (float) _d; } + +#define jlong_L2D(d, l) { \ + int32 _negative; \ + jlong _absval; \ + \ + _negative = (l).hi >> 31; \ + if (_negative) { \ + jlong_NEG(_absval, l); \ + } else { \ + _absval = l; \ + } \ + (d) = (double)_absval.hi * 4.294967296e9 + _absval.lo; \ + if (_negative) \ + (d) = -(d); \ +} + +#define jlong_I2L(l, i) ((l).hi = (i) >> 31, (l).lo = (i)) +#define jlong_UI2L(l, ui) ((l).hi = 0, (l).lo = (ui)) +#define jlong_F2L(l, f) { double _d = (double) f; jlong_D2L(l, _d); } + +#define jlong_D2L(l, d) { \ + int _negative; \ + double _absval, _d_hi; \ + jlong _lo_d; \ + \ + _negative = ((d) < 0); \ + _absval = _negative ? -(d) : (d); \ + \ + (l).hi = (juint)(_absval / 4.294967296e9); \ + (l).lo = 0; \ + jlong_L2D(_d_hi, l); \ + _absval -= _d_hi; \ + _lo_d.hi = 0; \ + if (_absval < 0) { \ + _lo_d.lo = (juint) -_absval; \ + jlong_SUB(l, l, _lo_d); \ + } else { \ + _lo_d.lo = (juint) _absval; \ + jlong_ADD(l, l, _lo_d); \ + } \ + \ + if (_negative) \ + jlong_NEG(l, l); \ +} + +#endif /* !HAVE_LONG_LONG */ + +/******************************************************************************/ + +#ifdef HAVE_ALIGNED_LONGLONGS +#define JRI_GET_INT64(_t,_addr) ( ((_t).x[0] = ((jint*)(_addr))[0]), \ + ((_t).x[1] = ((jint*)(_addr))[1]), \ + (_t).l ) +#define JRI_SET_INT64(_t, _addr, _v) ( (_t).l = (_v), \ + ((jint*)(_addr))[0] = (_t).x[0], \ + ((jint*)(_addr))[1] = (_t).x[1] ) +#else +#define JRI_GET_INT64(_t,_addr) (*(jlong*)(_addr)) +#define JRI_SET_INT64(_t, _addr, _v) (*(jlong*)(_addr) = (_v)) +#endif + +/* If double's must be aligned on doubleword boundaries then define this */ +#ifdef HAVE_ALIGNED_DOUBLES +#define JRI_GET_DOUBLE(_t,_addr) ( ((_t).x[0] = ((jint*)(_addr))[0]), \ + ((_t).x[1] = ((jint*)(_addr))[1]), \ + (_t).d ) +#define JRI_SET_DOUBLE(_t, _addr, _v) ( (_t).d = (_v), \ + ((jint*)(_addr))[0] = (_t).x[0], \ + ((jint*)(_addr))[1] = (_t).x[1] ) +#else +#define JRI_GET_DOUBLE(_t,_addr) (*(jdouble*)(_addr)) +#define JRI_SET_DOUBLE(_t, _addr, _v) (*(jdouble*)(_addr) = (_v)) +#endif + +/******************************************************************************/ +#ifdef __cplusplus +} +#endif +#endif /* JRI_MD_H */ +/******************************************************************************/ diff --git a/Templates/Empty/web/source/npplugin/windows/jritypes.h b/Templates/Empty/web/source/npplugin/windows/jritypes.h new file mode 100644 index 000000000..2ef14aebe --- /dev/null +++ b/Templates/Empty/web/source/npplugin/windows/jritypes.h @@ -0,0 +1,243 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/******************************************************************************* + * Java Runtime Interface + ******************************************************************************/ + +#ifndef JRITYPES_H +#define JRITYPES_H + +#include "jri_md.h" +#include "jni.h" +#include <stddef.h> +#include <stdlib.h> +#include <stdarg.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * Types + ******************************************************************************/ + +struct JRIEnvInterface; + +typedef void* JRIRef; +typedef void* JRIGlobalRef; + +typedef jint JRIFieldID; +typedef jint JRIMethodID; + +/* synonyms: */ +typedef JRIGlobalRef jglobal; + +typedef union JRIValue { + jbool z; + jbyte b; + jchar c; + jshort s; + jint i; + jlong l; + jfloat f; + jdouble d; + jref r; +} JRIValue; + +typedef enum JRIBoolean { + JRIFalse = 0, + JRITrue = 1 +} JRIBoolean; + +typedef enum JRIConstant { + JRIUninitialized = -1 +} JRIConstant; + +/* convenience types (these must be distinct struct types for c++ overloading): */ +#if 0 /* now in jni.h */ +typedef struct jbooleanArrayStruct* jbooleanArray; +typedef struct jbyteArrayStruct* jbyteArray; +typedef struct jcharArrayStruct* jcharArray; +typedef struct jshortArrayStruct* jshortArray; +typedef struct jintArrayStruct* jintArray; +typedef struct jlongArrayStruct* jlongArray; +typedef struct jfloatArrayStruct* jfloatArray; +typedef struct jdoubleArrayStruct* jdoubleArray; +typedef struct jobjectArrayStruct* jobjectArray; +#endif +typedef struct jstringArrayStruct* jstringArray; +typedef struct jarrayArrayStruct* jarrayArray; + +#define JRIConstructorMethodName "<init>" + +/******************************************************************************* + * Signature Construction Macros + ******************************************************************************/ + +/* +** These macros can be used to construct signature strings. Hopefully their names +** are a little easier to remember than the single character they correspond to. +** For example, to specify the signature of the method: +** +** public int read(byte b[], int off, int len); +** +** you could write something like this in C: +** +** char* readSig = JRISigMethod(JRISigArray(JRISigByte) +** JRISigInt +** JRISigInt) JRISigInt; +** +** Of course, don't put commas between the types. +*/ +#define JRISigArray(T) "[" T +#define JRISigByte "B" +#define JRISigChar "C" +#define JRISigClass(name) "L" name ";" +#define JRISigFloat "F" +#define JRISigDouble "D" +#define JRISigMethod(args) "(" args ")" +#define JRISigNoArgs "" +#define JRISigInt "I" +#define JRISigLong "J" +#define JRISigShort "S" +#define JRISigVoid "V" +#define JRISigBoolean "Z" + +/******************************************************************************* + * Environments + ******************************************************************************/ + +extern JRI_PUBLIC_API(const struct JRIEnvInterface**) +JRI_GetCurrentEnv(void); + +/******************************************************************************* + * Specific Scalar Array Types + ******************************************************************************/ + +/* +** The JRI Native Method Interface does not support boolean arrays. This +** is to allow Java runtime implementations to optimize boolean array +** storage. Using the ScalarArray operations on boolean arrays is bound +** to fail, so convert any boolean arrays to byte arrays in Java before +** passing them to a native method. +*/ + +#define JRI_NewByteArray(env, length, initialValues) \ + JRI_NewScalarArray(env, length, JRISigByte, (jbyte*)(initialValues)) +#define JRI_GetByteArrayLength(env, array) \ + JRI_GetScalarArrayLength(env, array) +#define JRI_GetByteArrayElements(env, array) \ + JRI_GetScalarArrayElements(env, array) + +#define JRI_NewCharArray(env, length, initialValues) \ + JRI_NewScalarArray(env, ((length) * sizeof(jchar)), JRISigChar, (jbyte*)(initialValues)) +#define JRI_GetCharArrayLength(env, array) \ + JRI_GetScalarArrayLength(env, array) +#define JRI_GetCharArrayElements(env, array) \ + ((jchar*)JRI_GetScalarArrayElements(env, array)) + +#define JRI_NewShortArray(env, length, initialValues) \ + JRI_NewScalarArray(env, ((length) * sizeof(jshort)), JRISigShort, (jbyte*)(initialValues)) +#define JRI_GetShortArrayLength(env, array) \ + JRI_GetScalarArrayLength(env, array) +#define JRI_GetShortArrayElements(env, array) \ + ((jshort*)JRI_GetScalarArrayElements(env, array)) + +#define JRI_NewIntArray(env, length, initialValues) \ + JRI_NewScalarArray(env, ((length) * sizeof(jint)), JRISigInt, (jbyte*)(initialValues)) +#define JRI_GetIntArrayLength(env, array) \ + JRI_GetScalarArrayLength(env, array) +#define JRI_GetIntArrayElements(env, array) \ + ((jint*)JRI_GetScalarArrayElements(env, array)) + +#define JRI_NewLongArray(env, length, initialValues) \ + JRI_NewScalarArray(env, ((length) * sizeof(jlong)), JRISigLong, (jbyte*)(initialValues)) +#define JRI_GetLongArrayLength(env, array) \ + JRI_GetScalarArrayLength(env, array) +#define JRI_GetLongArrayElements(env, array) \ + ((jlong*)JRI_GetScalarArrayElements(env, array)) + +#define JRI_NewFloatArray(env, length, initialValues) \ + JRI_NewScalarArray(env, ((length) * sizeof(jfloat)), JRISigFloat, (jbyte*)(initialValues)) +#define JRI_GetFloatArrayLength(env, array) \ + JRI_GetScalarArrayLength(env, array) +#define JRI_GetFloatArrayElements(env, array) \ + ((jfloat*)JRI_GetScalarArrayElements(env, array)) + +#define JRI_NewDoubleArray(env, length, initialValues) \ + JRI_NewScalarArray(env, ((length) * sizeof(jdouble)), JRISigDouble, (jbyte*)(initialValues)) +#define JRI_GetDoubleArrayLength(env, array) \ + JRI_GetScalarArrayLength(env, array) +#define JRI_GetDoubleArrayElements(env, array) \ + ((jdouble*)JRI_GetScalarArrayElements(env, array)) + +/******************************************************************************/ +/* +** JDK Stuff -- This stuff is still needed while we're using the JDK +** dynamic linking strategy to call native methods. +*/ + +typedef union JRI_JDK_stack_item { + /* Non pointer items */ + jint i; + jfloat f; + jint o; + /* Pointer items */ + void *h; + void *p; + unsigned char *addr; +#ifdef IS_64 + double d; + long l; /* == 64bits! */ +#endif +} JRI_JDK_stack_item; + +typedef union JRI_JDK_Java8Str { + jint x[2]; + jdouble d; + jlong l; + void *p; + float f; +} JRI_JDK_Java8; + +/******************************************************************************/ +#ifdef __cplusplus +} +#endif +#endif /* JRITYPES_H */ +/******************************************************************************/ diff --git a/Templates/Empty/web/source/npplugin/windows/npWebGamePlugin.cpp b/Templates/Empty/web/source/npplugin/windows/npWebGamePlugin.cpp new file mode 100644 index 000000000..0a68f8ff4 --- /dev/null +++ b/Templates/Empty/web/source/npplugin/windows/npWebGamePlugin.cpp @@ -0,0 +1,173 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#include <string> +#include <vector> + +#include "npWebGamePlugin.h" +#include "../../common/webCommon.h" + +NPWebGamePlugin* NPWebGamePlugin::sInstance = NULL; + + +// we use a timer to update the Torque 3D game loop (tick) and handle rendering +VOID CALLBACK MyTimerProc( HWND hwnd, // handle to window for timer messages + UINT message, // WM_TIMER message + UINT idTimer, // timer identifier + DWORD dwTime) // current system time +{ + static bool reentrant = false; + + if (!reentrant) + { + reentrant = true; + torque_enginetick(); + reentrant = false; + } +} + +// custom window proc for our plugin's rendering window +static LRESULT CALLBACK NPWebGamePluginWinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + NPWebGamePlugin* plugin = (NPWebGamePlugin*)GetWindowLongPtr(hWnd, GWL_USERDATA); + if (plugin) + { + switch (msg) + { + case WM_MOUSEACTIVATE: + break; + case WM_SIZE: + // handle resize of browser (sub)window updating our Torque 3D child window accordingly + int width = (int) LOWORD( lParam ); + int height = (int) HIWORD( lParam ); + torque_resizewindow(width,height); + + break; + } + + return CallWindowProc((WNDPROC)plugin->mOriginalWinProc, hWnd, msg, wParam, lParam); + } + else + { + return DefWindowProc(hWnd, msg, wParam, lParam); + } +} + +// DLL Entry Point +extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) +{ + WebCommon::gPluginModule = (HMODULE) hInstance; + return TRUE; +} + +NPWebGamePlugin::NPWebGamePlugin(NPP aInstance) +{ + + mOpen = FALSE; + mInstance = aInstance; + sInstance = this; + + mOriginalWinProc = NULL; + mHwnd = NULL; + +} + +NPWebGamePlugin::~NPWebGamePlugin() +{ + Close(); + sInstance = NULL; +} + + +NPBool NPWebGamePlugin::Open(NPWindow* aWindow) +{ + if (mOpen) + { + return TRUE; //firefox tries to open 2x + } + + if (!aWindow) + return FALSE; + + void* platformWindow = NULL; + + mHwnd = (HWND)aWindow->window; + + if (!mHwnd) + return FALSE; + + platformWindow = mHwnd; + + // replace our plugin window proc with a custom one (for handling resizing,etc) + mOriginalWinProc = SetWindowLongPtr(mHwnd, GWLP_WNDPROC, (LONG_PTR)NPWebGamePluginWinProc); + + LONG lStyle = GetWindowLong(mHwnd, GWL_STYLE); + SetWindowLong(mHwnd, GWL_STYLE, lStyle | WS_CLIPCHILDREN); + + SetWindowLongPtr(mHwnd, GWL_USERDATA, (LONG_PTR)this); + + + // load up the Torque 3D shared library and initialize it + if (!WebCommon::InitTorque3D(platformWindow)) + return false; + + mOpen = true; + + // fire up our tick/update timer + SetTimer( mHwnd, 1, // timer identifier + 1, // 1 millisecond + (TIMERPROC) MyTimerProc); // timer callback + + return mOpen; +} + +void NPWebGamePlugin::Close() +{ + + if (!mOpen) + return; + + if (mOriginalWinProc) + { + // restore original window proc + SetWindowLongPtr(mHwnd, GWLP_WNDPROC, mOriginalWinProc); + mOriginalWinProc = NULL; + } + + if (mHwnd) + { + // no more ticks please + KillTimer( mHwnd, 1); + } + + mHwnd = NULL; + + // shutdown and unload the Torque 3D DLL + WebCommon::ShutdownTorque3D(); + + mOpen = false; +} + +NPBool NPWebGamePlugin::IsOpen() +{ + return mOpen; +} diff --git a/Templates/Empty/web/source/npplugin/windows/npWebGamePlugin.def b/Templates/Empty/web/source/npplugin/windows/npWebGamePlugin.def new file mode 100644 index 000000000..f32e3563a --- /dev/null +++ b/Templates/Empty/web/source/npplugin/windows/npWebGamePlugin.def @@ -0,0 +1,6 @@ + + +EXPORTS + NP_GetEntryPoints @1 + NP_Initialize @2 + NP_Shutdown @3 diff --git a/Templates/Empty/web/source/npplugin/windows/npWebGamePlugin.h b/Templates/Empty/web/source/npplugin/windows/npWebGamePlugin.h new file mode 100644 index 000000000..a18a370a6 --- /dev/null +++ b/Templates/Empty/web/source/npplugin/windows/npWebGamePlugin.h @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +#pragma once + +#include "np_pluginbase.h" + +// Windows specific NP plugin interface for handling platform window integration with Torque 3D +class NPWebGamePlugin +{ +public: + + NPWebGamePlugin(NPP aInstance); + ~NPWebGamePlugin(); + + // very simple interface based on browser window opening/closing + NPBool Open(NPWindow* aWindow); + void Close(); + NPBool IsOpen(); + + // plugin instance + NPP mInstance; + bool mOpen; + + static NPWebGamePlugin* sInstance; + + // Browser platform native window handle + HWND mHwnd; + LONG_PTR mOriginalWinProc; + +}; + + diff --git a/Templates/Empty/web/source/npplugin/windows/np_plat.h b/Templates/Empty/web/source/npplugin/windows/np_plat.h new file mode 100644 index 000000000..18d9c3e4e --- /dev/null +++ b/Templates/Empty/web/source/npplugin/windows/np_plat.h @@ -0,0 +1,166 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef _NPPLAT_H_ +#define _NPPLAT_H_ + +#ifdef XP_WIN + +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef WINVER // Allow use of features specific to Windows XP or later. +#define WINVER 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#include <windows.h> +#include <windowsx.h> + +#endif // XP_WIN + +#include "npapi.h" +#include "npupp.h" + +/**************************************************/ +/* */ +/* Windows */ +/* */ +/**************************************************/ +#ifdef XP_WIN + +//#include "windows.h" + +#endif //XP_WIN + +/**************************************************/ +/* */ +/* Unix */ +/* */ +/**************************************************/ +#ifdef XP_UNIX +#include <stdio.h> +#endif //XP_UNIX + +/**************************************************/ +/* */ +/* Mac */ +/* */ +/**************************************************/ +#ifdef XP_MAC + +#include <Processes.h> +#include <Gestalt.h> +#include <CodeFragments.h> +#include <Timer.h> +#include <Resources.h> +#include <ToolUtils.h> + +// The Mixed Mode procInfos defined in npupp.h assume Think C- +// style calling conventions. These conventions are used by +// Metrowerks with the exception of pointer return types, which +// in Metrowerks 68K are returned in A0, instead of the standard +// D0. Thus, since NPN_MemAlloc and NPN_UserAgent return pointers, +// Mixed Mode will return the values to a 68K plugin in D0, but +// a 68K plugin compiled by Metrowerks will expect the result in +// A0. The following pragma forces Metrowerks to use D0 instead. +// +#ifdef __MWERKS__ +#ifndef powerc +#pragma pointers_in_D0 +#endif +#endif + +#ifdef __MWERKS__ +#ifndef powerc +#pragma pointers_in_A0 +#endif +#endif + +// The following fix for static initializers (which fixes a preious +// incompatibility with some parts of PowerPlant, was submitted by +// Jan Ulbrich. +#ifdef __MWERKS__ + #ifdef __cplusplus + extern "C" { + #endif + #ifndef powerc + extern void __InitCode__(void); + #else + extern void __sinit(void); + #define __InitCode__ __sinit + #endif + extern void __destroy_global_chain(void); + #ifdef __cplusplus + } + #endif // __cplusplus +#endif // __MWERKS__ + +// Wrapper functions for all calls from Netscape to the plugin. +// These functions let the plugin developer just create the APIs +// as documented and defined in npapi.h, without needing to +// install those functions in the function table or worry about +// setting up globals for 68K plugins. +NPError Private_Initialize(void); +void Private_Shutdown(void); +NPError Private_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved); +NPError Private_Destroy(NPP instance, NPSavedData** save); +NPError Private_SetWindow(NPP instance, NPWindow* window); +NPError Private_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype); +NPError Private_DestroyStream(NPP instance, NPStream* stream, NPError reason); +int32 Private_WriteReady(NPP instance, NPStream* stream); +int32 Private_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer); +void Private_StreamAsFile(NPP instance, NPStream* stream, const char* fname); +void Private_Print(NPP instance, NPPrint* platformPrint); +int16 Private_HandleEvent(NPP instance, void* event); +void Private_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData); +NPError Private_GetValue(NPP instance, NPPVariable variable, void *result); +NPError Private_SetValue(NPP instance, NPNVariable variable, void *value); + +#endif //XP_MAC + +#ifndef HIBYTE +#define HIBYTE(i) (i >> 8) +#endif + +#ifndef LOBYTE +#define LOBYTE(i) (i & 0xff) +#endif + +#endif //_NPPLAT_H_ diff --git a/Templates/Empty/web/source/npplugin/windows/np_pluginbase.h b/Templates/Empty/web/source/npplugin/windows/np_pluginbase.h new file mode 100644 index 000000000..e5e6fd037 --- /dev/null +++ b/Templates/Empty/web/source/npplugin/windows/np_pluginbase.h @@ -0,0 +1,94 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef N_NP_PLUGIN_BASE_H +#define N_NP_PLUGIN_BASE_H + +#include "np_plat.h" + +struct NPPluginCreateData +{ + NPP instance; + NPMIMEType type; + uint16 mode; + int16 argc; + char** argn; + char** argv; + NPSavedData* saved; +}; + +class NPPluginBase +{ +public: + // these three methods must be implemented in the derived + // class platform specific way + virtual NPBool Open(NPWindow* aWindow) = 0; + virtual void Close() = 0; + virtual NPBool IsOpen() = 0; + + // implement all or part of those methods in the derived + // class as needed + virtual NPError SetWindow(NPWindow* pNPWindow) { return NPERR_NO_ERROR; } + virtual NPError NewStream(NPMIMEType type, NPStream* stream, + NPBool seekable, uint16* stype) { return NPERR_NO_ERROR; } + virtual NPError DestroyStream(NPStream *stream, NPError reason) { return NPERR_NO_ERROR; } + virtual void StreamAsFile(NPStream* stream, const char* fname) { return; } + virtual int32 WriteReady(NPStream *stream) { return 0x0fffffff; } + virtual int32 Write(NPStream *stream, int32 offset, + int32 len, void *buffer) { return len; } + virtual void Print(NPPrint* printInfo) { return; } + virtual uint16 HandleEvent(void* event) { return 0; } + virtual void URLNotify(const char* url, NPReason reason, + void* notifyData) { return; } + virtual NPError GetValue(NPPVariable variable, void *value) { return NPERR_NO_ERROR; } + virtual NPError SetValue(NPNVariable variable, void *value) { return NPERR_NO_ERROR; } +}; + +// functions that should be implemented for each specific plugin + +NPError NS_PluginInitialize(); +void NS_PluginShutdown(); + +// creation and destruction of the object of the derived class +NPPluginBase* NS_NewPluginInstance(NPPluginCreateData * aCreateDataStruct); +void NS_DestroyPluginInstance(NPPluginBase * aPlugin); + +#ifdef XP_UNIX +// global to get plugins name & description +NPError NS_PluginGetValue(NPPVariable aVariable, void *aValue); +#endif + +#endif // N_NP_PLUGIN_BASE_H diff --git a/Templates/Empty/web/source/npplugin/windows/npapi.h b/Templates/Empty/web/source/npplugin/windows/npapi.h new file mode 100644 index 000000000..6f783a1dd --- /dev/null +++ b/Templates/Empty/web/source/npplugin/windows/npapi.h @@ -0,0 +1,766 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + + +/* + * npapi.h $Revision: 3.48 $ + * Netscape client plug-in API spec + */ + +#ifndef _NPAPI_H_ +#define _NPAPI_H_ + +#ifdef __OS2__ +#pragma pack(1) +#endif + +#include "prtypes.h" +/* Copied from xp_core.h */ +/* removed #ifdef for hpux defined in /usr/include/model.h */ +#ifndef _INT16 +#define _INT16 +#endif +#ifndef _INT32 +#define _INT32 +#endif +#ifndef _UINT16 +#define _UINT16 +#endif +#ifndef _UINT32 +#define _UINT32 +#endif + +/* + * NO_NSPR_10_SUPPORT disables the inclusion + * of obsolete/protypes.h, whose int16, uint16, + * int32, and uint32 typedefs conflict with those + * in this file. + */ +#ifndef NO_NSPR_10_SUPPORT +#define NO_NSPR_10_SUPPORT +#endif +#ifdef OJI +#include "jri.h" /* Java Runtime Interface */ +#endif + +#if defined (__OS2__ ) || defined (OS2) +# ifndef XP_OS2 +# define XP_OS2 1 +# endif /* XP_OS2 */ +#endif /* __OS2__ */ + +#ifdef _WINDOWS +# include <windef.h> +# ifndef XP_WIN +# define XP_WIN 1 +# endif /* XP_WIN */ +#endif /* _WINDOWS */ + +#ifdef __MWERKS__ +# define _declspec __declspec +# ifdef __INTEL__ +# undef NULL +# ifndef XP_WIN +# define XP_WIN 1 +# endif /* XP_WIN */ +# endif /* __INTEL__ */ +#endif /* __MWERKS__ */ + +#ifdef XP_MACOSX +#include <Carbon/Carbon.h> +#ifdef __LP64__ +#define NP_NO_QUICKDRAW +#endif +#endif + +#if defined(XP_UNIX) +# include <stdio.h> +# if defined(MOZ_X11) +# include <X11/Xlib.h> +# include <X11/Xutil.h> +# endif +#endif + +/*----------------------------------------------------------------------*/ +/* Plugin Version Constants */ +/*----------------------------------------------------------------------*/ + +#define NP_VERSION_MAJOR 0 +#define NP_VERSION_MINOR 19 + + +/* The OS/2 version of Netscape uses RC_DATA to define the + mime types, file extensions, etc that are required. + Use a vertical bar to separate types, end types with \0. + FileVersion and ProductVersion are 32bit ints, all other + entries are strings the MUST be terminated wwith a \0. + +AN EXAMPLE: + +RCDATA NP_INFO_ProductVersion { 1,0,0,1,} + +RCDATA NP_INFO_MIMEType { "video/x-video|", + "video/x-flick\0" } +RCDATA NP_INFO_FileExtents { "avi|", + "flc\0" } +RCDATA NP_INFO_FileOpenName{ "MMOS2 video player(*.avi)|", + "MMOS2 Flc/Fli player(*.flc)\0" } + +RCDATA NP_INFO_FileVersion { 1,0,0,1 } +RCDATA NP_INFO_CompanyName { "Netscape Communications\0" } +RCDATA NP_INFO_FileDescription { "NPAVI32 Extension DLL\0" +RCDATA NP_INFO_InternalName { "NPAVI32\0" ) +RCDATA NP_INFO_LegalCopyright { "Copyright Netscape Communications \251 1996\0" +RCDATA NP_INFO_OriginalFilename { "NVAPI32.DLL" } +RCDATA NP_INFO_ProductName { "NPAVI32 Dynamic Link Library\0" } + +*/ + + +/* RC_DATA types for version info - required */ +#define NP_INFO_ProductVersion 1 +#define NP_INFO_MIMEType 2 +#define NP_INFO_FileOpenName 3 +#define NP_INFO_FileExtents 4 + +/* RC_DATA types for version info - used if found */ +#define NP_INFO_FileDescription 5 +#define NP_INFO_ProductName 6 + +/* RC_DATA types for version info - optional */ +#define NP_INFO_CompanyName 7 +#define NP_INFO_FileVersion 8 +#define NP_INFO_InternalName 9 +#define NP_INFO_LegalCopyright 10 +#define NP_INFO_OriginalFilename 11 + +#ifndef RC_INVOKED + + + +/*----------------------------------------------------------------------*/ +/* Definition of Basic Types */ +/*----------------------------------------------------------------------*/ + +#ifndef _UINT16 +typedef unsigned short uint16; +#endif + +#ifndef _UINT32 +# if defined(__alpha) || defined(__amd64__) || defined(__x86_64__) +typedef unsigned int uint32; +# else /* __alpha */ +typedef unsigned long uint32; +# endif /* __alpha */ +#endif + +/* + * AIX defines these in sys/inttypes.h included from sys/types.h + */ +#ifndef AIX +#ifndef _INT16 +typedef short int16; +#endif + +#ifndef _INT32 +# if defined(__alpha) || defined(__amd64__) || defined(__x86_64__) +typedef int int32; +# else /* __alpha */ +typedef long int32; +# endif /* __alpha */ +#endif +#endif + +#ifndef FALSE +#define FALSE (0) +#endif +#ifndef TRUE +#define TRUE (1) +#endif +#ifndef NULL +#define NULL (0L) +#endif + +#ifdef XP_MACOSX +typedef enum { +#ifndef NP_NO_QUICKDRAW + NPDrawingModelQuickDraw = 0, +#endif + NPDrawingModelCoreGraphics = 1 +} NPDrawingModel; +#endif + +typedef unsigned char NPBool; +typedef int16 NPError; +typedef int16 NPReason; +typedef char* NPMIMEType; + + + +/*----------------------------------------------------------------------*/ +/* Structures and definitions */ +/*----------------------------------------------------------------------*/ + +/* + * NPP is a plug-in's opaque instance handle + */ +typedef struct _NPP +{ + void* pdata; /* plug-in private data */ + void* ndata; /* netscape private data */ +} NPP_t; + +typedef NPP_t* NPP; + + +typedef struct _NPStream +{ + void* pdata; /* plug-in private data */ + void* ndata; /* netscape private data */ + const char* url; + uint32 end; + uint32 lastmodified; + void* notifyData; + const char* headers; /* Response headers from host. + * Exists only for >= NPVERS_HAS_RESPONSE_HEADERS. + * Used for HTTP only; NULL for non-HTTP. + * Available from NPP_NewStream onwards. + * Plugin should copy this data before storing it. + * Includes HTTP status line and all headers, + * preferably verbatim as received from server, + * headers formatted as in HTTP ("Header: Value"), + * and newlines (\n, NOT \r\n) separating lines. + * Terminated by \n\0 (NOT \n\n\0). */ +} NPStream; + + +typedef struct _NPByteRange +{ + int32 offset; /* negative offset means from the end */ + uint32 length; + struct _NPByteRange* next; +} NPByteRange; + + +typedef struct _NPSavedData +{ + int32 len; + void* buf; +} NPSavedData; + + +typedef struct _NPRect +{ + uint16 top; + uint16 left; + uint16 bottom; + uint16 right; +} NPRect; + +typedef struct _NPSize +{ + int32 width; + int32 height; +} NPSize; + +#ifdef XP_UNIX +/* + * Unix specific structures and definitions + */ + +/* + * Callback Structures. + * + * These are used to pass additional platform specific information. + */ +enum { + NP_SETWINDOW = 1, + NP_PRINT +}; + +typedef struct +{ + int32 type; +} NPAnyCallbackStruct; + +typedef struct +{ + int32 type; +#ifdef MOZ_X11 + Display* display; + Visual* visual; + Colormap colormap; + unsigned int depth; +#endif +} NPSetWindowCallbackStruct; + +typedef struct +{ + int32 type; + FILE* fp; +} NPPrintCallbackStruct; + +#endif /* XP_UNIX */ + + +/* + * The following masks are applied on certain platforms to NPNV and + * NPPV selectors that pass around pointers to COM interfaces. Newer + * compilers on some platforms may generate vtables that are not + * compatible with older compilers. To prevent older plugins from + * not understanding a new browser's ABI, these masks change the + * values of those selectors on those platforms. To remain backwards + * compatible with differenet versions of the browser, plugins can + * use these masks to dynamically determine and use the correct C++ + * ABI that the browser is expecting. This does not apply to Windows + * as Microsoft's COM ABI will likely not change. + */ + +#define NP_ABI_GCC3_MASK 0x10000000 +/* + * gcc 3.x generated vtables on UNIX and OSX are incompatible with + * previous compilers. + */ +#if (defined (XP_UNIX) && defined(__GNUC__) && (__GNUC__ >= 3)) +#define _NP_ABI_MIXIN_FOR_GCC3 NP_ABI_GCC3_MASK +#else +#define _NP_ABI_MIXIN_FOR_GCC3 0 +#endif + + +#define NP_ABI_MACHO_MASK 0x01000000 +/* + * On OSX, the Mach-O executable format is significantly + * different than CFM. In addition to having a different + * C++ ABI, it also has has different C calling convention. + * You must use glue code when calling between CFM and + * Mach-O C functions. + */ +#if (defined(TARGET_RT_MAC_MACHO)) +#define _NP_ABI_MIXIN_FOR_MACHO NP_ABI_MACHO_MASK +#else +#define _NP_ABI_MIXIN_FOR_MACHO 0 +#endif + + +#define NP_ABI_MASK (_NP_ABI_MIXIN_FOR_GCC3 | _NP_ABI_MIXIN_FOR_MACHO) + +/* + * List of variable names for which NPP_GetValue shall be implemented + */ +typedef enum { + NPPVpluginNameString = 1, + NPPVpluginDescriptionString, + NPPVpluginWindowBool, + NPPVpluginTransparentBool, + NPPVjavaClass, /* Not implemented in Mozilla 1.0 */ + NPPVpluginWindowSize, + NPPVpluginTimerInterval, + + NPPVpluginScriptableInstance = (10 | NP_ABI_MASK), + NPPVpluginScriptableIID = 11, + + /* Introduced in Mozilla 0.9.9 */ + NPPVjavascriptPushCallerBool = 12, + + /* Introduced in Mozilla 1.0 */ + NPPVpluginKeepLibraryInMemory = 13, + NPPVpluginNeedsXEmbed = 14, + + /* Get the NPObject for scripting the plugin. Introduced in Firefox + * 1.0 (NPAPI minor version 14). + */ + NPPVpluginScriptableNPObject = 15, + + /* Get the plugin value (as \0-terminated UTF-8 string data) for + * form submission if the plugin is part of a form. Use + * NPN_MemAlloc() to allocate memory for the string data. Introduced + * in Mozilla 1.8b2 (NPAPI minor version 15). + */ + NPPVformValue = 16 +#ifdef XP_MACOSX + /* Used for negotiating drawing models */ + , NPPVpluginDrawingModel = 1000 +#endif +} NPPVariable; + +/* + * List of variable names for which NPN_GetValue is implemented by Mozilla + */ +typedef enum { + NPNVxDisplay = 1, + NPNVxtAppContext, + NPNVnetscapeWindow, + NPNVjavascriptEnabledBool, + NPNVasdEnabledBool, + NPNVisOfflineBool, + + /* 10 and over are available on Mozilla builds starting with 0.9.4 */ + NPNVserviceManager = (10 | NP_ABI_MASK), + NPNVDOMElement = (11 | NP_ABI_MASK), /* available in Mozilla 1.2 */ + NPNVDOMWindow = (12 | NP_ABI_MASK), + NPNVToolkit = (13 | NP_ABI_MASK), + NPNVSupportsXEmbedBool = 14, + + /* Get the NPObject wrapper for the browser window. */ + NPNVWindowNPObject = 15, + + /* Get the NPObject wrapper for the plugins DOM element. */ + NPNVPluginElementNPObject = 16, + + NPNVSupportsWindowless = 17 + +#ifdef XP_MACOSX + /* Used for negotiating drawing models */ + , NPNVpluginDrawingModel = 1000 +#ifndef NP_NO_QUICKDRAW + , NPNVsupportsQuickDrawBool = 2000 +#endif + , NPNVsupportsCoreGraphicsBool = 2001 +#endif +} NPNVariable; + +/* + * The type of Tookkit the widgets use + */ +typedef enum { + NPNVGtk12 = 1, + NPNVGtk2 +} NPNToolkitType; + +/* + * The type of a NPWindow - it specifies the type of the data structure + * returned in the window field. + */ +typedef enum { + NPWindowTypeWindow = 1, + NPWindowTypeDrawable +} NPWindowType; + +typedef struct _NPWindow +{ + void* window; /* Platform specific window handle */ + /* OS/2: x - Position of bottom left corner */ + /* OS/2: y - relative to visible netscape window */ + int32 x; /* Position of top left corner relative */ + int32 y; /* to a netscape page. */ + uint32 width; /* Maximum window size */ + uint32 height; + NPRect clipRect; /* Clipping rectangle in port coordinates */ + /* Used by MAC only. */ +#if defined(XP_UNIX) && !defined(XP_MACOSX) + void * ws_info; /* Platform-dependent additonal data */ +#endif /* XP_UNIX */ + NPWindowType type; /* Is this a window or a drawable? */ +} NPWindow; + + +typedef struct _NPFullPrint +{ + NPBool pluginPrinted;/* Set TRUE if plugin handled fullscreen printing */ + NPBool printOne; /* TRUE if plugin should print one copy to default printer */ + void* platformPrint; /* Platform-specific printing info */ +} NPFullPrint; + +typedef struct _NPEmbedPrint +{ + NPWindow window; + void* platformPrint; /* Platform-specific printing info */ +} NPEmbedPrint; + +typedef struct _NPPrint +{ + uint16 mode; /* NP_FULL or NP_EMBED */ + union + { + NPFullPrint fullPrint; /* if mode is NP_FULL */ + NPEmbedPrint embedPrint; /* if mode is NP_EMBED */ + } print; +} NPPrint; + +#ifdef XP_MACOSX +typedef EventRecord NPEvent; +#elif defined(XP_WIN) +typedef struct _NPEvent +{ + uint16 event; + uint32 wParam; + uint32 lParam; +} NPEvent; +#elif defined(XP_OS2) +typedef struct _NPEvent +{ + uint32 event; + uint32 wParam; + uint32 lParam; +} NPEvent; +#elif defined (XP_UNIX) && defined(MOZ_X11) +typedef XEvent NPEvent; +#else +typedef void* NPEvent; +#endif /* XP_MACOSX */ + +#ifdef XP_MACOSX +typedef void* NPRegion; +#ifndef NP_NO_QUICKDRAW +typedef RgnHandle NPQDRegion; +#endif +typedef CGPathRef NPCGRegion; +#elif defined(XP_WIN) +typedef HRGN NPRegion; +#elif defined(XP_UNIX) && defined(MOZ_X11) +typedef Region NPRegion; +#else +typedef void *NPRegion; +#endif /* XP_MACOSX */ + +#ifdef XP_MACOSX +/* + * Mac-specific structures and definitions. + */ + +typedef struct NP_Port +{ + CGrafPtr port; /* Grafport */ + int32 portx; /* position inside the topmost window */ + int32 porty; +} NP_Port; + +typedef struct NP_CGContext +{ + CGContextRef context; + WindowRef window; +} NP_CGContext; + +/* + * Non-standard event types that can be passed to HandleEvent + */ + +enum NPEventType { + NPEventType_GetFocusEvent = (osEvt + 16), + NPEventType_LoseFocusEvent, + NPEventType_AdjustCursorEvent, + NPEventType_MenuCommandEvent, + NPEventType_ClippingChangedEvent, + NPEventType_ScrollingBeginsEvent = 1000, + NPEventType_ScrollingEndsEvent +}; + +#ifdef OBSOLETE +#define getFocusEvent (osEvt + 16) +#define loseFocusEvent (osEvt + 17) +#define adjustCursorEvent (osEvt + 18) +#endif +#endif /* XP_MACOSX */ + +/* + * Values for mode passed to NPP_New: + */ +#define NP_EMBED 1 +#define NP_FULL 2 + +/* + * Values for stream type passed to NPP_NewStream: + */ +#define NP_NORMAL 1 +#define NP_SEEK 2 +#define NP_ASFILE 3 +#define NP_ASFILEONLY 4 + +#define NP_MAXREADY (((unsigned)(~0)<<1)>>1) + + +/*----------------------------------------------------------------------*/ +/* Error and Reason Code definitions */ +/*----------------------------------------------------------------------*/ + +/* + * Values of type NPError: + */ +#define NPERR_BASE 0 +#define NPERR_NO_ERROR (NPERR_BASE + 0) +#define NPERR_GENERIC_ERROR (NPERR_BASE + 1) +#define NPERR_INVALID_INSTANCE_ERROR (NPERR_BASE + 2) +#define NPERR_INVALID_FUNCTABLE_ERROR (NPERR_BASE + 3) +#define NPERR_MODULE_LOAD_FAILED_ERROR (NPERR_BASE + 4) +#define NPERR_OUT_OF_MEMORY_ERROR (NPERR_BASE + 5) +#define NPERR_INVALID_PLUGIN_ERROR (NPERR_BASE + 6) +#define NPERR_INVALID_PLUGIN_DIR_ERROR (NPERR_BASE + 7) +#define NPERR_INCOMPATIBLE_VERSION_ERROR (NPERR_BASE + 8) +#define NPERR_INVALID_PARAM (NPERR_BASE + 9) +#define NPERR_INVALID_URL (NPERR_BASE + 10) +#define NPERR_FILE_NOT_FOUND (NPERR_BASE + 11) +#define NPERR_NO_DATA (NPERR_BASE + 12) +#define NPERR_STREAM_NOT_SEEKABLE (NPERR_BASE + 13) + +/* + * Values of type NPReason: + */ +#define NPRES_BASE 0 +#define NPRES_DONE (NPRES_BASE + 0) +#define NPRES_NETWORK_ERR (NPRES_BASE + 1) +#define NPRES_USER_BREAK (NPRES_BASE + 2) + +/* + * Don't use these obsolete error codes any more. + */ +#define NP_NOERR NP_NOERR_is_obsolete_use_NPERR_NO_ERROR +#define NP_EINVAL NP_EINVAL_is_obsolete_use_NPERR_GENERIC_ERROR +#define NP_EABORT NP_EABORT_is_obsolete_use_NPRES_USER_BREAK + +/* + * Version feature information + */ +#define NPVERS_HAS_STREAMOUTPUT 8 +#define NPVERS_HAS_NOTIFICATION 9 +#define NPVERS_HAS_LIVECONNECT 9 +#define NPVERS_WIN16_HAS_LIVECONNECT 9 +#define NPVERS_68K_HAS_LIVECONNECT 11 +#define NPVERS_HAS_WINDOWLESS 11 +#define NPVERS_HAS_XPCONNECT_SCRIPTING 13 +#define NPVERS_HAS_NPRUNTIME_SCRIPTING 14 +#define NPVERS_HAS_FORM_VALUES 15 +#define NPVERS_HAS_POPUPS_ENABLED_STATE 16 +#define NPVERS_HAS_RESPONSE_HEADERS 17 +#define NPVERS_HAS_NPOBJECT_ENUM 18 +#define NPVERS_HAS_PLUGIN_THREAD_ASYNC_CALL 19 + +/*----------------------------------------------------------------------*/ +/* Function Prototypes */ +/*----------------------------------------------------------------------*/ + +#if defined(_WINDOWS) && !defined(WIN32) +#define NP_LOADDS _loadds +#else +#if defined(__OS2__) +#define NP_LOADDS _System +#else +#define NP_LOADDS +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * NPP_* functions are provided by the plugin and called by the navigator. + */ + +#ifdef XP_UNIX +char* NPP_GetMIMEDescription(void); +#endif /* XP_UNIX */ + +NPError NP_LOADDS NPP_Initialize(void); +void NP_LOADDS NPP_Shutdown(void); +NPError NP_LOADDS NPP_New(NPMIMEType pluginType, NPP instance, + uint16 mode, int16 argc, char* argn[], + char* argv[], NPSavedData* saved); +NPError NP_LOADDS NPP_Destroy(NPP instance, NPSavedData** save); +NPError NP_LOADDS NPP_SetWindow(NPP instance, NPWindow* window); +NPError NP_LOADDS NPP_NewStream(NPP instance, NPMIMEType type, + NPStream* stream, NPBool seekable, + uint16* stype); +NPError NP_LOADDS NPP_DestroyStream(NPP instance, NPStream* stream, + NPReason reason); +int32 NP_LOADDS NPP_WriteReady(NPP instance, NPStream* stream); +int32 NP_LOADDS NPP_Write(NPP instance, NPStream* stream, int32 offset, + int32 len, void* buffer); +void NP_LOADDS NPP_StreamAsFile(NPP instance, NPStream* stream, + const char* fname); +void NP_LOADDS NPP_Print(NPP instance, NPPrint* platformPrint); +int16 NP_LOADDS NPP_HandleEvent(NPP instance, void* event); +void NP_LOADDS NPP_URLNotify(NPP instance, const char* url, + NPReason reason, void* notifyData); +#ifdef OJI +jref NP_LOADDS NPP_GetJavaClass(void); +#endif +NPError NP_LOADDS NPP_GetValue(NPP instance, NPPVariable variable, void *value); +NPError NP_LOADDS NPP_SetValue(NPP instance, NPNVariable variable, void *value); + +/* + * NPN_* functions are provided by the navigator and called by the plugin. + */ +void NP_LOADDS NPN_Version(int* plugin_major, int* plugin_minor, + int* netscape_major, int* netscape_minor); +NPError NP_LOADDS NPN_GetURLNotify(NPP instance, const char* url, + const char* target, void* notifyData); +NPError NP_LOADDS NPN_GetURL(NPP instance, const char* url, + const char* target); +NPError NP_LOADDS NPN_PostURLNotify(NPP instance, const char* url, + const char* target, uint32 len, + const char* buf, NPBool file, + void* notifyData); +NPError NP_LOADDS NPN_PostURL(NPP instance, const char* url, + const char* target, uint32 len, + const char* buf, NPBool file); +NPError NP_LOADDS NPN_RequestRead(NPStream* stream, NPByteRange* rangeList); +NPError NP_LOADDS NPN_NewStream(NPP instance, NPMIMEType type, + const char* target, NPStream** stream); +int32 NP_LOADDS NPN_Write(NPP instance, NPStream* stream, int32 len, void* buffer); +NPError NP_LOADDS NPN_DestroyStream(NPP instance, NPStream* stream, NPReason reason); +void NP_LOADDS NPN_Status(NPP instance, const char* message); +const char* NP_LOADDS NPN_UserAgent(NPP instance); +void* NP_LOADDS NPN_MemAlloc(uint32 size); +void NP_LOADDS NPN_MemFree(void* ptr); +uint32 NP_LOADDS NPN_MemFlush(uint32 size); +void NP_LOADDS NPN_ReloadPlugins(NPBool reloadPages); +#ifdef OJI +JRIEnv* NP_LOADDS NPN_GetJavaEnv(void); +jref NP_LOADDS NPN_GetJavaPeer(NPP instance); +#endif +NPError NP_LOADDS NPN_GetValue(NPP instance, NPNVariable variable, void *value); +NPError NP_LOADDS NPN_SetValue(NPP instance, NPPVariable variable, void *value); +void NP_LOADDS NPN_InvalidateRect(NPP instance, NPRect *invalidRect); +void NP_LOADDS NPN_InvalidateRegion(NPP instance, NPRegion invalidRegion); +void NP_LOADDS NPN_ForceRedraw(NPP instance); +void NP_LOADDS NPN_PushPopupsEnabledState(NPP instance, NPBool enabled); +void NP_LOADDS NPN_PopPopupsEnabledState(NPP instance); +void NP_LOADDS NPN_PluginThreadAsyncCall(NPP instance, + void (*func) (void *), + void *userData); + +#ifdef __cplusplus +} /* end extern "C" */ +#endif + +#endif /* RC_INVOKED */ +#ifdef __OS2__ +#pragma pack() +#endif + +#endif /* _NPAPI_H_ */ diff --git a/Templates/Empty/web/source/npplugin/windows/npruntime.h b/Templates/Empty/web/source/npplugin/windows/npruntime.h new file mode 100644 index 000000000..b8421a25e --- /dev/null +++ b/Templates/Empty/web/source/npplugin/windows/npruntime.h @@ -0,0 +1,423 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Copyright © 2004, Apple Computer, Inc. and The Mozilla Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the names of Apple Computer, Inc. ("Apple") or The Mozilla + * Foundation ("Mozilla") nor the names of their contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE, MOZILLA AND THEIR CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE, MOZILLA OR + * THEIR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Revision 1 (March 4, 2004): + * Initial proposal. + * + * Revision 2 (March 10, 2004): + * All calls into script were made asynchronous. Results are + * provided via the NPScriptResultFunctionPtr callback. + * + * Revision 3 (March 10, 2004): + * Corrected comments to not refer to class retain/release FunctionPtrs. + * + * Revision 4 (March 11, 2004): + * Added additional convenience NPN_SetExceptionWithUTF8(). + * Changed NPHasPropertyFunctionPtr and NPHasMethodFunctionPtr to take NPClass + * pointers instead of NPObject pointers. + * Added NPIsValidIdentifier(). + * + * Revision 5 (March 17, 2004): + * Added context parameter to result callbacks from ScriptObject functions. + * + * Revision 6 (March 29, 2004): + * Renamed functions implemented by user agent to NPN_*. Removed _ from + * type names. + * Renamed "JavaScript" types to "Script". + * + * Revision 7 (April 21, 2004): + * NPIdentifier becomes a void*, was int32_t + * Remove NP_IsValidIdentifier, renamed NP_IdentifierFromUTF8 to NP_GetIdentifier + * Added NPVariant and modified functions to use this new type. + * + * Revision 8 (July 9, 2004): + * Updated to joint Apple-Mozilla license. + * + */ +#ifndef _NP_RUNTIME_H_ +#define _NP_RUNTIME_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "nptypes.h" + +/* + This API is used to facilitate binding code written in C to script + objects. The API in this header does not assume the presence of a + user agent. That is, it can be used to bind C code to scripting + environments outside of the context of a user agent. + + However, the normal use of the this API is in the context of a + scripting environment running in a browser or other user agent. + In particular it is used to support the extended Netscape + script-ability API for plugins (NP-SAP). NP-SAP is an extension + of the Netscape plugin API. As such we have adopted the use of + the "NP" prefix for this API. + + The following NP{N|P}Variables were added to the Netscape plugin + API (in npapi.h): + + NPNVWindowNPObject + NPNVPluginElementNPObject + NPPVpluginScriptableNPObject + + These variables are exposed through NPN_GetValue() and + NPP_GetValue() (respectively) and are used to establish the + initial binding between the user agent and native code. The DOM + objects in the user agent can be examined and manipulated using + the NPN_ functions that operate on NPObjects described in this + header. + + To the extent possible the assumptions about the scripting + language used by the scripting environment have been minimized. +*/ + +#define NP_BEGIN_MACRO do { +#define NP_END_MACRO } while (0) + +/* + Objects (non-primitive data) passed between 'C' and script is + always wrapped in an NPObject. The 'interface' of an NPObject is + described by an NPClass. +*/ +typedef struct NPObject NPObject; +typedef struct NPClass NPClass; + +typedef char NPUTF8; +typedef struct _NPString { + const NPUTF8 *UTF8Characters; + uint32_t UTF8Length; +} NPString; + +typedef enum { + NPVariantType_Void, + NPVariantType_Null, + NPVariantType_Bool, + NPVariantType_Int32, + NPVariantType_Double, + NPVariantType_String, + NPVariantType_Object +} NPVariantType; + +typedef struct _NPVariant { + NPVariantType type; + union { + bool boolValue; + int32_t intValue; + double doubleValue; + NPString stringValue; + NPObject *objectValue; + } value; +} NPVariant; + +/* + NPN_ReleaseVariantValue is called on all 'out' parameters + references. Specifically it is to be called on variants that own + their value, as is the case with all non-const NPVariant* + arguments after a successful call to any methods (except this one) + in this API. + + After calling NPN_ReleaseVariantValue, the type of the variant + will be NPVariantType_Void. +*/ +void NPN_ReleaseVariantValue(NPVariant *variant); + +#define NPVARIANT_IS_VOID(_v) ((_v).type == NPVariantType_Void) +#define NPVARIANT_IS_NULL(_v) ((_v).type == NPVariantType_Null) +#define NPVARIANT_IS_BOOLEAN(_v) ((_v).type == NPVariantType_Bool) +#define NPVARIANT_IS_INT32(_v) ((_v).type == NPVariantType_Int32) +#define NPVARIANT_IS_DOUBLE(_v) ((_v).type == NPVariantType_Double) +#define NPVARIANT_IS_STRING(_v) ((_v).type == NPVariantType_String) +#define NPVARIANT_IS_OBJECT(_v) ((_v).type == NPVariantType_Object) + +#define NPVARIANT_TO_BOOLEAN(_v) ((_v).value.boolValue) +#define NPVARIANT_TO_INT32(_v) ((_v).value.intValue) +#define NPVARIANT_TO_DOUBLE(_v) ((_v).value.doubleValue) +#define NPVARIANT_TO_STRING(_v) ((_v).value.stringValue) +#define NPVARIANT_TO_OBJECT(_v) ((_v).value.objectValue) + +#define VOID_TO_NPVARIANT(_v) \ +NP_BEGIN_MACRO \ + (_v).type = NPVariantType_Void; \ + (_v).value.objectValue = NULL; \ +NP_END_MACRO + +#define NULL_TO_NPVARIANT(_v) \ +NP_BEGIN_MACRO \ + (_v).type = NPVariantType_Null; \ + (_v).value.objectValue = NULL; \ +NP_END_MACRO + +#define BOOLEAN_TO_NPVARIANT(_val, _v) \ +NP_BEGIN_MACRO \ + (_v).type = NPVariantType_Bool; \ + (_v).value.boolValue = !!(_val); \ +NP_END_MACRO + +#define INT32_TO_NPVARIANT(_val, _v) \ +NP_BEGIN_MACRO \ + (_v).type = NPVariantType_Int32; \ + (_v).value.intValue = _val; \ +NP_END_MACRO + +#define DOUBLE_TO_NPVARIANT(_val, _v) \ +NP_BEGIN_MACRO \ + (_v).type = NPVariantType_Double; \ + (_v).value.doubleValue = _val; \ +NP_END_MACRO + +#define STRINGZ_TO_NPVARIANT(_val, _v) \ +NP_BEGIN_MACRO \ + (_v).type = NPVariantType_String; \ + NPString str = { _val, strlen(_val) }; \ + (_v).value.stringValue = str; \ +NP_END_MACRO + +#define STRINGN_TO_NPVARIANT(_val, _len, _v) \ +NP_BEGIN_MACRO \ + (_v).type = NPVariantType_String; \ + NPString str = { _val, _len }; \ + (_v).value.stringValue = str; \ +NP_END_MACRO + +#define OBJECT_TO_NPVARIANT(_val, _v) \ +NP_BEGIN_MACRO \ + (_v).type = NPVariantType_Object; \ + (_v).value.objectValue = _val; \ +NP_END_MACRO + + +/* + Type mappings (JavaScript types have been used for illustration + purposes): + + JavaScript to C (NPVariant with type:) + undefined NPVariantType_Void + null NPVariantType_Null + Boolean NPVariantType_Bool + Number NPVariantType_Double or NPVariantType_Int32 + String NPVariantType_String + Object NPVariantType_Object + + C (NPVariant with type:) to JavaScript + NPVariantType_Void undefined + NPVariantType_Null null + NPVariantType_Bool Boolean + NPVariantType_Int32 Number + NPVariantType_Double Number + NPVariantType_String String + NPVariantType_Object Object +*/ + +typedef void *NPIdentifier; + +/* + NPObjects have methods and properties. Methods and properties are + identified with NPIdentifiers. These identifiers may be reflected + in script. NPIdentifiers can be either strings or integers, IOW, + methods and properties can be identified by either strings or + integers (i.e. foo["bar"] vs foo[1]). NPIdentifiers can be + compared using ==. In case of any errors, the requested + NPIdentifier(s) will be NULL. +*/ +NPIdentifier NPN_GetStringIdentifier(const NPUTF8 *name); +void NPN_GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount, + NPIdentifier *identifiers); +NPIdentifier NPN_GetIntIdentifier(int32_t intid); +bool NPN_IdentifierIsString(NPIdentifier identifier); + +/* + The NPUTF8 returned from NPN_UTF8FromIdentifier SHOULD be freed. +*/ +NPUTF8 *NPN_UTF8FromIdentifier(NPIdentifier identifier); + +/* + Get the integer represented by identifier. If identifier is not an + integer identifier, the behaviour is undefined. +*/ +int32_t NPN_IntFromIdentifier(NPIdentifier identifier); + +/* + NPObject behavior is implemented using the following set of + callback functions. + + The NPVariant *result argument of these functions (where + applicable) should be released using NPN_ReleaseVariantValue(). +*/ +typedef NPObject *(*NPAllocateFunctionPtr)(NPP npp, NPClass *aClass); +typedef void (*NPDeallocateFunctionPtr)(NPObject *npobj); +typedef void (*NPInvalidateFunctionPtr)(NPObject *npobj); +typedef bool (*NPHasMethodFunctionPtr)(NPObject *npobj, NPIdentifier name); +typedef bool (*NPInvokeFunctionPtr)(NPObject *npobj, NPIdentifier name, + const NPVariant *args, uint32_t argCount, + NPVariant *result); +typedef bool (*NPInvokeDefaultFunctionPtr)(NPObject *npobj, + const NPVariant *args, + uint32_t argCount, + NPVariant *result); +typedef bool (*NPHasPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name); +typedef bool (*NPGetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name, + NPVariant *result); +typedef bool (*NPSetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name, + const NPVariant *value); +typedef bool (*NPRemovePropertyFunctionPtr)(NPObject *npobj, + NPIdentifier name); +typedef bool (*NPEnumerationFunctionPtr)(NPObject *npobj, NPIdentifier **value, + uint32_t *count); +typedef bool (*NPConstructFunctionPtr)(NPObject *npobj, + const NPVariant *args, + uint32_t argCount, + NPVariant *result); + +/* + NPObjects returned by create, retain, invoke, and getProperty pass + a reference count to the caller. That is, the callee adds a + reference count which passes to the caller. It is the caller's + responsibility to release the returned object. + + NPInvokeFunctionPtr function may return 0 to indicate a void + result. + + NPInvalidateFunctionPtr is called by the scripting environment + when the native code is shutdown. Any attempt to message a + NPObject instance after the invalidate callback has been + called will result in undefined behavior, even if the native code + is still retaining those NPObject instances. (The runtime + will typically return immediately, with 0 or NULL, from an attempt + to dispatch to a NPObject, but this behavior should not be + depended upon.) + + The NPEnumerationFunctionPtr function may pass an array of + NPIdentifiers back to the caller. The callee allocs the memory of + the array using NPN_MemAlloc(), and it's the caller's responsibility + to release it using NPN_MemFree(). +*/ +struct NPClass +{ + uint32_t structVersion; + NPAllocateFunctionPtr allocate; + NPDeallocateFunctionPtr deallocate; + NPInvalidateFunctionPtr invalidate; + NPHasMethodFunctionPtr hasMethod; + NPInvokeFunctionPtr invoke; + NPInvokeDefaultFunctionPtr invokeDefault; + NPHasPropertyFunctionPtr hasProperty; + NPGetPropertyFunctionPtr getProperty; + NPSetPropertyFunctionPtr setProperty; + NPRemovePropertyFunctionPtr removeProperty; + NPEnumerationFunctionPtr enumerate; + NPConstructFunctionPtr construct; +}; + +#define NP_CLASS_STRUCT_VERSION 3 + +#define NP_CLASS_STRUCT_VERSION_ENUM 2 +#define NP_CLASS_STRUCT_VERSION_CTOR 3 + +#define NP_CLASS_STRUCT_VERSION_HAS_ENUM(npclass) \ + ((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_ENUM) + +#define NP_CLASS_STRUCT_VERSION_HAS_CTOR(npclass) \ + ((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_CTOR) + +struct NPObject { + NPClass *_class; + uint32_t referenceCount; + /* + * Additional space may be allocated here by types of NPObjects + */ +}; + +/* + If the class has an allocate function, NPN_CreateObject invokes + that function, otherwise a NPObject is allocated and + returned. This method will initialize the referenceCount member of + the NPObject to 1. +*/ +NPObject *NPN_CreateObject(NPP npp, NPClass *aClass); + +/* + Increment the NPObject's reference count. +*/ +NPObject *NPN_RetainObject(NPObject *npobj); + +/* + Decremented the NPObject's reference count. If the reference + count goes to zero, the class's destroy function is invoke if + specified, otherwise the object is freed directly. +*/ +void NPN_ReleaseObject(NPObject *npobj); + +/* + Functions to access script objects represented by NPObject. + + Calls to script objects are synchronous. If a function returns a + value, it will be supplied via the result NPVariant + argument. Successful calls will return true, false will be + returned in case of an error. + + Calls made from plugin code to script must be made from the thread + on which the plugin was initialized. +*/ + +bool NPN_Invoke(NPP npp, NPObject *npobj, NPIdentifier methodName, + const NPVariant *args, uint32_t argCount, NPVariant *result); +bool NPN_InvokeDefault(NPP npp, NPObject *npobj, const NPVariant *args, + uint32_t argCount, NPVariant *result); +bool NPN_Evaluate(NPP npp, NPObject *npobj, NPString *script, + NPVariant *result); +bool NPN_GetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName, + NPVariant *result); +bool NPN_SetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName, + const NPVariant *value); +bool NPN_RemoveProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName); +bool NPN_HasProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName); +bool NPN_HasMethod(NPP npp, NPObject *npobj, NPIdentifier methodName); +bool NPN_Enumerate(NPP npp, NPObject *npobj, NPIdentifier **identifier, + uint32_t *count); +bool NPN_Construct(NPP npp, NPObject *npobj, const NPVariant *args, + uint32_t argCount, NPVariant *result); + +/* + NPN_SetException may be called to trigger a script exception upon + return from entry points into NPObjects. Typical usage: + + NPN_SetException (npobj, message); +*/ +void NPN_SetException(NPObject *npobj, const NPUTF8 *message); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Templates/Empty/web/source/npplugin/windows/nptypes.h b/Templates/Empty/web/source/npplugin/windows/nptypes.h new file mode 100644 index 000000000..6f6e3fbf4 --- /dev/null +++ b/Templates/Empty/web/source/npplugin/windows/nptypes.h @@ -0,0 +1,105 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * mozilla.org. + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Johnny Stenback <jst@mozilla.org> (Original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * Header file for ensuring that C99 types ([u]int32_t and bool) are + * available. + */ + +#if defined(WIN32) || defined(OS2) + /* + * Win32 and OS/2 don't know C99, so define [u]int_32 here. The bool + * is predefined tho, both in C and C++. + */ + typedef int int32_t; + typedef unsigned int uint32_t; +#elif defined(_AIX) || defined(__sun) || defined(__osf__) || defined(IRIX) || defined(HPUX) + /* + * AIX and SunOS ship a inttypes.h header that defines [u]int32_t, + * but not bool for C. + */ + #include <inttypes.h> + + #ifndef __cplusplus + typedef int bool; + #endif +#elif defined(bsdi) || defined(FREEBSD) || defined(OPENBSD) + /* + * BSD/OS, FreeBSD, and OpenBSD ship sys/types.h that define int32_t and + * u_int32_t. + */ + #include <sys/types.h> + + /* + * BSD/OS ships no header that defines uint32_t, nor bool (for C) + */ + #if defined(bsdi) + typedef u_int32_t uint32_t; + + #if !defined(__cplusplus) + typedef int bool; + #endif + #else + /* + * FreeBSD and OpenBSD define uint32_t and bool. + */ + #include <inttypes.h> + #include <stdbool.h> + #endif +#elif defined(BEOS) + #include <inttypes.h> +#else + /* + * For those that ship a standard C99 stdint.h header file, include + * it. Can't do the same for stdbool.h tho, since some systems ship + * with a stdbool.h file that doesn't compile! + */ + #include <stdint.h> + + #ifndef __cplusplus + #if !defined(__GNUC__) || (__GNUC__ > 2 || __GNUC_MINOR__ > 95) + #include <stdbool.h> + #else + /* + * GCC 2.91 can't deal with a typedef for bool, but a #define + * works. + */ + #define bool int + #endif + #endif +#endif diff --git a/Templates/Empty/web/source/npplugin/windows/npupp.h b/Templates/Empty/web/source/npplugin/windows/npupp.h new file mode 100644 index 000000000..7079f40ee --- /dev/null +++ b/Templates/Empty/web/source/npplugin/windows/npupp.h @@ -0,0 +1,715 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + + +/* + * npupp.h $Revision: 3.26 $ + * function call mecahnics needed by platform specific glue code. + */ + + +#ifndef _NPUPP_H_ +#define _NPUPP_H_ + +#if defined(__OS2__) +#pragma pack(1) +#endif + +#ifndef GENERATINGCFM +#define GENERATINGCFM 0 +#endif + +#ifndef _NPAPI_H_ +#include "npapi.h" +#endif + +#include "npruntime.h" + +#include "jri.h" + + +/****************************************************************************************** + plug-in function table macros + for each function in and out of the plugin API we define + typedef NPP_FooUPP + #define NewNPP_FooProc + #define CallNPP_FooProc + *******************************************************************************************/ + + +/* NPP_Initialize */ +typedef void (* NP_LOADDS NPP_InitializeUPP)(void); +#define NewNPP_InitializeProc(FUNC) \ + ((NPP_InitializeUPP) (FUNC)) +#define CallNPP_InitializeProc(FUNC) \ + (*(FUNC))() + +/* NPP_Shutdown */ +typedef void (* NP_LOADDS NPP_ShutdownUPP)(void); +#define NewNPP_ShutdownProc(FUNC) \ + ((NPP_ShutdownUPP) (FUNC)) +#define CallNPP_ShutdownProc(FUNC) \ + (*(FUNC))() + +/* NPP_New */ +typedef NPError (* NP_LOADDS NPP_NewUPP)(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved); +#define NewNPP_NewProc(FUNC) \ + ((NPP_NewUPP) (FUNC)) +#define CallNPP_NewProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6), (ARG7)) + +/* NPP_Destroy */ +typedef NPError (* NP_LOADDS NPP_DestroyUPP)(NPP instance, NPSavedData** save); +#define NewNPP_DestroyProc(FUNC) \ + ((NPP_DestroyUPP) (FUNC)) +#define CallNPP_DestroyProc(FUNC, ARG1, ARG2) \ + (*(FUNC))((ARG1), (ARG2)) + +/* NPP_SetWindow */ +typedef NPError (* NP_LOADDS NPP_SetWindowUPP)(NPP instance, NPWindow* window); +#define NewNPP_SetWindowProc(FUNC) \ + ((NPP_SetWindowUPP) (FUNC)) +#define CallNPP_SetWindowProc(FUNC, ARG1, ARG2) \ + (*(FUNC))((ARG1), (ARG2)) + +/* NPP_NewStream */ +typedef NPError (* NP_LOADDS NPP_NewStreamUPP)(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype); +#define NewNPP_NewStreamProc(FUNC) \ + ((NPP_NewStreamUPP) (FUNC)) +#define CallNPP_NewStreamProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5)) + +/* NPP_DestroyStream */ +typedef NPError (* NP_LOADDS NPP_DestroyStreamUPP)(NPP instance, NPStream* stream, NPReason reason); +#define NewNPP_DestroyStreamProc(FUNC) \ + ((NPP_DestroyStreamUPP) (FUNC)) +#define CallNPP_DestroyStreamProc(FUNC, NPParg, NPStreamPtr, NPReasonArg) \ + (*(FUNC))((NPParg), (NPStreamPtr), (NPReasonArg)) + +/* NPP_WriteReady */ +typedef int32 (* NP_LOADDS NPP_WriteReadyUPP)(NPP instance, NPStream* stream); +#define NewNPP_WriteReadyProc(FUNC) \ + ((NPP_WriteReadyUPP) (FUNC)) +#define CallNPP_WriteReadyProc(FUNC, NPParg, NPStreamPtr) \ + (*(FUNC))((NPParg), (NPStreamPtr)) + +/* NPP_Write */ +typedef int32 (* NP_LOADDS NPP_WriteUPP)(NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buffer); +#define NewNPP_WriteProc(FUNC) \ + ((NPP_WriteUPP) (FUNC)) +#define CallNPP_WriteProc(FUNC, NPParg, NPStreamPtr, offsetArg, lenArg, bufferPtr) \ + (*(FUNC))((NPParg), (NPStreamPtr), (offsetArg), (lenArg), (bufferPtr)) + +/* NPP_StreamAsFile */ +typedef void (* NP_LOADDS NPP_StreamAsFileUPP)(NPP instance, NPStream* stream, const char* fname); +#define NewNPP_StreamAsFileProc(FUNC) \ + ((NPP_StreamAsFileUPP) (FUNC)) +#define CallNPP_StreamAsFileProc(FUNC, ARG1, ARG2, ARG3) \ + (*(FUNC))((ARG1), (ARG2), (ARG3)) + +/* NPP_Print */ +typedef void (* NP_LOADDS NPP_PrintUPP)(NPP instance, NPPrint* platformPrint); +#define NewNPP_PrintProc(FUNC) \ + ((NPP_PrintUPP) (FUNC)) +#define CallNPP_PrintProc(FUNC, NPParg, NPPrintArg) \ + (*(FUNC))((NPParg), (NPPrintArg)) + +/* NPP_HandleEvent */ +typedef int16 (* NP_LOADDS NPP_HandleEventUPP)(NPP instance, void* event); +#define NewNPP_HandleEventProc(FUNC) \ + ((NPP_HandleEventUPP) (FUNC)) +#define CallNPP_HandleEventProc(FUNC, NPParg, voidPtr) \ + (*(FUNC))((NPParg), (voidPtr)) + +/* NPP_URLNotify */ +typedef void (* NP_LOADDS NPP_URLNotifyUPP)(NPP instance, const char* url, NPReason reason, void* notifyData); +#define NewNPP_URLNotifyProc(FUNC) \ + ((NPP_URLNotifyUPP) (FUNC)) +#define CallNPP_URLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4)) + +/* NPP_GetValue */ +typedef NPError (* NP_LOADDS NPP_GetValueUPP)(NPP instance, NPPVariable variable, void *ret_alue); +#define NewNPP_GetValueProc(FUNC) \ + ((NPP_GetValueUPP) (FUNC)) +#define CallNPP_GetValueProc(FUNC, ARG1, ARG2, ARG3) \ + (*(FUNC))((ARG1), (ARG2), (ARG3)) + +/* NPP_SetValue */ +typedef NPError (* NP_LOADDS NPP_SetValueUPP)(NPP instance, NPNVariable variable, void *ret_alue); +#define NewNPP_SetValueProc(FUNC) \ + ((NPP_SetValueUPP) (FUNC)) +#define CallNPP_SetValueProc(FUNC, ARG1, ARG2, ARG3) \ + (*(FUNC))((ARG1), (ARG2), (ARG3)) + +/* + * Netscape entry points + */ + + +/* NPN_GetValue */ +typedef NPError (* NP_LOADDS NPN_GetValueUPP)(NPP instance, NPNVariable variable, void *ret_alue); +#define NewNPN_GetValueProc(FUNC) \ + ((NPN_GetValueUPP) (FUNC)) +#define CallNPN_GetValueProc(FUNC, ARG1, ARG2, ARG3) \ + (*(FUNC))((ARG1), (ARG2), (ARG3)) + +/* NPN_SetValue */ +typedef NPError (* NP_LOADDS NPN_SetValueUPP)(NPP instance, NPPVariable variable, void *ret_alue); +#define NewNPN_SetValueProc(FUNC) \ + ((NPN_SetValueUPP) (FUNC)) +#define CallNPN_SetValueProc(FUNC, ARG1, ARG2, ARG3) \ + (*(FUNC))((ARG1), (ARG2), (ARG3)) + +/* NPN_GetUrlNotify */ +typedef NPError (* NP_LOADDS NPN_GetURLNotifyUPP)(NPP instance, const char* url, const char* window, void* notifyData); +#define NewNPN_GetURLNotifyProc(FUNC) \ + ((NPN_GetURLNotifyUPP) (FUNC)) +#define CallNPN_GetURLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4)) + +/* NPN_PostUrlNotify */ +typedef NPError (* NP_LOADDS NPN_PostURLNotifyUPP)(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file, void* notifyData); +#define NewNPN_PostURLNotifyProc(FUNC) \ + ((NPN_PostURLNotifyUPP) (FUNC)) +#define CallNPN_PostURLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6), (ARG7)) + +/* NPN_GetUrl */ +typedef NPError (* NP_LOADDS NPN_GetURLUPP)(NPP instance, const char* url, const char* window); +#define NewNPN_GetURLProc(FUNC) \ + ((NPN_GetURLUPP) (FUNC)) +#define CallNPN_GetURLProc(FUNC, ARG1, ARG2, ARG3) \ + (*(FUNC))((ARG1), (ARG2), (ARG3)) + +/* NPN_PostUrl */ +typedef NPError (* NP_LOADDS NPN_PostURLUPP)(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file); +#define NewNPN_PostURLProc(FUNC) \ + ((NPN_PostURLUPP) (FUNC)) +#define CallNPN_PostURLProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6)) + +/* NPN_RequestRead */ +typedef NPError (* NP_LOADDS NPN_RequestReadUPP)(NPStream* stream, NPByteRange* rangeList); +#define NewNPN_RequestReadProc(FUNC) \ + ((NPN_RequestReadUPP) (FUNC)) +#define CallNPN_RequestReadProc(FUNC, stream, range) \ + (*(FUNC))((stream), (range)) + +/* NPN_NewStream */ +typedef NPError (* NP_LOADDS NPN_NewStreamUPP)(NPP instance, NPMIMEType type, const char* window, NPStream** stream); +#define NewNPN_NewStreamProc(FUNC) \ + ((NPN_NewStreamUPP) (FUNC)) +#define CallNPN_NewStreamProc(FUNC, npp, type, window, stream) \ + (*(FUNC))((npp), (type), (window), (stream)) + +/* NPN_Write */ +typedef int32 (* NP_LOADDS NPN_WriteUPP)(NPP instance, NPStream* stream, int32 len, void* buffer); +#define NewNPN_WriteProc(FUNC) \ + ((NPN_WriteUPP) (FUNC)) +#define CallNPN_WriteProc(FUNC, npp, stream, len, buffer) \ + (*(FUNC))((npp), (stream), (len), (buffer)) + +/* NPN_DestroyStream */ +typedef NPError (* NP_LOADDS NPN_DestroyStreamUPP)(NPP instance, NPStream* stream, NPReason reason); +#define NewNPN_DestroyStreamProc(FUNC) \ + ((NPN_DestroyStreamUPP) (FUNC)) +#define CallNPN_DestroyStreamProc(FUNC, npp, stream, reason) \ + (*(FUNC))((npp), (stream), (reason)) + +/* NPN_Status */ +typedef void (* NP_LOADDS NPN_StatusUPP)(NPP instance, const char* message); +#define NewNPN_StatusProc(FUNC) \ + ((NPN_StatusUPP) (FUNC)) +#define CallNPN_StatusProc(FUNC, npp, msg) \ + (*(FUNC))((npp), (msg)) + +/* NPN_UserAgent */ +typedef const char* (* NP_LOADDS NPN_UserAgentUPP)(NPP instance); +#define NewNPN_UserAgentProc(FUNC) \ + ((NPN_UserAgentUPP) (FUNC)) +#define CallNPN_UserAgentProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +/* NPN_MemAlloc */ +typedef void* (* NP_LOADDS NPN_MemAllocUPP)(uint32 size); +#define NewNPN_MemAllocProc(FUNC) \ + ((NPN_MemAllocUPP) (FUNC)) +#define CallNPN_MemAllocProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +/* NPN__MemFree */ +typedef void (* NP_LOADDS NPN_MemFreeUPP)(void* ptr); +#define NewNPN_MemFreeProc(FUNC) \ + ((NPN_MemFreeUPP) (FUNC)) +#define CallNPN_MemFreeProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +/* NPN_MemFlush */ +typedef uint32 (* NP_LOADDS NPN_MemFlushUPP)(uint32 size); +#define NewNPN_MemFlushProc(FUNC) \ + ((NPN_MemFlushUPP) (FUNC)) +#define CallNPN_MemFlushProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +/* NPN_ReloadPlugins */ +typedef void (* NP_LOADDS NPN_ReloadPluginsUPP)(NPBool reloadPages); +#define NewNPN_ReloadPluginsProc(FUNC) \ + ((NPN_ReloadPluginsUPP) (FUNC)) +#define CallNPN_ReloadPluginsProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +/* NPN_GetJavaEnv */ +typedef JRIEnv* (* NP_LOADDS NPN_GetJavaEnvUPP)(void); +#define NewNPN_GetJavaEnvProc(FUNC) \ + ((NPN_GetJavaEnvUPP) (FUNC)) +#define CallNPN_GetJavaEnvProc(FUNC) \ + (*(FUNC))() + +/* NPN_GetJavaPeer */ +typedef jref (* NP_LOADDS NPN_GetJavaPeerUPP)(NPP instance); +#define NewNPN_GetJavaPeerProc(FUNC) \ + ((NPN_GetJavaPeerUPP) (FUNC)) +#define CallNPN_GetJavaPeerProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +/* NPN_InvalidateRect */ +typedef void (* NP_LOADDS NPN_InvalidateRectUPP)(NPP instance, NPRect *rect); +#define NewNPN_InvalidateRectProc(FUNC) \ + ((NPN_InvalidateRectUPP) (FUNC)) +#define CallNPN_InvalidateRectProc(FUNC, ARG1, ARG2) \ + (*(FUNC))((ARG1), (ARG2)) + +/* NPN_InvalidateRegion */ +typedef void (* NP_LOADDS NPN_InvalidateRegionUPP)(NPP instance, NPRegion region); +#define NewNPN_InvalidateRegionProc(FUNC) \ + ((NPN_InvalidateRegionUPP) (FUNC)) +#define CallNPN_InvalidateRegionProc(FUNC, ARG1, ARG2) \ + (*(FUNC))((ARG1), (ARG2)) + +/* NPN_ForceRedraw */ +typedef void (* NP_LOADDS NPN_ForceRedrawUPP)(NPP instance); +#define NewNPN_ForceRedrawProc(FUNC) \ + ((NPN_ForceRedrawUPP) (FUNC)) +#define CallNPN_ForceRedrawProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +/* NPN_GetStringIdentifier */ +typedef NPIdentifier (* NP_LOADDS NPN_GetStringIdentifierUPP)(const NPUTF8* name); +#define NewNPN_GetStringIdentifierProc(FUNC) \ + ((NPN_GetStringIdentifierUPP) (FUNC)) +#define CallNPN_GetStringIdentifierProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +/* NPN_GetStringIdentifiers */ +typedef void (* NP_LOADDS NPN_GetStringIdentifiersUPP)(const NPUTF8** names, + int32_t nameCount, + NPIdentifier* identifiers); +#define NewNPN_GetStringIdentifiersProc(FUNC) \ + ((NPN_GetStringIdentifiersUPP) (FUNC)) +#define CallNPN_GetStringIdentifiersProc(FUNC, ARG1, ARG2, ARG3) \ + (*(FUNC))((ARG1), (ARG2), (ARG3)) + +/* NPN_GetIntIdentifier */ +typedef NPIdentifier (* NP_LOADDS NPN_GetIntIdentifierUPP)(int32_t intid); +#define NewNPN_GetIntIdentifierProc(FUNC) \ + ((NPN_GetIntIdentifierUPP) (FUNC)) +#define CallNPN_GetIntIdentifierProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +/* NPN_IdentifierIsString */ +typedef bool (* NP_LOADDS NPN_IdentifierIsStringUPP)(NPIdentifier identifier); +#define NewNPN_IdentifierIsStringProc(FUNC) \ + ((NPN_IdentifierIsStringUPP) (FUNC)) +#define CallNPN_IdentifierIsStringProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +/* NPN_UTF8FromIdentifier */ +typedef NPUTF8* (* NP_LOADDS NPN_UTF8FromIdentifierUPP)(NPIdentifier identifier); +#define NewNPN_UTF8FromIdentifierProc(FUNC) \ + ((NPN_UTF8FromIdentifierUPP) (FUNC)) +#define CallNPN_UTF8FromIdentifierProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +/* NPN_IntFromIdentifier */ +typedef int32_t (* NP_LOADDS NPN_IntFromIdentifierUPP)(NPIdentifier identifier); +#define NewNPN_IntFromIdentifierProc(FUNC) \ + ((NPN_IntFromIdentifierUPP) (FUNC)) +#define CallNPN_IntFromIdentifierProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +/* NPN_CreateObject */ +typedef NPObject* (* NP_LOADDS NPN_CreateObjectUPP)(NPP npp, NPClass *aClass); +#define NewNPN_CreateObjectProc(FUNC) \ + ((NPN_CreateObjectUPP) (FUNC)) +#define CallNPN_CreateObjectProc(FUNC, ARG1, ARG2) \ + (*(FUNC))((ARG1), (ARG2)) + +/* NPN_RetainObject */ +typedef NPObject* (* NP_LOADDS NPN_RetainObjectUPP)(NPObject *obj); +#define NewNPN_RetainObjectProc(FUNC) \ + ((NPN_RetainObjectUPP) (FUNC)) +#define CallNPN_RetainObjectProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +/* NPN_ReleaseObject */ +typedef void (* NP_LOADDS NPN_ReleaseObjectUPP)(NPObject *obj); +#define NewNPN_ReleaseObjectProc(FUNC) \ + ((NPN_ReleaseObjectUPP) (FUNC)) +#define CallNPN_ReleaseObjectProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +/* NPN_Invoke */ +typedef bool (* NP_LOADDS NPN_InvokeUPP)(NPP npp, NPObject* obj, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result); +#define NewNPN_InvokeProc(FUNC) \ + ((NPN_InvokeUPP) (FUNC)) +#define CallNPN_InvokeProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6)) + +/* NPN_InvokeDefault */ +typedef bool (* NP_LOADDS NPN_InvokeDefaultUPP)(NPP npp, NPObject* obj, const NPVariant *args, uint32_t argCount, NPVariant *result); +#define NewNPN_InvokeDefaultProc(FUNC) \ + ((NPN_InvokeDefaultUPP) (FUNC)) +#define CallNPN_InvokeDefaultProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5)) + +/* NPN_Evaluate */ +typedef bool (* NP_LOADDS NPN_EvaluateUPP)(NPP npp, NPObject *obj, NPString *script, NPVariant *result); +#define NewNPN_EvaluateProc(FUNC) \ + ((NPN_EvaluateUPP) (FUNC)) +#define CallNPN_EvaluateProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4)) + +/* NPN_GetProperty */ +typedef bool (* NP_LOADDS NPN_GetPropertyUPP)(NPP npp, NPObject *obj, NPIdentifier propertyName, NPVariant *result); +#define NewNPN_GetPropertyProc(FUNC) \ + ((NPN_GetPropertyUPP) (FUNC)) +#define CallNPN_GetPropertyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4)) + +/* NPN_SetProperty */ +typedef bool (* NP_LOADDS NPN_SetPropertyUPP)(NPP npp, NPObject *obj, NPIdentifier propertyName, const NPVariant *value); +#define NewNPN_SetPropertyProc(FUNC) \ + ((NPN_SetPropertyUPP) (FUNC)) +#define CallNPN_SetPropertyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4)) + +/* NPN_RemoveProperty */ +typedef bool (* NP_LOADDS NPN_RemovePropertyUPP)(NPP npp, NPObject *obj, NPIdentifier propertyName); +#define NewNPN_RemovePropertyProc(FUNC) \ + ((NPN_RemovePropertyUPP) (FUNC)) +#define CallNPN_RemovePropertyProc(FUNC, ARG1, ARG2, ARG3) \ + (*(FUNC))((ARG1), (ARG2), (ARG3)) + +/* NPN_HasProperty */ +typedef bool (* NP_LOADDS NPN_HasPropertyUPP)(NPP npp, NPObject *obj, NPIdentifier propertyName); +#define NewNPN_HasPropertyProc(FUNC) \ + ((NPN_HasPropertyUPP) (FUNC)) +#define CallNPN_HasPropertyProc(FUNC, ARG1, ARG2, ARG3) \ + (*(FUNC))((ARG1), (ARG2), (ARG3)) + +/* NPN_HasMethod */ +typedef bool (* NP_LOADDS NPN_HasMethodUPP)(NPP npp, NPObject *obj, NPIdentifier propertyName); +#define NewNPN_HasMethodProc(FUNC) \ + ((NPN_HasMethodUPP) (FUNC)) +#define CallNPN_HasMethodProc(FUNC, ARG1, ARG2, ARG3) \ + (*(FUNC))((ARG1), (ARG2), (ARG3)) + +/* NPN_ReleaseVariantValue */ +typedef void (* NP_LOADDS NPN_ReleaseVariantValueUPP)(NPVariant *variant); +#define NewNPN_ReleaseVariantValueProc(FUNC) \ + ((NPN_ReleaseVariantValueUPP) (FUNC)) +#define CallNPN_ReleaseVariantValueProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +/* NPN_SetException */ +typedef void (* NP_LOADDS NPN_SetExceptionUPP)(NPObject *obj, const NPUTF8 *message); +#define NewNPN_SetExceptionProc(FUNC) \ + ((NPN_SetExceptionUPP) (FUNC)) +#define CallNPN_SetExceptionProc(FUNC, ARG1, ARG2) \ + (*(FUNC))((ARG1), (ARG2)) + +/* NPN_PushPopupsEnabledStateUPP */ +typedef bool (* NP_LOADDS NPN_PushPopupsEnabledStateUPP)(NPP npp, NPBool enabled); +#define NewNPN_PushPopupsEnabledStateProc(FUNC) \ + ((NPN_PushPopupsEnabledStateUPP) (FUNC)) +#define CallNPN_PushPopupsEnabledStateProc(FUNC, ARG1, ARG2) \ + (*(FUNC))((ARG1), (ARG2)) + +/* NPN_PopPopupsEnabledState */ +typedef bool (* NP_LOADDS NPN_PopPopupsEnabledStateUPP)(NPP npp); +#define NewNPN_PopPopupsEnabledStateProc(FUNC) \ + ((NPN_PopPopupsEnabledStateUPP) (FUNC)) +#define CallNPN_PopPopupsEnabledStateProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +/* NPN_Enumerate */ +typedef bool (* NP_LOADDS NPN_EnumerateUPP)(NPP npp, NPObject *obj, NPIdentifier **identifier, uint32_t *count); +#define NewNPN_EnumerateProc(FUNC) \ + ((NPN_EnumerateUPP) (FUNC)) +#define CallNPN_EnumerateProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4)) + +/* NPN_PluginThreadAsyncCall */ +typedef void (* NP_LOADDS NPN_PluginThreadAsyncCallUPP)(NPP instance, void (*func)(void *), void *userData); +#define NewNPN_PluginThreadAsyncCallProc(FUNC) \ + ((NPN_PluginThreadAsyncCallUPP) (FUNC)) +#define CallNPN_PluginThreadAsyncCallProc(FUNC, ARG1, ARG2, ARG3) \ + (*(FUNC))((ARG1), (ARG2), (ARG3)) + +/* NPN_Construct */ +typedef bool (* NP_LOADDS NPN_ConstructUPP)(NPP npp, NPObject* obj, const NPVariant *args, uint32_t argCount, NPVariant *result); +#define NewNPN_ConstructProc(FUNC) \ + ((NPN_ConstructUPP) (FUNC)) +#define CallNPN_ConstructProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5)) + + + +/****************************************************************************************** + * The actual plugin function table definitions + *******************************************************************************************/ + +typedef struct _NPPluginFuncs { + uint16 size; + uint16 version; + NPP_NewUPP newp; + NPP_DestroyUPP destroy; + NPP_SetWindowUPP setwindow; + NPP_NewStreamUPP newstream; + NPP_DestroyStreamUPP destroystream; + NPP_StreamAsFileUPP asfile; + NPP_WriteReadyUPP writeready; + NPP_WriteUPP write; + NPP_PrintUPP print; + NPP_HandleEventUPP event; + NPP_URLNotifyUPP urlnotify; + JRIGlobalRef javaClass; + NPP_GetValueUPP getvalue; + NPP_SetValueUPP setvalue; +} NPPluginFuncs; + +typedef struct _NPNetscapeFuncs { + uint16 size; + uint16 version; + NPN_GetURLUPP geturl; + NPN_PostURLUPP posturl; + NPN_RequestReadUPP requestread; + NPN_NewStreamUPP newstream; + NPN_WriteUPP write; + NPN_DestroyStreamUPP destroystream; + NPN_StatusUPP status; + NPN_UserAgentUPP uagent; + NPN_MemAllocUPP memalloc; + NPN_MemFreeUPP memfree; + NPN_MemFlushUPP memflush; + NPN_ReloadPluginsUPP reloadplugins; + NPN_GetJavaEnvUPP getJavaEnv; + NPN_GetJavaPeerUPP getJavaPeer; + NPN_GetURLNotifyUPP geturlnotify; + NPN_PostURLNotifyUPP posturlnotify; + NPN_GetValueUPP getvalue; + NPN_SetValueUPP setvalue; + NPN_InvalidateRectUPP invalidaterect; + NPN_InvalidateRegionUPP invalidateregion; + NPN_ForceRedrawUPP forceredraw; + NPN_GetStringIdentifierUPP getstringidentifier; + NPN_GetStringIdentifiersUPP getstringidentifiers; + NPN_GetIntIdentifierUPP getintidentifier; + NPN_IdentifierIsStringUPP identifierisstring; + NPN_UTF8FromIdentifierUPP utf8fromidentifier; + NPN_IntFromIdentifierUPP intfromidentifier; + NPN_CreateObjectUPP createobject; + NPN_RetainObjectUPP retainobject; + NPN_ReleaseObjectUPP releaseobject; + NPN_InvokeUPP invoke; + NPN_InvokeDefaultUPP invokeDefault; + NPN_EvaluateUPP evaluate; + NPN_GetPropertyUPP getproperty; + NPN_SetPropertyUPP setproperty; + NPN_RemovePropertyUPP removeproperty; + NPN_HasPropertyUPP hasproperty; + NPN_HasMethodUPP hasmethod; + NPN_ReleaseVariantValueUPP releasevariantvalue; + NPN_SetExceptionUPP setexception; + NPN_PushPopupsEnabledStateUPP pushpopupsenabledstate; + NPN_PopPopupsEnabledStateUPP poppopupsenabledstate; + NPN_EnumerateUPP enumerate; + NPN_PluginThreadAsyncCallUPP pluginthreadasynccall; + NPN_ConstructUPP construct; +} NPNetscapeFuncs; + + +#ifdef XP_MACOSX +/****************************************************************************************** + * Mac platform-specific plugin glue stuff + *******************************************************************************************/ + +/* + * Main entry point of the plugin. + * This routine will be called when the plugin is loaded. The function + * tables are passed in and the plugin fills in the NPPluginFuncs table + * and NPPShutdownUPP for Netscape's use. + */ +typedef NPError (* NP_LOADDS NPP_MainEntryUPP)(NPNetscapeFuncs*, NPPluginFuncs*, NPP_ShutdownUPP*); +#define NewNPP_MainEntryProc(FUNC) \ + ((NPP_MainEntryUPP) (FUNC)) +#define CallNPP_MainEntryProc(FUNC, netscapeFunc, pluginFunc, shutdownUPP) \ + (*(FUNC))((netscapeFunc), (pluginFunc), (shutdownUPP)) + +/* + * Mac OS X version(s) of NP_GetMIMEDescription(const char *) + * These can be called to retreive MIME information from the plugin dynamically + * + * Note: For compatibility with Quicktime, BPSupportedMIMEtypes is another way + * to get mime info from the plugin only on OSX and may not be supported + * in furture version -- use NP_GetMIMEDescription instead + */ + +enum +{ + kBPSupportedMIMETypesStructVers_1 = 1 +}; + +typedef struct _BPSupportedMIMETypes +{ + SInt32 structVersion; /* struct version */ + Handle typeStrings; /* STR# formated handle, allocated by plug-in */ + Handle infoStrings; /* STR# formated handle, allocated by plug-in */ +} BPSupportedMIMETypes; +OSErr BP_GetSupportedMIMETypes(BPSupportedMIMETypes *mimeInfo, UInt32 flags); + + /* NP_GetMIMEDescription */ +#define NP_GETMIMEDESCRIPTION_NAME "NP_GetMIMEDescription" +typedef const char* (* NP_LOADDS NP_GetMIMEDescriptionUPP)(); +#define NewNP_GetMIMEDescEntryProc(FUNC) \ + ((NP_GetMIMEDescriptionUPP) (FUNC)) +#define CallNP_GetMIMEDescEntryProc(FUNC) \ + (*(FUNC))() + +/* BP_GetSupportedMIMETypes */ +typedef OSErr (* NP_LOADDS BP_GetSupportedMIMETypesUPP)(BPSupportedMIMETypes*, UInt32); +#define NewBP_GetSupportedMIMETypesEntryProc(FUNC) \ + ((BP_GetSupportedMIMETypesUPP) (FUNC)) +#define CallBP_GetMIMEDescEntryProc(FUNC, mimeInfo, flags) \ + (*(FUNC))((mimeInfo), (flags)) + +#endif /* XP_MACOSX */ + +#if defined(_WINDOWS) +#define OSCALL WINAPI +#else +#if defined(__OS2__) +#define OSCALL _System +#else +#define OSCALL +#endif +#endif + +#if defined(XP_UNIX) +/* GCC 3.3 and later support the visibility attribute. */ +#if defined(__GNUC__) && \ + ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) +#define NP_VISIBILITY_DEFAULT __attribute__((visibility("default"))) +#else +#define NP_VISIBILITY_DEFAULT +#endif + +#define NP_EXPORT(__type) NP_VISIBILITY_DEFAULT __type +#endif + +#if defined( _WINDOWS ) || defined (__OS2__) + +#ifdef __cplusplus +extern "C" { +#endif + +/* plugin meta member functions */ +#if defined(__OS2__) + +typedef struct _NPPluginData { /* Alternate OS2 Plugin interface */ + char *pMimeTypes; + char *pFileExtents; + char *pFileOpenTemplate; + char *pProductName; + char *pProductDescription; + unsigned long dwProductVersionMS; + unsigned long dwProductVersionLS; +} NPPluginData; + +NPError OSCALL NP_GetPluginData(NPPluginData * pPluginData); + +#endif + +NPError OSCALL NP_GetEntryPoints(NPPluginFuncs* pFuncs); + +NPError OSCALL NP_Initialize(NPNetscapeFuncs* pFuncs); + +NPError OSCALL NP_Shutdown(); + +char* NP_GetMIMEDescription(); + +#ifdef __cplusplus +} +#endif + +#endif /* _WINDOWS || __OS2__ */ + +#if defined(__OS2__) +#pragma pack() +#endif + +#ifdef XP_UNIX + +#ifdef __cplusplus +extern "C" { +#endif + +/* plugin meta member functions */ + +NP_EXPORT(char*) NP_GetMIMEDescription(void); +NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs*, NPPluginFuncs*); +NP_EXPORT(NPError) NP_Shutdown(void); +NP_EXPORT(NPError) NP_GetValue(void *future, NPPVariable aVariable, void *aValue); + +#ifdef __cplusplus +} +#endif + +#endif /* XP_UNIX */ + +#endif /* _NPUPP_H_ */ diff --git a/Templates/Empty/web/source/npplugin/windows/obsolete/protypes.h b/Templates/Empty/web/source/npplugin/windows/obsolete/protypes.h new file mode 100644 index 000000000..4405bfce2 --- /dev/null +++ b/Templates/Empty/web/source/npplugin/windows/obsolete/protypes.h @@ -0,0 +1,252 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape Portable Runtime (NSPR). + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * This header typedefs the old 'native' types to the new PR<type>s. + * These definitions are scheduled to be eliminated at the earliest + * possible time. The NSPR API is implemented and documented using + * the new definitions. + */ + +#if !defined(PROTYPES_H) +#define PROTYPES_H + +typedef PRUintn uintn; +#ifndef _XP_Core_ +typedef PRIntn intn; +#endif + +/* + * It is trickier to define uint, int8, uint8, int16, uint16, + * int32, uint32, int64, and uint64 because some of these int + * types are defined by standard header files on some platforms. + * Our strategy here is to include all such standard headers + * first, and then define these int types only if they are not + * defined by those standard headers. + */ + +/* + * BeOS defines all the int types below in its standard header + * file SupportDefs.h. + */ +#ifdef XP_BEOS +#include <support/SupportDefs.h> +#endif + +/* + * OpenVMS defines all the int types below in its standard + * header files ints.h and types.h. + */ +#ifdef VMS +#include <ints.h> +#include <types.h> +#endif + +/* + * SVR4 typedef of uint is commonly found on UNIX machines. + * + * On AIX 4.3, sys/inttypes.h (which is included by sys/types.h) + * defines the types int8, int16, int32, and int64. + */ +#ifdef XP_UNIX +#include <sys/types.h> +#endif + +/* model.h on HP-UX defines int8, int16, and int32. */ +#ifdef HPUX +#include <model.h> +#endif + +/* + * uint + */ + +#if !defined(XP_BEOS) && !defined(VMS) \ + && !defined(XP_UNIX) || defined(NTO) +typedef PRUintn uint; +#endif + +/* + * uint64 + */ + +#if !defined(XP_BEOS) && !defined(VMS) +typedef PRUint64 uint64; +#endif + +/* + * uint32 + */ + +#if !defined(XP_BEOS) && !defined(VMS) +#if !defined(XP_MAC) && !defined(_WIN32) && !defined(XP_OS2) && !defined(NTO) +typedef PRUint32 uint32; +#else +typedef unsigned long uint32; +#endif +#endif + +/* + * uint16 + */ + +#if !defined(XP_BEOS) && !defined(VMS) +typedef PRUint16 uint16; +#endif + +/* + * uint8 + */ + +#if !defined(XP_BEOS) && !defined(VMS) +typedef PRUint8 uint8; +#endif + +/* + * int64 + */ + +#if !defined(XP_BEOS) && !defined(VMS) \ + && !defined(_PR_AIX_HAVE_BSD_INT_TYPES) +typedef PRInt64 int64; +#endif + +/* + * int32 + */ + +#if !defined(XP_BEOS) && !defined(VMS) \ + && !defined(_PR_AIX_HAVE_BSD_INT_TYPES) \ + && !defined(HPUX) +#if !defined(XP_MAC) && !defined(_WIN32) && !defined(XP_OS2) && !defined(NTO) +typedef PRInt32 int32; +#else +typedef long int32; +#endif +#endif + +/* + * int16 + */ + +#if !defined(XP_BEOS) && !defined(VMS) \ + && !defined(_PR_AIX_HAVE_BSD_INT_TYPES) \ + && !defined(HPUX) +typedef PRInt16 int16; +#endif + +/* + * int8 + */ + +#if !defined(XP_BEOS) && !defined(VMS) \ + && !defined(_PR_AIX_HAVE_BSD_INT_TYPES) \ + && !defined(HPUX) +typedef PRInt8 int8; +#endif + +typedef PRFloat64 float64; +typedef PRUptrdiff uptrdiff_t; +typedef PRUword uprword_t; +typedef PRWord prword_t; + + +/* Re: prbit.h */ +#define TEST_BIT PR_TEST_BIT +#define SET_BIT PR_SET_BIT +#define CLEAR_BIT PR_CLEAR_BIT + +/* Re: prarena.h->plarena.h */ +#define PRArena PLArena +#define PRArenaPool PLArenaPool +#define PRArenaStats PLArenaStats +#define PR_ARENA_ALIGN PL_ARENA_ALIGN +#define PR_INIT_ARENA_POOL PL_INIT_ARENA_POOL +#define PR_ARENA_ALLOCATE PL_ARENA_ALLOCATE +#define PR_ARENA_GROW PL_ARENA_GROW +#define PR_ARENA_MARK PL_ARENA_MARK +#define PR_CLEAR_UNUSED PL_CLEAR_UNUSED +#define PR_CLEAR_ARENA PL_CLEAR_ARENA +#define PR_ARENA_RELEASE PL_ARENA_RELEASE +#define PR_COUNT_ARENA PL_COUNT_ARENA +#define PR_ARENA_DESTROY PL_ARENA_DESTROY +#define PR_InitArenaPool PL_InitArenaPool +#define PR_FreeArenaPool PL_FreeArenaPool +#define PR_FinishArenaPool PL_FinishArenaPool +#define PR_CompactArenaPool PL_CompactArenaPool +#define PR_ArenaFinish PL_ArenaFinish +#define PR_ArenaAllocate PL_ArenaAllocate +#define PR_ArenaGrow PL_ArenaGrow +#define PR_ArenaRelease PL_ArenaRelease +#define PR_ArenaCountAllocation PL_ArenaCountAllocation +#define PR_ArenaCountInplaceGrowth PL_ArenaCountInplaceGrowth +#define PR_ArenaCountGrowth PL_ArenaCountGrowth +#define PR_ArenaCountRelease PL_ArenaCountRelease +#define PR_ArenaCountRetract PL_ArenaCountRetract + +/* Re: prhash.h->plhash.h */ +#define PRHashEntry PLHashEntry +#define PRHashTable PLHashTable +#define PRHashNumber PLHashNumber +#define PRHashFunction PLHashFunction +#define PRHashComparator PLHashComparator +#define PRHashEnumerator PLHashEnumerator +#define PRHashAllocOps PLHashAllocOps +#define PR_NewHashTable PL_NewHashTable +#define PR_HashTableDestroy PL_HashTableDestroy +#define PR_HashTableRawLookup PL_HashTableRawLookup +#define PR_HashTableRawAdd PL_HashTableRawAdd +#define PR_HashTableRawRemove PL_HashTableRawRemove +#define PR_HashTableAdd PL_HashTableAdd +#define PR_HashTableRemove PL_HashTableRemove +#define PR_HashTableEnumerateEntries PL_HashTableEnumerateEntries +#define PR_HashTableLookup PL_HashTableLookup +#define PR_HashTableDump PL_HashTableDump +#define PR_HashString PL_HashString +#define PR_CompareStrings PL_CompareStrings +#define PR_CompareValues PL_CompareValues + +#if defined(XP_MAC) +#ifndef TRUE /* Mac standard is lower case true */ + #define TRUE 1 +#endif +#ifndef FALSE /* Mac standard is lower case false */ + #define FALSE 0 +#endif +#endif + +#endif /* !defined(PROTYPES_H) */ diff --git a/Templates/Empty/web/source/npplugin/windows/prcpucfg.h b/Templates/Empty/web/source/npplugin/windows/prcpucfg.h new file mode 100644 index 000000000..026258b8c --- /dev/null +++ b/Templates/Empty/web/source/npplugin/windows/prcpucfg.h @@ -0,0 +1,300 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape Portable Runtime (NSPR). + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_PC +#define XP_PC +#endif + +#ifndef WIN32 +#define WIN32 +#endif + +#ifndef WIN95 +#define WIN95 +#endif + +#define PR_AF_INET6 23 /* same as AF_INET6 */ + +#if defined(_M_IX86) || defined(_X86_) + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_DOUBLE 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_WORD 32 +#define PR_BITS_PER_DWORD 64 +#define PR_BITS_PER_DOUBLE 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_WORD_LOG2 5 +#define PR_BITS_PER_DWORD_LOG2 6 +#define PR_BITS_PER_DOUBLE_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_WORD 4 +#define PR_ALIGN_OF_DWORD 8 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_POINTER 4 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 2 + +#elif defined(_ALPHA_) + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 4 + +#elif defined(_AMD64_) + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_DOUBLE 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_WORD 64 +#define PR_BITS_PER_DWORD 64 +#define PR_BITS_PER_DOUBLE 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_WORD_LOG2 6 +#define PR_BITS_PER_DWORD_LOG2 6 +#define PR_BITS_PER_DOUBLE_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_WORD 8 +#define PR_ALIGN_OF_DWORD 8 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 + +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(_IA64_) + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_DOUBLE 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_WORD 64 +#define PR_BITS_PER_DWORD 64 +#define PR_BITS_PER_DOUBLE 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_WORD_LOG2 6 +#define PR_BITS_PER_DWORD_LOG2 6 +#define PR_BITS_PER_DOUBLE_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_WORD 8 +#define PR_ALIGN_OF_DWORD 8 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 + +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#else /* defined(_M_IX86) || defined(_X86_) */ + +#error unknown processor architecture + +#endif /* defined(_M_IX86) || defined(_X86_) */ + +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ diff --git a/Templates/Empty/web/source/npplugin/windows/prtypes.h b/Templates/Empty/web/source/npplugin/windows/prtypes.h new file mode 100644 index 000000000..6850d6f9a --- /dev/null +++ b/Templates/Empty/web/source/npplugin/windows/prtypes.h @@ -0,0 +1,569 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape Portable Runtime (NSPR). + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* +** File: prtypes.h +** Description: Definitions of NSPR's basic types +** +** Prototypes and macros used to make up for deficiencies that we have found +** in ANSI environments. +** +** Since we do not wrap <stdlib.h> and all the other standard headers, authors +** of portable code will not know in general that they need these definitions. +** Instead of requiring these authors to find the dependent uses in their code +** and take the following steps only in those C files, we take steps once here +** for all C files. +**/ + +#ifndef prtypes_h___ +#define prtypes_h___ + +#ifdef MDCPUCFG +#include MDCPUCFG +#else +#include "prcpucfg.h" +#endif + +#include <stddef.h> + +/*********************************************************************** +** MACROS: PR_EXTERN +** PR_IMPLEMENT +** DESCRIPTION: +** These are only for externally visible routines and globals. For +** internal routines, just use "extern" for type checking and that +** will not export internal cross-file or forward-declared symbols. +** Define a macro for declaring procedures return types. We use this to +** deal with windoze specific type hackery for DLL definitions. Use +** PR_EXTERN when the prototype for the method is declared. Use +** PR_IMPLEMENT for the implementation of the method. +** +** Example: +** in dowhim.h +** PR_EXTERN( void ) DoWhatIMean( void ); +** in dowhim.c +** PR_IMPLEMENT( void ) DoWhatIMean( void ) { return; } +** +** +***********************************************************************/ +#if defined(WIN32) + +#define PR_EXPORT(__type) extern __declspec(dllexport) __type +#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type +#define PR_IMPORT(__type) __declspec(dllimport) __type +#define PR_IMPORT_DATA(__type) __declspec(dllimport) __type + +#define PR_EXTERN(__type) extern __declspec(dllexport) __type +#define PR_IMPLEMENT(__type) __declspec(dllexport) __type +#define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type +#define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type + +#define PR_CALLBACK +#define PR_CALLBACK_DECL +#define PR_STATIC_CALLBACK(__x) static __x + +#elif defined(XP_BEOS) + +#define PR_EXPORT(__type) extern __declspec(dllexport) __type +#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type +#define PR_IMPORT(__type) extern __declspec(dllexport) __type +#define PR_IMPORT_DATA(__type) extern __declspec(dllexport) __type + +#define PR_EXTERN(__type) extern __declspec(dllexport) __type +#define PR_IMPLEMENT(__type) __declspec(dllexport) __type +#define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type +#define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type + +#define PR_CALLBACK +#define PR_CALLBACK_DECL +#define PR_STATIC_CALLBACK(__x) static __x + +#elif defined(WIN16) + +#define PR_CALLBACK_DECL __cdecl + +#if defined(_WINDLL) +#define PR_EXPORT(__type) extern __type _cdecl _export _loadds +#define PR_IMPORT(__type) extern __type _cdecl _export _loadds +#define PR_EXPORT_DATA(__type) extern __type _export +#define PR_IMPORT_DATA(__type) extern __type _export + +#define PR_EXTERN(__type) extern __type _cdecl _export _loadds +#define PR_IMPLEMENT(__type) __type _cdecl _export _loadds +#define PR_EXTERN_DATA(__type) extern __type _export +#define PR_IMPLEMENT_DATA(__type) __type _export + +#define PR_CALLBACK __cdecl __loadds +#define PR_STATIC_CALLBACK(__x) static __x PR_CALLBACK + +#else /* this must be .EXE */ +#define PR_EXPORT(__type) extern __type _cdecl _export +#define PR_IMPORT(__type) extern __type _cdecl _export +#define PR_EXPORT_DATA(__type) extern __type _export +#define PR_IMPORT_DATA(__type) extern __type _export + +#define PR_EXTERN(__type) extern __type _cdecl _export +#define PR_IMPLEMENT(__type) __type _cdecl _export +#define PR_EXTERN_DATA(__type) extern __type _export +#define PR_IMPLEMENT_DATA(__type) __type _export + +#define PR_CALLBACK __cdecl __loadds +#define PR_STATIC_CALLBACK(__x) __x PR_CALLBACK +#endif /* _WINDLL */ + +#elif defined(XP_MAC) + +#define PR_EXPORT(__type) extern __declspec(export) __type +#define PR_EXPORT_DATA(__type) extern __declspec(export) __type +#define PR_IMPORT(__type) extern __declspec(export) __type +#define PR_IMPORT_DATA(__type) extern __declspec(export) __type + +#define PR_EXTERN(__type) extern __declspec(export) __type +#define PR_IMPLEMENT(__type) __declspec(export) __type +#define PR_EXTERN_DATA(__type) extern __declspec(export) __type +#define PR_IMPLEMENT_DATA(__type) __declspec(export) __type + +#define PR_CALLBACK +#define PR_CALLBACK_DECL +#define PR_STATIC_CALLBACK(__x) static __x + +#elif defined(XP_OS2) && defined(__declspec) + +#define PR_EXPORT(__type) extern __declspec(dllexport) __type +#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type +#define PR_IMPORT(__type) extern __declspec(dllimport) __type +#define PR_IMPORT_DATA(__type) extern __declspec(dllimport) __type + +#define PR_EXTERN(__type) extern __declspec(dllexport) __type +#define PR_IMPLEMENT(__type) __declspec(dllexport) __type +#define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type +#define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type + +#define PR_CALLBACK +#define PR_CALLBACK_DECL +#define PR_STATIC_CALLBACK(__x) static __x + +#elif defined(XP_OS2_VACPP) + +#define PR_EXPORT(__type) extern __type +#define PR_EXPORT_DATA(__type) extern __type +#define PR_IMPORT(__type) extern __type +#define PR_IMPORT_DATA(__type) extern __type + +#define PR_EXTERN(__type) extern __type +#define PR_IMPLEMENT(__type) __type +#define PR_EXTERN_DATA(__type) extern __type +#define PR_IMPLEMENT_DATA(__type) __type +#define PR_CALLBACK _Optlink +#define PR_CALLBACK_DECL +#define PR_STATIC_CALLBACK(__x) static __x PR_CALLBACK + +#else /* Unix */ + +/* GCC 3.3 and later support the visibility attribute. */ +#if (__GNUC__ >= 4) || \ + (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) +#define PR_VISIBILITY_DEFAULT __attribute__((visibility("default"))) +#else +#define PR_VISIBILITY_DEFAULT +#endif + +#define PR_EXPORT(__type) extern PR_VISIBILITY_DEFAULT __type +#define PR_EXPORT_DATA(__type) extern PR_VISIBILITY_DEFAULT __type +#define PR_IMPORT(__type) extern PR_VISIBILITY_DEFAULT __type +#define PR_IMPORT_DATA(__type) extern PR_VISIBILITY_DEFAULT __type + +#define PR_EXTERN(__type) extern PR_VISIBILITY_DEFAULT __type +#define PR_IMPLEMENT(__type) PR_VISIBILITY_DEFAULT __type +#define PR_EXTERN_DATA(__type) extern PR_VISIBILITY_DEFAULT __type +#define PR_IMPLEMENT_DATA(__type) PR_VISIBILITY_DEFAULT __type +#define PR_CALLBACK +#define PR_CALLBACK_DECL +#define PR_STATIC_CALLBACK(__x) static __x + +#endif + +#if defined(_NSPR_BUILD_) +#define NSPR_API(__type) PR_EXPORT(__type) +#define NSPR_DATA_API(__type) PR_EXPORT_DATA(__type) +#else +#define NSPR_API(__type) PR_IMPORT(__type) +#define NSPR_DATA_API(__type) PR_IMPORT_DATA(__type) +#endif + +/*********************************************************************** +** MACROS: PR_BEGIN_MACRO +** PR_END_MACRO +** DESCRIPTION: +** Macro body brackets so that macros with compound statement definitions +** behave syntactically more like functions when called. +***********************************************************************/ +#define PR_BEGIN_MACRO do { +#define PR_END_MACRO } while (0) + +/*********************************************************************** +** MACROS: PR_BEGIN_EXTERN_C +** PR_END_EXTERN_C +** DESCRIPTION: +** Macro shorthands for conditional C++ extern block delimiters. +***********************************************************************/ +#ifdef __cplusplus +#define PR_BEGIN_EXTERN_C extern "C" { +#define PR_END_EXTERN_C } +#else +#define PR_BEGIN_EXTERN_C +#define PR_END_EXTERN_C +#endif + +/*********************************************************************** +** MACROS: PR_BIT +** PR_BITMASK +** DESCRIPTION: +** Bit masking macros. XXX n must be <= 31 to be portable +***********************************************************************/ +#define PR_BIT(n) ((PRUint32)1 << (n)) +#define PR_BITMASK(n) (PR_BIT(n) - 1) + +/*********************************************************************** +** MACROS: PR_ROUNDUP +** PR_MIN +** PR_MAX +** PR_ABS +** DESCRIPTION: +** Commonly used macros for operations on compatible types. +***********************************************************************/ +#define PR_ROUNDUP(x,y) ((((x)+((y)-1))/(y))*(y)) +#define PR_MIN(x,y) ((x)<(y)?(x):(y)) +#define PR_MAX(x,y) ((x)>(y)?(x):(y)) +#define PR_ABS(x) ((x)<0?-(x):(x)) + +PR_BEGIN_EXTERN_C + +/************************************************************************ +** TYPES: PRUint8 +** PRInt8 +** DESCRIPTION: +** The int8 types are known to be 8 bits each. There is no type that +** is equivalent to a plain "char". +************************************************************************/ +#if PR_BYTES_PER_BYTE == 1 +typedef unsigned char PRUint8; +/* +** Some cfront-based C++ compilers do not like 'signed char' and +** issue the warning message: +** warning: "signed" not implemented (ignored) +** For these compilers, we have to define PRInt8 as plain 'char'. +** Make sure that plain 'char' is indeed signed under these compilers. +*/ +#if (defined(HPUX) && defined(__cplusplus) \ + && !defined(__GNUC__) && __cplusplus < 199707L) \ + || (defined(SCO) && defined(__cplusplus) \ + && !defined(__GNUC__) && __cplusplus == 1L) +typedef char PRInt8; +#else +typedef signed char PRInt8; +#endif +#else +#error No suitable type for PRInt8/PRUint8 +#endif + +/************************************************************************ + * MACROS: PR_INT8_MAX + * PR_INT8_MIN + * PR_UINT8_MAX + * DESCRIPTION: + * The maximum and minimum values of a PRInt8 or PRUint8. +************************************************************************/ + +#define PR_INT8_MAX 127 +#define PR_INT8_MIN (-128) +#define PR_UINT8_MAX 255U + +/************************************************************************ +** TYPES: PRUint16 +** PRInt16 +** DESCRIPTION: +** The int16 types are known to be 16 bits each. +************************************************************************/ +#if PR_BYTES_PER_SHORT == 2 +typedef unsigned short PRUint16; +typedef short PRInt16; +#else +#error No suitable type for PRInt16/PRUint16 +#endif + +/************************************************************************ + * MACROS: PR_INT16_MAX + * PR_INT16_MIN + * PR_UINT16_MAX + * DESCRIPTION: + * The maximum and minimum values of a PRInt16 or PRUint16. +************************************************************************/ + +#define PR_INT16_MAX 32767 +#define PR_INT16_MIN (-32768) +#define PR_UINT16_MAX 65535U + +/************************************************************************ +** TYPES: PRUint32 +** PRInt32 +** DESCRIPTION: +** The int32 types are known to be 32 bits each. +************************************************************************/ +#if PR_BYTES_PER_INT == 4 +typedef unsigned int PRUint32; +typedef int PRInt32; +#define PR_INT32(x) x +#define PR_UINT32(x) x ## U +#elif PR_BYTES_PER_LONG == 4 +typedef unsigned long PRUint32; +typedef long PRInt32; +#define PR_INT32(x) x ## L +#define PR_UINT32(x) x ## UL +#else +#error No suitable type for PRInt32/PRUint32 +#endif + +/************************************************************************ + * MACROS: PR_INT32_MAX + * PR_INT32_MIN + * PR_UINT32_MAX + * DESCRIPTION: + * The maximum and minimum values of a PRInt32 or PRUint32. +************************************************************************/ + +#define PR_INT32_MAX PR_INT32(2147483647) +#define PR_INT32_MIN (-PR_INT32_MAX - 1) +#define PR_UINT32_MAX PR_UINT32(4294967295) + +/************************************************************************ +** TYPES: PRUint64 +** PRInt64 +** DESCRIPTION: +** The int64 types are known to be 64 bits each. Care must be used when +** declaring variables of type PRUint64 or PRInt64. Different hardware +** architectures and even different compilers have varying support for +** 64 bit values. The only guaranteed portability requires the use of +** the LL_ macros (see prlong.h). +************************************************************************/ +#ifdef HAVE_LONG_LONG +#if PR_BYTES_PER_LONG == 8 +typedef long PRInt64; +typedef unsigned long PRUint64; +#elif defined(WIN16) +typedef __int64 PRInt64; +typedef unsigned __int64 PRUint64; +#elif defined(WIN32) && !defined(__GNUC__) +typedef __int64 PRInt64; +typedef unsigned __int64 PRUint64; +#else +typedef long long PRInt64; +typedef unsigned long long PRUint64; +#endif /* PR_BYTES_PER_LONG == 8 */ +#else /* !HAVE_LONG_LONG */ +typedef struct { +#ifdef IS_LITTLE_ENDIAN + PRUint32 lo, hi; +#else + PRUint32 hi, lo; +#endif +} PRInt64; +typedef PRInt64 PRUint64; +#endif /* !HAVE_LONG_LONG */ + +/************************************************************************ +** TYPES: PRUintn +** PRIntn +** DESCRIPTION: +** The PRIntn types are most appropriate for automatic variables. They are +** guaranteed to be at least 16 bits, though various architectures may +** define them to be wider (e.g., 32 or even 64 bits). These types are +** never valid for fields of a structure. +************************************************************************/ +#if PR_BYTES_PER_INT >= 2 +typedef int PRIntn; +typedef unsigned int PRUintn; +#else +#error 'sizeof(int)' not sufficient for platform use +#endif + +/************************************************************************ +** TYPES: PRFloat64 +** DESCRIPTION: +** NSPR's floating point type is always 64 bits. +************************************************************************/ +typedef double PRFloat64; + +/************************************************************************ +** TYPES: PRSize +** DESCRIPTION: +** A type for representing the size of objects. +************************************************************************/ +typedef size_t PRSize; + + +/************************************************************************ +** TYPES: PROffset32, PROffset64 +** DESCRIPTION: +** A type for representing byte offsets from some location. +************************************************************************/ +typedef PRInt32 PROffset32; +typedef PRInt64 PROffset64; + +/************************************************************************ +** TYPES: PRPtrDiff +** DESCRIPTION: +** A type for pointer difference. Variables of this type are suitable +** for storing a pointer or pointer subtraction. +************************************************************************/ +typedef ptrdiff_t PRPtrdiff; + +/************************************************************************ +** TYPES: PRUptrdiff +** DESCRIPTION: +** A type for pointer difference. Variables of this type are suitable +** for storing a pointer or pointer sutraction. +************************************************************************/ +#ifdef _WIN64 +typedef unsigned __int64 PRUptrdiff; +#else +typedef unsigned long PRUptrdiff; +#endif + +/************************************************************************ +** TYPES: PRBool +** DESCRIPTION: +** Use PRBool for variables and parameter types. Use PR_FALSE and PR_TRUE +** for clarity of target type in assignments and actual arguments. Use +** 'if (bool)', 'while (!bool)', '(bool) ? x : y' etc., to test booleans +** just as you would C int-valued conditions. +************************************************************************/ +typedef PRIntn PRBool; +#define PR_TRUE 1 +#define PR_FALSE 0 + +/************************************************************************ +** TYPES: PRPackedBool +** DESCRIPTION: +** Use PRPackedBool within structs where bitfields are not desirable +** but minimum and consistant overhead matters. +************************************************************************/ +typedef PRUint8 PRPackedBool; + +/* +** Status code used by some routines that have a single point of failure or +** special status return. +*/ +typedef enum { PR_FAILURE = -1, PR_SUCCESS = 0 } PRStatus; + +#ifndef __PRUNICHAR__ +#define __PRUNICHAR__ +#if defined(WIN32) || defined(XP_MAC) +typedef wchar_t PRUnichar; +#else +typedef PRUint16 PRUnichar; +#endif +#endif + +/* +** WARNING: The undocumented data types PRWord and PRUword are +** only used in the garbage collection and arena code. Do not +** use PRWord and PRUword in new code. +** +** A PRWord is an integer that is the same size as a void*. +** It implements the notion of a "word" in the Java Virtual +** Machine. (See Sec. 3.4 "Words", The Java Virtual Machine +** Specification, Addison-Wesley, September 1996. +** http://java.sun.com/docs/books/vmspec/index.html.) +*/ +#ifdef _WIN64 +typedef __int64 PRWord; +typedef unsigned __int64 PRUword; +#else +typedef long PRWord; +typedef unsigned long PRUword; +#endif + +#if defined(NO_NSPR_10_SUPPORT) +#else +/********* ???????????????? FIX ME ??????????????????????????? *****/ +/********************** Some old definitions until pr=>ds transition is done ***/ +/********************** Also, we are still using NSPR 1.0. GC ******************/ +/* +** Fundamental NSPR macros, used nearly everywhere. +*/ + +#define PR_PUBLIC_API PR_IMPLEMENT + +/* +** Macro body brackets so that macros with compound statement definitions +** behave syntactically more like functions when called. +*/ +#define NSPR_BEGIN_MACRO do { +#define NSPR_END_MACRO } while (0) + +/* +** Macro shorthands for conditional C++ extern block delimiters. +*/ +#ifdef NSPR_BEGIN_EXTERN_C +#undef NSPR_BEGIN_EXTERN_C +#endif +#ifdef NSPR_END_EXTERN_C +#undef NSPR_END_EXTERN_C +#endif + +#ifdef __cplusplus +#define NSPR_BEGIN_EXTERN_C extern "C" { +#define NSPR_END_EXTERN_C } +#else +#define NSPR_BEGIN_EXTERN_C +#define NSPR_END_EXTERN_C +#endif + +#ifdef XP_MAC +#include "protypes.h" +#else +#include "obsolete/protypes.h" +#endif + +/********* ????????????? End Fix me ?????????????????????????????? *****/ +#endif /* NO_NSPR_10_SUPPORT */ + +PR_END_EXTERN_C + +#endif /* prtypes_h___ */ + diff --git a/Templates/Empty/web/source/npplugin/windows/resource.h b/Templates/Empty/web/source/npplugin/windows/resource.h new file mode 100644 index 000000000..18aed9c93 --- /dev/null +++ b/Templates/Empty/web/source/npplugin/windows/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by webgameplugin.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif