| @@ -36,7 +36,7 @@ ifeq ($(CONFIG),Debug) | |||||
| endif | endif | ||||
| JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DDEBUG=1 -D_DEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=5.3.2 -DJUCE_APP_VERSION_HEX=0x50302 $(shell pkg-config --cflags freetype2 libcurl x11 xext xinerama webkit2gtk-4.0 gtk+-x11-3.0) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS) | JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DDEBUG=1 -D_DEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=5.3.2 -DJUCE_APP_VERSION_HEX=0x50302 $(shell pkg-config --cflags freetype2 libcurl x11 xext xinerama webkit2gtk-4.0 gtk+-x11-3.0) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS) | ||||
| JUCE_CPPFLAGS_APP := -DJucePlugin_Build_VST=0 -DJucePlugin_Build_VST3=0 -DJucePlugin_Build_AU=0 -DJucePlugin_Build_AUv3=0 -DJucePlugin_Build_RTAS=0 -DJucePlugin_Build_AAX=0 -DJucePlugin_Build_Standalone=0 | |||||
| JUCE_CPPFLAGS_APP := -DJucePlugin_Build_VST=0 -DJucePlugin_Build_VST3=0 -DJucePlugin_Build_AU=0 -DJucePlugin_Build_AUv3=0 -DJucePlugin_Build_RTAS=0 -DJucePlugin_Build_AAX=0 -DJucePlugin_Build_Standalone=0 -DJucePlugin_Build_Unity=0 | |||||
| JUCE_TARGET_APP := Projucer | JUCE_TARGET_APP := Projucer | ||||
| JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O0 $(CFLAGS) | JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O0 $(CFLAGS) | ||||
| @@ -57,7 +57,7 @@ ifeq ($(CONFIG),Release) | |||||
| endif | endif | ||||
| JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DNDEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=5.3.2 -DJUCE_APP_VERSION_HEX=0x50302 $(shell pkg-config --cflags freetype2 libcurl x11 xext xinerama webkit2gtk-4.0 gtk+-x11-3.0) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS) | JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DNDEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=5.3.2 -DJUCE_APP_VERSION_HEX=0x50302 $(shell pkg-config --cflags freetype2 libcurl x11 xext xinerama webkit2gtk-4.0 gtk+-x11-3.0) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS) | ||||
| JUCE_CPPFLAGS_APP := -DJucePlugin_Build_VST=0 -DJucePlugin_Build_VST3=0 -DJucePlugin_Build_AU=0 -DJucePlugin_Build_AUv3=0 -DJucePlugin_Build_RTAS=0 -DJucePlugin_Build_AAX=0 -DJucePlugin_Build_Standalone=0 | |||||
| JUCE_CPPFLAGS_APP := -DJucePlugin_Build_VST=0 -DJucePlugin_Build_VST3=0 -DJucePlugin_Build_AU=0 -DJucePlugin_Build_AUv3=0 -DJucePlugin_Build_RTAS=0 -DJucePlugin_Build_AAX=0 -DJucePlugin_Build_Standalone=0 -DJucePlugin_Build_Unity=0 | |||||
| JUCE_TARGET_APP := Projucer | JUCE_TARGET_APP := Projucer | ||||
| JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -O3 $(CFLAGS) | JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -O3 $(CFLAGS) | ||||
| @@ -233,6 +233,7 @@ | |||||
| 72ED72174F9DBD0ABD8AFCED = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_PaintElementImage.cpp"; path = "../../Source/ComponentEditor/PaintElements/jucer_PaintElementImage.cpp"; sourceTree = "SOURCE_ROOT"; }; | 72ED72174F9DBD0ABD8AFCED = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_PaintElementImage.cpp"; path = "../../Source/ComponentEditor/PaintElements/jucer_PaintElementImage.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 73DE14CEAD25D3445457013E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_SliderHandler.h"; path = "../../Source/ComponentEditor/Components/jucer_SliderHandler.h"; sourceTree = "SOURCE_ROOT"; }; | 73DE14CEAD25D3445457013E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_SliderHandler.h"; path = "../../Source/ComponentEditor/Components/jucer_SliderHandler.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 75BE2887C6F324B818D80A21 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_SnapGridPainter.h"; path = "../../Source/ComponentEditor/UI/jucer_SnapGridPainter.h"; sourceTree = "SOURCE_ROOT"; }; | 75BE2887C6F324B818D80A21 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_SnapGridPainter.h"; path = "../../Source/ComponentEditor/UI/jucer_SnapGridPainter.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 763A63E75AC802F17D11FE8B = {isa = PBXFileReference; lastKnownFileType = file.cs; name = "jucer_UnityPluginGUIScript.cs"; path = "../../Source/BinaryData/Templates/jucer_UnityPluginGUIScript.cs"; sourceTree = "SOURCE_ROOT"; }; | |||||
| 7687A1374C60A025BDBE98DE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_PointComponent.h"; path = "../../Source/ComponentEditor/PaintElements/jucer_PointComponent.h"; sourceTree = "SOURCE_ROOT"; }; | 7687A1374C60A025BDBE98DE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_PointComponent.h"; path = "../../Source/ComponentEditor/PaintElements/jucer_PointComponent.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 77EA01E7D04BF889930BFF54 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_PaintElementRoundedRectangle.h"; path = "../../Source/ComponentEditor/PaintElements/jucer_PaintElementRoundedRectangle.h"; sourceTree = "SOURCE_ROOT"; }; | 77EA01E7D04BF889930BFF54 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_PaintElementRoundedRectangle.h"; path = "../../Source/ComponentEditor/PaintElements/jucer_PaintElementRoundedRectangle.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 78D0DBC4798FF040FDB90F6D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_GeneratedCode.cpp"; path = "../../Source/ComponentEditor/jucer_GeneratedCode.cpp"; sourceTree = "SOURCE_ROOT"; }; | 78D0DBC4798FF040FDB90F6D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_GeneratedCode.cpp"; path = "../../Source/ComponentEditor/jucer_GeneratedCode.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -493,7 +494,8 @@ | |||||
| 3F7C5B53347A487C7FBD2223, | 3F7C5B53347A487C7FBD2223, | ||||
| 4ECF029E3A69BF42FED1503D, | 4ECF029E3A69BF42FED1503D, | ||||
| 3DC2ED15A9DFAAEF3D2ACDDF, | 3DC2ED15A9DFAAEF3D2ACDDF, | ||||
| E67999BF57B139E00207A374, ); name = Templates; sourceTree = "<group>"; }; | |||||
| E67999BF57B139E00207A374, | |||||
| 763A63E75AC802F17D11FE8B, ); name = Templates; sourceTree = "<group>"; }; | |||||
| A9399733CAA07BDAB958242C = {isa = PBXGroup; children = ( | A9399733CAA07BDAB958242C = {isa = PBXGroup; children = ( | ||||
| 8CF70DA9AB4725126B9F55BE, | 8CF70DA9AB4725126B9F55BE, | ||||
| F0F189518721D46C0F94FD56, | F0F189518721D46C0F94FD56, | ||||
| @@ -822,7 +824,8 @@ | |||||
| "JucePlugin_Build_AUv3=0", | "JucePlugin_Build_AUv3=0", | ||||
| "JucePlugin_Build_RTAS=0", | "JucePlugin_Build_RTAS=0", | ||||
| "JucePlugin_Build_AAX=0", | "JucePlugin_Build_AAX=0", | ||||
| "JucePlugin_Build_Standalone=0", ); | |||||
| "JucePlugin_Build_Standalone=0", | |||||
| "JucePlugin_Build_Unity=0", ); | |||||
| GCC_VERSION = com.apple.compilers.llvm.clang.1_0; | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; | ||||
| HEADER_SEARCH_PATHS = ("../../JuceLibraryCode", "../../../../modules", "$(inherited)"); | HEADER_SEARCH_PATHS = ("../../JuceLibraryCode", "../../../../modules", "$(inherited)"); | ||||
| INFOPLIST_FILE = Info-App.plist; | INFOPLIST_FILE = Info-App.plist; | ||||
| @@ -832,6 +835,7 @@ | |||||
| MACOSX_DEPLOYMENT_TARGET_ppc = 10.4; | MACOSX_DEPLOYMENT_TARGET_ppc = 10.4; | ||||
| OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow -Wno-missing-field-initializers -Wshadow -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wno-ignored-qualifiers -Wunreachable-code"; | OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow -Wno-missing-field-initializers -Wshadow -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wno-ignored-qualifiers -Wunreachable-code"; | ||||
| PRODUCT_BUNDLE_IDENTIFIER = com.juce.theprojucer; | PRODUCT_BUNDLE_IDENTIFIER = com.juce.theprojucer; | ||||
| PRODUCT_NAME = "Projucer"; | |||||
| SDKROOT_ppc = macosx10.5; | SDKROOT_ppc = macosx10.5; | ||||
| USE_HEADERMAP = NO; }; name = Debug; }; | USE_HEADERMAP = NO; }; name = Debug; }; | ||||
| 0BC15DC2E5FE5ECFFB398D49 = {isa = XCBuildConfiguration; buildSettings = { | 0BC15DC2E5FE5ECFFB398D49 = {isa = XCBuildConfiguration; buildSettings = { | ||||
| @@ -855,7 +859,8 @@ | |||||
| "JucePlugin_Build_AUv3=0", | "JucePlugin_Build_AUv3=0", | ||||
| "JucePlugin_Build_RTAS=0", | "JucePlugin_Build_RTAS=0", | ||||
| "JucePlugin_Build_AAX=0", | "JucePlugin_Build_AAX=0", | ||||
| "JucePlugin_Build_Standalone=0", ); | |||||
| "JucePlugin_Build_Standalone=0", | |||||
| "JucePlugin_Build_Unity=0", ); | |||||
| GCC_SYMBOLS_PRIVATE_EXTERN = YES; | GCC_SYMBOLS_PRIVATE_EXTERN = YES; | ||||
| GCC_VERSION = com.apple.compilers.llvm.clang.1_0; | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; | ||||
| HEADER_SEARCH_PATHS = ("../../JuceLibraryCode", "../../../../modules", "$(inherited)"); | HEADER_SEARCH_PATHS = ("../../JuceLibraryCode", "../../../../modules", "$(inherited)"); | ||||
| @@ -867,6 +872,7 @@ | |||||
| MACOSX_DEPLOYMENT_TARGET_ppc = 10.4; | MACOSX_DEPLOYMENT_TARGET_ppc = 10.4; | ||||
| OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow -Wno-missing-field-initializers -Wshadow -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wno-ignored-qualifiers -Wunreachable-code"; | OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow -Wno-missing-field-initializers -Wshadow -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wno-ignored-qualifiers -Wunreachable-code"; | ||||
| PRODUCT_BUNDLE_IDENTIFIER = com.juce.theprojucer; | PRODUCT_BUNDLE_IDENTIFIER = com.juce.theprojucer; | ||||
| PRODUCT_NAME = "Projucer"; | |||||
| SDKROOT_ppc = macosx10.5; | SDKROOT_ppc = macosx10.5; | ||||
| USE_HEADERMAP = NO; }; name = Release; }; | USE_HEADERMAP = NO; }; name = Release; }; | ||||
| C42924A24AB55E6A940423EA = {isa = XCBuildConfiguration; buildSettings = { | C42924A24AB55E6A940423EA = {isa = XCBuildConfiguration; buildSettings = { | ||||
| @@ -74,7 +74,7 @@ | |||||
| <Optimization>Disabled</Optimization> | <Optimization>Disabled</Optimization> | ||||
| <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> | <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> | ||||
| <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | ||||
| <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=5.3.2;JUCE_APP_VERSION_HEX=0x50302;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
| <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=5.3.2;JUCE_APP_VERSION_HEX=0x50302;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
| <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> | <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> | ||||
| <RuntimeTypeInfo>true</RuntimeTypeInfo> | <RuntimeTypeInfo>true</RuntimeTypeInfo> | ||||
| <PrecompiledHeader/> | <PrecompiledHeader/> | ||||
| @@ -115,7 +115,7 @@ | |||||
| <ClCompile> | <ClCompile> | ||||
| <Optimization>Full</Optimization> | <Optimization>Full</Optimization> | ||||
| <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | ||||
| <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=5.3.2;JUCE_APP_VERSION_HEX=0x50302;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
| <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=5.3.2;JUCE_APP_VERSION_HEX=0x50302;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
| <RuntimeLibrary>MultiThreaded</RuntimeLibrary> | <RuntimeLibrary>MultiThreaded</RuntimeLibrary> | ||||
| <RuntimeTypeInfo>true</RuntimeTypeInfo> | <RuntimeTypeInfo>true</RuntimeTypeInfo> | ||||
| <PrecompiledHeader/> | <PrecompiledHeader/> | ||||
| @@ -2065,6 +2065,7 @@ | |||||
| <None Include="..\..\Source\BinaryData\Icons\wizard_Openfile.svg"/> | <None Include="..\..\Source\BinaryData\Icons\wizard_Openfile.svg"/> | ||||
| <None Include="..\..\Source\BinaryData\Icons\wizard_OpenGL.svg"/> | <None Include="..\..\Source\BinaryData\Icons\wizard_OpenGL.svg"/> | ||||
| <None Include="..\..\Source\BinaryData\Icons\wizard_StaticLibrary.svg"/> | <None Include="..\..\Source\BinaryData\Icons\wizard_StaticLibrary.svg"/> | ||||
| <None Include="..\..\Source\BinaryData\Templates\jucer_UnityPluginGUIScript.cs"/> | |||||
| <None Include="..\..\Source\BinaryData\colourscheme_dark.xml"/> | <None Include="..\..\Source\BinaryData\colourscheme_dark.xml"/> | ||||
| <None Include="..\..\Source\BinaryData\colourscheme_light.xml"/> | <None Include="..\..\Source\BinaryData\colourscheme_light.xml"/> | ||||
| <None Include="..\..\Source\BinaryData\nothingtoseehere.txt"/> | <None Include="..\..\Source\BinaryData\nothingtoseehere.txt"/> | ||||
| @@ -3662,6 +3662,9 @@ | |||||
| <None Include="..\..\Source\BinaryData\Icons\wizard_StaticLibrary.svg"> | <None Include="..\..\Source\BinaryData\Icons\wizard_StaticLibrary.svg"> | ||||
| <Filter>Projucer\BinaryData\Icons</Filter> | <Filter>Projucer\BinaryData\Icons</Filter> | ||||
| </None> | </None> | ||||
| <None Include="..\..\Source\BinaryData\Templates\jucer_UnityPluginGUIScript.cs"> | |||||
| <Filter>Projucer\BinaryData\Templates</Filter> | |||||
| </None> | |||||
| <None Include="..\..\Source\BinaryData\colourscheme_dark.xml"> | <None Include="..\..\Source\BinaryData\colourscheme_dark.xml"> | ||||
| <Filter>Projucer\BinaryData</Filter> | <Filter>Projucer\BinaryData</Filter> | ||||
| </None> | </None> | ||||
| @@ -74,7 +74,7 @@ | |||||
| <Optimization>Disabled</Optimization> | <Optimization>Disabled</Optimization> | ||||
| <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> | <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> | ||||
| <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | ||||
| <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=5.3.2;JUCE_APP_VERSION_HEX=0x50302;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
| <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=5.3.2;JUCE_APP_VERSION_HEX=0x50302;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
| <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> | <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> | ||||
| <RuntimeTypeInfo>true</RuntimeTypeInfo> | <RuntimeTypeInfo>true</RuntimeTypeInfo> | ||||
| <PrecompiledHeader/> | <PrecompiledHeader/> | ||||
| @@ -115,7 +115,7 @@ | |||||
| <ClCompile> | <ClCompile> | ||||
| <Optimization>Full</Optimization> | <Optimization>Full</Optimization> | ||||
| <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | ||||
| <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=5.3.2;JUCE_APP_VERSION_HEX=0x50302;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
| <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=5.3.2;JUCE_APP_VERSION_HEX=0x50302;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
| <RuntimeLibrary>MultiThreaded</RuntimeLibrary> | <RuntimeLibrary>MultiThreaded</RuntimeLibrary> | ||||
| <RuntimeTypeInfo>true</RuntimeTypeInfo> | <RuntimeTypeInfo>true</RuntimeTypeInfo> | ||||
| <PrecompiledHeader/> | <PrecompiledHeader/> | ||||
| @@ -2065,6 +2065,7 @@ | |||||
| <None Include="..\..\Source\BinaryData\Icons\wizard_Openfile.svg"/> | <None Include="..\..\Source\BinaryData\Icons\wizard_Openfile.svg"/> | ||||
| <None Include="..\..\Source\BinaryData\Icons\wizard_OpenGL.svg"/> | <None Include="..\..\Source\BinaryData\Icons\wizard_OpenGL.svg"/> | ||||
| <None Include="..\..\Source\BinaryData\Icons\wizard_StaticLibrary.svg"/> | <None Include="..\..\Source\BinaryData\Icons\wizard_StaticLibrary.svg"/> | ||||
| <None Include="..\..\Source\BinaryData\Templates\jucer_UnityPluginGUIScript.cs"/> | |||||
| <None Include="..\..\Source\BinaryData\colourscheme_dark.xml"/> | <None Include="..\..\Source\BinaryData\colourscheme_dark.xml"/> | ||||
| <None Include="..\..\Source\BinaryData\colourscheme_light.xml"/> | <None Include="..\..\Source\BinaryData\colourscheme_light.xml"/> | ||||
| <None Include="..\..\Source\BinaryData\nothingtoseehere.txt"/> | <None Include="..\..\Source\BinaryData\nothingtoseehere.txt"/> | ||||
| @@ -3662,6 +3662,9 @@ | |||||
| <None Include="..\..\Source\BinaryData\Icons\wizard_StaticLibrary.svg"> | <None Include="..\..\Source\BinaryData\Icons\wizard_StaticLibrary.svg"> | ||||
| <Filter>Projucer\BinaryData\Icons</Filter> | <Filter>Projucer\BinaryData\Icons</Filter> | ||||
| </None> | </None> | ||||
| <None Include="..\..\Source\BinaryData\Templates\jucer_UnityPluginGUIScript.cs"> | |||||
| <Filter>Projucer\BinaryData\Templates</Filter> | |||||
| </None> | |||||
| <None Include="..\..\Source\BinaryData\colourscheme_dark.xml"> | <None Include="..\..\Source\BinaryData\colourscheme_dark.xml"> | ||||
| <Filter>Projucer\BinaryData</Filter> | <Filter>Projucer\BinaryData</Filter> | ||||
| </None> | </None> | ||||
| @@ -74,7 +74,7 @@ | |||||
| <Optimization>Disabled</Optimization> | <Optimization>Disabled</Optimization> | ||||
| <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> | <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> | ||||
| <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | ||||
| <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=5.3.2;JUCE_APP_VERSION_HEX=0x50302;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
| <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=5.3.2;JUCE_APP_VERSION_HEX=0x50302;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
| <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> | <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> | ||||
| <RuntimeTypeInfo>true</RuntimeTypeInfo> | <RuntimeTypeInfo>true</RuntimeTypeInfo> | ||||
| <PrecompiledHeader/> | <PrecompiledHeader/> | ||||
| @@ -115,7 +115,7 @@ | |||||
| <ClCompile> | <ClCompile> | ||||
| <Optimization>Full</Optimization> | <Optimization>Full</Optimization> | ||||
| <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | ||||
| <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=5.3.2;JUCE_APP_VERSION_HEX=0x50302;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
| <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=5.3.2;JUCE_APP_VERSION_HEX=0x50302;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
| <RuntimeLibrary>MultiThreaded</RuntimeLibrary> | <RuntimeLibrary>MultiThreaded</RuntimeLibrary> | ||||
| <RuntimeTypeInfo>true</RuntimeTypeInfo> | <RuntimeTypeInfo>true</RuntimeTypeInfo> | ||||
| <PrecompiledHeader/> | <PrecompiledHeader/> | ||||
| @@ -2065,6 +2065,7 @@ | |||||
| <None Include="..\..\Source\BinaryData\Icons\wizard_Openfile.svg"/> | <None Include="..\..\Source\BinaryData\Icons\wizard_Openfile.svg"/> | ||||
| <None Include="..\..\Source\BinaryData\Icons\wizard_OpenGL.svg"/> | <None Include="..\..\Source\BinaryData\Icons\wizard_OpenGL.svg"/> | ||||
| <None Include="..\..\Source\BinaryData\Icons\wizard_StaticLibrary.svg"/> | <None Include="..\..\Source\BinaryData\Icons\wizard_StaticLibrary.svg"/> | ||||
| <None Include="..\..\Source\BinaryData\Templates\jucer_UnityPluginGUIScript.cs"/> | |||||
| <None Include="..\..\Source\BinaryData\colourscheme_dark.xml"/> | <None Include="..\..\Source\BinaryData\colourscheme_dark.xml"/> | ||||
| <None Include="..\..\Source\BinaryData\colourscheme_light.xml"/> | <None Include="..\..\Source\BinaryData\colourscheme_light.xml"/> | ||||
| <None Include="..\..\Source\BinaryData\nothingtoseehere.txt"/> | <None Include="..\..\Source\BinaryData\nothingtoseehere.txt"/> | ||||
| @@ -3662,6 +3662,9 @@ | |||||
| <None Include="..\..\Source\BinaryData\Icons\wizard_StaticLibrary.svg"> | <None Include="..\..\Source\BinaryData\Icons\wizard_StaticLibrary.svg"> | ||||
| <Filter>Projucer\BinaryData\Icons</Filter> | <Filter>Projucer\BinaryData\Icons</Filter> | ||||
| </None> | </None> | ||||
| <None Include="..\..\Source\BinaryData\Templates\jucer_UnityPluginGUIScript.cs"> | |||||
| <Filter>Projucer\BinaryData\Templates</Filter> | |||||
| </None> | |||||
| <None Include="..\..\Source\BinaryData\colourscheme_dark.xml"> | <None Include="..\..\Source\BinaryData\colourscheme_dark.xml"> | ||||
| <Filter>Projucer\BinaryData</Filter> | <Filter>Projucer\BinaryData</Filter> | ||||
| </None> | </None> | ||||
| @@ -7267,8 +7267,194 @@ static const unsigned char temp_binary_data_54[] = | |||||
| const char* jucer_PIPTemplate_h = (const char*) temp_binary_data_54; | const char* jucer_PIPTemplate_h = (const char*) temp_binary_data_54; | ||||
| //================== colourscheme_dark.xml ================== | |||||
| //================== jucer_UnityPluginGUIScript.cs ================== | |||||
| static const unsigned char temp_binary_data_55[] = | static const unsigned char temp_binary_data_55[] = | ||||
| "#if UNITY_EDITOR\n" | |||||
| "\n" | |||||
| "using UnityEditor;\n" | |||||
| "using UnityEngine;\n" | |||||
| "\n" | |||||
| "using System.Collections.Generic;\n" | |||||
| "using System.Runtime.InteropServices;\n" | |||||
| "\n" | |||||
| "public class %%plugin_name%%GUI : IAudioEffectPluginGUI\n" | |||||
| "{\n" | |||||
| " public override string Name { get { return \"%%plugin_name%%\"; } }\n" | |||||
| " public override string Description { get { return \"%%plugin_description%%\"; } }\n" | |||||
| " public override string Vendor { get { return \"%%plugin_vendor%%\"; } }\n" | |||||
| "\n" | |||||
| " //==============================================================================\n" | |||||
| "\t[DllImport(\"%%plugin_name%%\")] static extern System.IntPtr getRenderCallback();\n" | |||||
| "\n" | |||||
| " [DllImport(\"%%plugin_name%%\")] static extern void unityInitialiseTexture (int id, System.IntPtr texture, int width, int height);\n" | |||||
| "\n" | |||||
| " [DllImport(\"%%plugin_name%%\")] static extern void unityMouseDown (int id, float x, float y, EventModifiers mods, int button);\n" | |||||
| " [DllImport(\"%%plugin_name%%\")] static extern void unityMouseDrag (int id, float x, float y, EventModifiers mods, int button);\n" | |||||
| " [DllImport(\"%%plugin_name%%\")] static extern void unityMouseUp (int id, float x, float y, EventModifiers mods);\n" | |||||
| "\n" | |||||
| " [DllImport(\"%%plugin_name%%\")] static extern void unityKeyEvent (int id, KeyCode code, EventModifiers mods, string name);\n" | |||||
| "\n" | |||||
| " [DllImport(\"%%plugin_name%%\")] static extern void unitySetScreenBounds (int id, float x, float y, float w, float h);\n" | |||||
| "\n" | |||||
| " //==============================================================================\n" | |||||
| " private class PluginGUIInstance\n" | |||||
| " {\n" | |||||
| " public PluginGUIInstance (ref IAudioEffectPlugin plugin, int id)\n" | |||||
| " {\n" | |||||
| " instanceID = id;\n" | |||||
| "\n" | |||||
| " float[] arr;\n" | |||||
| " plugin.GetFloatBuffer (\"Editor\", out arr, 1);\n" | |||||
| " hasEditor = (arr[0] > 0.0f);\n" | |||||
| " }\n" | |||||
| "\n" | |||||
| " public void repaint (Rect r)\n" | |||||
| " { \n" | |||||
| " Vector2 newScreenPosition = GUIUtility.GUIToScreenPoint (r.position);\n" | |||||
| "\n" | |||||
| " if (bounds != r \n" | |||||
| " || screenPosition != newScreenPosition)\n" | |||||
| " {\n" | |||||
| " screenPosition = newScreenPosition;\n" | |||||
| " bounds = r;\n" | |||||
| "\n" | |||||
| " unitySetScreenBounds (instanceID, screenPosition.x, screenPosition.y, bounds.width, bounds.height);\n" | |||||
| " setupTexture();\n" | |||||
| " }\n" | |||||
| "\n" | |||||
| "\t\t\tGL.IssuePluginEvent (getRenderCallback(), instanceID);\n" | |||||
| "\n" | |||||
| " texture.SetPixels32 (pixels);\n" | |||||
| " texture.Apply();\n" | |||||
| "\n" | |||||
| " EditorGUI.DrawPreviewTexture (bounds, texture);\n" | |||||
| " }\n" | |||||
| "\n" | |||||
| " public bool handleMouseEvent (EventType eventType)\n" | |||||
| " {\n" | |||||
| " Vector2 mousePos = Event.current.mousePosition;\n" | |||||
| " EventModifiers mods = Event.current.modifiers;\n" | |||||
| "\n" | |||||
| " if (! bounds.Contains (mousePos))\n" | |||||
| " return false;\n" | |||||
| "\n" | |||||
| " Vector2 relativePos = new Vector2 (mousePos.x - bounds.x, mousePos.y - bounds.y);\n" | |||||
| "\n" | |||||
| " if (eventType == EventType.MouseDown) \n" | |||||
| " {\n" | |||||
| " unityMouseDown (instanceID, relativePos.x, relativePos.y, mods, Event.current.button);\n" | |||||
| " GUIUtility.hotControl = GUIUtility.GetControlID (FocusType.Passive);\n" | |||||
| " }\n" | |||||
| " else if (eventType == EventType.MouseUp)\n" | |||||
| " {\n" | |||||
| " unityMouseUp (instanceID, relativePos.x, relativePos.y, mods);\n" | |||||
| " GUIUtility.hotControl = 0;\n" | |||||
| " }\n" | |||||
| " else if (eventType == EventType.MouseDrag) \n" | |||||
| " {\n" | |||||
| " unityMouseDrag (instanceID, relativePos.x, relativePos.y, mods, Event.current.button);\n" | |||||
| " }\n" | |||||
| "\n" | |||||
| " Event.current.Use();\n" | |||||
| "\n" | |||||
| " return true;\n" | |||||
| " }\n" | |||||
| "\n" | |||||
| " public void handleKeyEvent (EventType eventType)\n" | |||||
| " {\n" | |||||
| " if (eventType == EventType.KeyDown)\n" | |||||
| " {\n" | |||||
| " KeyCode code = Event.current.keyCode;\n" | |||||
| "\n" | |||||
| " if (code == KeyCode.None)\n" | |||||
| " return;\n" | |||||
| "\n" | |||||
| " EventModifiers mods = Event.current.modifiers;\n" | |||||
| "\n" | |||||
| " unityKeyEvent (instanceID, code, mods, code.ToString());\n" | |||||
| " }\n" | |||||
| " }\n" | |||||
| "\n" | |||||
| " private void setupTexture()\n" | |||||
| " {\n" | |||||
| " if (pixelHandle.IsAllocated)\n" | |||||
| " pixelHandle.Free();\n" | |||||
| "\n" | |||||
| " texture = new Texture2D ((int) bounds.width, (int) bounds.height, TextureFormat.ARGB32, false);\n" | |||||
| "\n" | |||||
| " pixels = texture.GetPixels32();\n" | |||||
| " pixelHandle = GCHandle.Alloc (pixels, GCHandleType.Pinned);\n" | |||||
| "\n" | |||||
| " unityInitialiseTexture (instanceID, pixelHandle.AddrOfPinnedObject(), texture.width, texture.height);\n" | |||||
| " }\n" | |||||
| "\n" | |||||
| " public int instanceID = -1;\n" | |||||
| " public bool hasEditor;\n" | |||||
| "\n" | |||||
| " private Vector2 screenPosition;\n" | |||||
| " private Rect bounds;\n" | |||||
| "\n" | |||||
| " private Texture2D texture;\n" | |||||
| " private Color32[] pixels;\n" | |||||
| " private GCHandle pixelHandle;\n" | |||||
| " }\n" | |||||
| " List<PluginGUIInstance> guis = new List<PluginGUIInstance>();\n" | |||||
| "\n" | |||||
| " private PluginGUIInstance getGUIInstanceForPlugin (ref IAudioEffectPlugin plugin)\n" | |||||
| " {\n" | |||||
| " float[] idArray;\n" | |||||
| " plugin.GetFloatBuffer (\"ID\", out idArray, 1);\n" | |||||
| "\n" | |||||
| " int id = (int) idArray[0];\n" | |||||
| "\n" | |||||
| " for (int i = 0; i < guis.Count; ++i)\n" | |||||
| " {\n" | |||||
| " if (guis[i].instanceID == id)\n" | |||||
| " return guis[i];\n" | |||||
| " }\n" | |||||
| "\n" | |||||
| " PluginGUIInstance newInstance = new PluginGUIInstance (ref plugin, id);\n" | |||||
| " guis.Add (newInstance);\n" | |||||
| "\n" | |||||
| " return guis[guis.Count - 1];\n" | |||||
| " }\n" | |||||
| "\n" | |||||
| " //==============================================================================\n" | |||||
| " public override bool OnGUI (IAudioEffectPlugin plugin)\n" | |||||
| " {\n" | |||||
| " PluginGUIInstance guiInstance = getGUIInstanceForPlugin (ref plugin);\n" | |||||
| "\n" | |||||
| " if (! guiInstance.hasEditor)\n" | |||||
| " return true;\n" | |||||
| "\n" | |||||
| " float[] arr;\n" | |||||
| " plugin.GetFloatBuffer (\"Size\", out arr, 6);\n" | |||||
| "\n" | |||||
| " Rect r = GUILayoutUtility.GetRect (arr[0], arr[1],\n" | |||||
| " new GUILayoutOption[] { GUILayout.MinWidth (arr[2]), GUILayout.MinHeight (arr[3]),\n" | |||||
| " GUILayout.MaxWidth (arr[4]), GUILayout.MaxHeight (arr[5]) });\n" | |||||
| "\n" | |||||
| " int controlID = GUIUtility.GetControlID (FocusType.Passive);\n" | |||||
| " Event currentEvent = Event.current;\n" | |||||
| " EventType currentEventType = currentEvent.GetTypeForControl (controlID);\n" | |||||
| "\n" | |||||
| " if (currentEventType == EventType.Repaint)\n" | |||||
| " guiInstance.repaint (r);\n" | |||||
| " else if (currentEvent.isMouse)\n" | |||||
| " guiInstance.handleMouseEvent (currentEventType);\n" | |||||
| " else if (currentEvent.isKey)\n" | |||||
| " guiInstance.handleKeyEvent (currentEventType);\n" | |||||
| "\n" | |||||
| " return false;\n" | |||||
| " }\n" | |||||
| "}\n" | |||||
| "\n" | |||||
| "#endif"; | |||||
| const char* jucer_UnityPluginGUIScript_cs = (const char*) temp_binary_data_55; | |||||
| //================== colourscheme_dark.xml ================== | |||||
| static const unsigned char temp_binary_data_56[] = | |||||
| "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" | "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" | ||||
| "\r\n" | "\r\n" | ||||
| "<COLOUR_SCHEME font=\"<Monospaced>; 13.0\">\r\n" | "<COLOUR_SCHEME font=\"<Monospaced>; 13.0\">\r\n" | ||||
| @@ -7293,10 +7479,10 @@ static const unsigned char temp_binary_data_55[] = | |||||
| " <COLOUR name=\"Error\" colour=\"FFE60000\"/>\r\n" | " <COLOUR name=\"Error\" colour=\"FFE60000\"/>\r\n" | ||||
| "</COLOUR_SCHEME>\r\n"; | "</COLOUR_SCHEME>\r\n"; | ||||
| const char* colourscheme_dark_xml = (const char*) temp_binary_data_55; | |||||
| const char* colourscheme_dark_xml = (const char*) temp_binary_data_56; | |||||
| //================== colourscheme_light.xml ================== | //================== colourscheme_light.xml ================== | ||||
| static const unsigned char temp_binary_data_56[] = | |||||
| static const unsigned char temp_binary_data_57[] = | |||||
| "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" | "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" | ||||
| "\r\n" | "\r\n" | ||||
| "<COLOUR_SCHEME font=\"<Monospaced>; 13.0\">\r\n" | "<COLOUR_SCHEME font=\"<Monospaced>; 13.0\">\r\n" | ||||
| @@ -7321,16 +7507,16 @@ static const unsigned char temp_binary_data_56[] = | |||||
| " <COLOUR name=\"Error\" colour=\"ffcc0000\"/>\r\n" | " <COLOUR name=\"Error\" colour=\"ffcc0000\"/>\r\n" | ||||
| "</COLOUR_SCHEME>\r\n"; | "</COLOUR_SCHEME>\r\n"; | ||||
| const char* colourscheme_light_xml = (const char*) temp_binary_data_56; | |||||
| const char* colourscheme_light_xml = (const char*) temp_binary_data_57; | |||||
| //================== nothingtoseehere.txt ================== | //================== nothingtoseehere.txt ================== | ||||
| static const unsigned char temp_binary_data_57[] = | |||||
| static const unsigned char temp_binary_data_58[] = | |||||
| "VUEtMTk3NTkzMTgtNA=="; | "VUEtMTk3NTkzMTgtNA=="; | ||||
| const char* nothingtoseehere_txt = (const char*) temp_binary_data_57; | |||||
| const char* nothingtoseehere_txt = (const char*) temp_binary_data_58; | |||||
| //================== offlinepage.html ================== | //================== offlinepage.html ================== | ||||
| static const unsigned char temp_binary_data_58[] = | |||||
| static const unsigned char temp_binary_data_59[] = | |||||
| "<html>\n" | "<html>\n" | ||||
| " <head>\n" | " <head>\n" | ||||
| " <meta http-equiv=\"X-UA-Compatible\" content=\"IE=11\">\n" | " <meta http-equiv=\"X-UA-Compatible\" content=\"IE=11\">\n" | ||||
| @@ -7374,10 +7560,10 @@ static const unsigned char temp_binary_data_58[] = | |||||
| " </body>\n" | " </body>\n" | ||||
| "</html>"; | "</html>"; | ||||
| const char* offlinepage_html = (const char*) temp_binary_data_58; | |||||
| const char* offlinepage_html = (const char*) temp_binary_data_59; | |||||
| //================== projucer_EULA.txt ================== | //================== projucer_EULA.txt ================== | ||||
| static const unsigned char temp_binary_data_59[] = | |||||
| static const unsigned char temp_binary_data_60[] = | |||||
| "\r\n" | "\r\n" | ||||
| "IMPORTANT NOTICE: PLEASE READ CAREFULLY BEFORE INSTALLING THE SOFTWARE:\r\n" | "IMPORTANT NOTICE: PLEASE READ CAREFULLY BEFORE INSTALLING THE SOFTWARE:\r\n" | ||||
| "\r\n" | "\r\n" | ||||
| @@ -7541,10 +7727,10 @@ static const unsigned char temp_binary_data_59[] = | |||||
| "\r\n" | "\r\n" | ||||
| "10.6. Please note that this License, its subject matter and its formation, are governed by English law. You and we both agree to that the courts of England and Wales will have exclusive jurisdiction.\r\n"; | "10.6. Please note that this License, its subject matter and its formation, are governed by English law. You and we both agree to that the courts of England and Wales will have exclusive jurisdiction.\r\n"; | ||||
| const char* projucer_EULA_txt = (const char*) temp_binary_data_59; | |||||
| const char* projucer_EULA_txt = (const char*) temp_binary_data_60; | |||||
| //================== RecentFilesMenuTemplate.nib ================== | //================== RecentFilesMenuTemplate.nib ================== | ||||
| static const unsigned char temp_binary_data_60[] = | |||||
| static const unsigned char temp_binary_data_61[] = | |||||
| { 98,112,108,105,115,116,48,48,212,0,1,0,2,0,3,0,4,0,5,0,6,1,53,1,54,88,36,118,101,114,115,105,111,110,88,36,111,98,106,101,99,116,115,89,36,97,114,99,104,105,118,101,114,84,36,116,111,112,18,0,1,134,160,175,16,74,0,7,0,8,0,31,0,35,0,36,0,42,0,46,0,50, | { 98,112,108,105,115,116,48,48,212,0,1,0,2,0,3,0,4,0,5,0,6,1,53,1,54,88,36,118,101,114,115,105,111,110,88,36,111,98,106,101,99,116,115,89,36,97,114,99,104,105,118,101,114,84,36,116,111,112,18,0,1,134,160,175,16,74,0,7,0,8,0,31,0,35,0,36,0,42,0,46,0,50, | ||||
| 0,53,0,57,0,74,0,77,0,78,0,86,0,87,0,97,0,112,0,113,0,114,0,119,0,120,0,121,0,124,0,128,0,129,0,132,0,143,0,144,0,145,0,149,0,153,0,162,0,163,0,164,0,169,0,173,0,180,0,181,0,182,0,185,0,192,0,193,0,200,0,201,0,208,0,209,0,216,0,217,0,224,0,225,0,226, | 0,53,0,57,0,74,0,77,0,78,0,86,0,87,0,97,0,112,0,113,0,114,0,119,0,120,0,121,0,124,0,128,0,129,0,132,0,143,0,144,0,145,0,149,0,153,0,162,0,163,0,164,0,169,0,173,0,180,0,181,0,182,0,185,0,192,0,193,0,200,0,201,0,208,0,209,0,216,0,217,0,224,0,225,0,226, | ||||
| 0,229,0,230,0,232,0,249,1,11,1,29,1,30,1,31,1,32,1,33,1,34,1,35,1,36,1,37,1,38,1,39,1,40,1,41,1,42,1,43,1,44,1,47,1,50,85,36,110,117,108,108,219,0,9,0,10,0,11,0,12,0,13,0,14,0,15,0,16,0,17,0,18,0,19,0,20,0,21,0,22,0,23,0,24,0,25,0,26,0,27,0,28,0,29,0, | 0,229,0,230,0,232,0,249,1,11,1,29,1,30,1,31,1,32,1,33,1,34,1,35,1,36,1,37,1,38,1,39,1,40,1,41,1,42,1,43,1,44,1,47,1,50,85,36,110,117,108,108,219,0,9,0,10,0,11,0,12,0,13,0,14,0,15,0,16,0,17,0,18,0,19,0,20,0,21,0,22,0,23,0,24,0,25,0,26,0,27,0,28,0,29,0, | ||||
| @@ -7581,7 +7767,7 @@ static const unsigned char temp_binary_data_60[] = | |||||
| 7,157,7,159,7,161,7,163,7,165,7,167,7,169,7,171,7,173,7,175,7,177,7,179,7,181,7,190,7,192,7,225,7,227,7,229,7,231,7,233,7,235,7,237,7,239,7,241,7,243,7,245,7,247,7,249,7,251,7,253,7,255,8,2,8,5,8,8,8,11,8,14,8,17,8,20,8,23,8,26,8,29,8,32,8,35,8,38,8, | 7,157,7,159,7,161,7,163,7,165,7,167,7,169,7,171,7,173,7,175,7,177,7,179,7,181,7,190,7,192,7,225,7,227,7,229,7,231,7,233,7,235,7,237,7,239,7,241,7,243,7,245,7,247,7,249,7,251,7,253,7,255,8,2,8,5,8,8,8,11,8,14,8,17,8,20,8,23,8,26,8,29,8,32,8,35,8,38,8, | ||||
| 41,8,44,8,53,8,55,8,56,8,65,8,67,8,68,8,77,8,92,8,97,8,115,8,120,8,134,0,0,0,0,0,0,2,2,0,0,0,0,0,0,1,57,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,136,0,0 }; | 41,8,44,8,53,8,55,8,56,8,65,8,67,8,68,8,77,8,92,8,97,8,115,8,120,8,134,0,0,0,0,0,0,2,2,0,0,0,0,0,0,1,57,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,136,0,0 }; | ||||
| const char* RecentFilesMenuTemplate_nib = (const char*) temp_binary_data_60; | |||||
| const char* RecentFilesMenuTemplate_nib = (const char*) temp_binary_data_61; | |||||
| const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) | const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) | ||||
| @@ -7648,6 +7834,7 @@ const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) | |||||
| case 0xbc050edc: numBytes = 4926; return jucer_PIPAudioProcessorTemplate_h; | case 0xbc050edc: numBytes = 4926; return jucer_PIPAudioProcessorTemplate_h; | ||||
| case 0xf4ca9e9a: numBytes = 2447; return jucer_PIPMain_cpp; | case 0xf4ca9e9a: numBytes = 2447; return jucer_PIPMain_cpp; | ||||
| case 0x0b16e320: numBytes = 517; return jucer_PIPTemplate_h; | case 0x0b16e320: numBytes = 517; return jucer_PIPTemplate_h; | ||||
| case 0xcd472557: numBytes = 6426; return jucer_UnityPluginGUIScript_cs; | |||||
| case 0x763d39dc: numBytes = 1050; return colourscheme_dark_xml; | case 0x763d39dc: numBytes = 1050; return colourscheme_dark_xml; | ||||
| case 0xe8b08520: numBytes = 1050; return colourscheme_light_xml; | case 0xe8b08520: numBytes = 1050; return colourscheme_light_xml; | ||||
| case 0x938e96ec: numBytes = 20; return nothingtoseehere_txt; | case 0x938e96ec: numBytes = 20; return nothingtoseehere_txt; | ||||
| @@ -7718,6 +7905,7 @@ const char* namedResourceList[] = | |||||
| "jucer_PIPAudioProcessorTemplate_h", | "jucer_PIPAudioProcessorTemplate_h", | ||||
| "jucer_PIPMain_cpp", | "jucer_PIPMain_cpp", | ||||
| "jucer_PIPTemplate_h", | "jucer_PIPTemplate_h", | ||||
| "jucer_UnityPluginGUIScript_cs", | |||||
| "colourscheme_dark_xml", | "colourscheme_dark_xml", | ||||
| "colourscheme_light_xml", | "colourscheme_light_xml", | ||||
| "nothingtoseehere_txt", | "nothingtoseehere_txt", | ||||
| @@ -7783,6 +7971,7 @@ const char* originalFilenames[] = | |||||
| "jucer_PIPAudioProcessorTemplate.h", | "jucer_PIPAudioProcessorTemplate.h", | ||||
| "jucer_PIPMain.cpp", | "jucer_PIPMain.cpp", | ||||
| "jucer_PIPTemplate.h", | "jucer_PIPTemplate.h", | ||||
| "jucer_UnityPluginGUIScript.cs", | |||||
| "colourscheme_dark.xml", | "colourscheme_dark.xml", | ||||
| "colourscheme_light.xml", | "colourscheme_light.xml", | ||||
| "nothingtoseehere.txt", | "nothingtoseehere.txt", | ||||
| @@ -173,6 +173,9 @@ namespace BinaryData | |||||
| extern const char* jucer_PIPTemplate_h; | extern const char* jucer_PIPTemplate_h; | ||||
| const int jucer_PIPTemplate_hSize = 517; | const int jucer_PIPTemplate_hSize = 517; | ||||
| extern const char* jucer_UnityPluginGUIScript_cs; | |||||
| const int jucer_UnityPluginGUIScript_csSize = 6426; | |||||
| extern const char* colourscheme_dark_xml; | extern const char* colourscheme_dark_xml; | ||||
| const int colourscheme_dark_xmlSize = 1050; | const int colourscheme_dark_xmlSize = 1050; | ||||
| @@ -192,7 +195,7 @@ namespace BinaryData | |||||
| const int RecentFilesMenuTemplate_nibSize = 2842; | const int RecentFilesMenuTemplate_nibSize = 2842; | ||||
| // Number of elements in the namedResourceList and originalFileNames arrays. | // Number of elements in the namedResourceList and originalFileNames arrays. | ||||
| const int namedResourceListSize = 61; | |||||
| const int namedResourceListSize = 62; | |||||
| // Points to the start of a list of resource names. | // Points to the start of a list of resource names. | ||||
| extern const char* namedResourceList[]; | extern const char* namedResourceList[]; | ||||
| @@ -263,6 +263,8 @@ | |||||
| file="Source/BinaryData/Templates/jucer_PIPMain.cpp"/> | file="Source/BinaryData/Templates/jucer_PIPMain.cpp"/> | ||||
| <FILE id="WqDCf0" name="jucer_PIPTemplate.h" compile="0" resource="1" | <FILE id="WqDCf0" name="jucer_PIPTemplate.h" compile="0" resource="1" | ||||
| file="Source/BinaryData/Templates/jucer_PIPTemplate.h"/> | file="Source/BinaryData/Templates/jucer_PIPTemplate.h"/> | ||||
| <FILE id="wrkU1v" name="jucer_UnityPluginGUIScript.cs" compile="0" | |||||
| resource="1" file="Source/BinaryData/Templates/jucer_UnityPluginGUIScript.cs"/> | |||||
| </GROUP> | </GROUP> | ||||
| <FILE id="oXM3fR" name="colourscheme_dark.xml" compile="0" resource="1" | <FILE id="oXM3fR" name="colourscheme_dark.xml" compile="0" resource="1" | ||||
| file="Source/BinaryData/colourscheme_dark.xml"/> | file="Source/BinaryData/colourscheme_dark.xml"/> | ||||
| @@ -0,0 +1,181 @@ | |||||
| #if UNITY_EDITOR | |||||
| using UnityEditor; | |||||
| using UnityEngine; | |||||
| using System.Collections.Generic; | |||||
| using System.Runtime.InteropServices; | |||||
| public class %%plugin_name%%GUI : IAudioEffectPluginGUI | |||||
| { | |||||
| public override string Name { get { return "%%plugin_name%%"; } } | |||||
| public override string Description { get { return "%%plugin_description%%"; } } | |||||
| public override string Vendor { get { return "%%plugin_vendor%%"; } } | |||||
| //============================================================================== | |||||
| [DllImport("%%plugin_name%%")] static extern System.IntPtr getRenderCallback(); | |||||
| [DllImport("%%plugin_name%%")] static extern void unityInitialiseTexture (int id, System.IntPtr texture, int width, int height); | |||||
| [DllImport("%%plugin_name%%")] static extern void unityMouseDown (int id, float x, float y, EventModifiers mods, int button); | |||||
| [DllImport("%%plugin_name%%")] static extern void unityMouseDrag (int id, float x, float y, EventModifiers mods, int button); | |||||
| [DllImport("%%plugin_name%%")] static extern void unityMouseUp (int id, float x, float y, EventModifiers mods); | |||||
| [DllImport("%%plugin_name%%")] static extern void unityKeyEvent (int id, KeyCode code, EventModifiers mods, string name); | |||||
| [DllImport("%%plugin_name%%")] static extern void unitySetScreenBounds (int id, float x, float y, float w, float h); | |||||
| //============================================================================== | |||||
| private class PluginGUIInstance | |||||
| { | |||||
| public PluginGUIInstance (ref IAudioEffectPlugin plugin, int id) | |||||
| { | |||||
| instanceID = id; | |||||
| float[] arr; | |||||
| plugin.GetFloatBuffer ("Editor", out arr, 1); | |||||
| hasEditor = (arr[0] > 0.0f); | |||||
| } | |||||
| public void repaint (Rect r) | |||||
| { | |||||
| Vector2 newScreenPosition = GUIUtility.GUIToScreenPoint (r.position); | |||||
| if (bounds != r | |||||
| || screenPosition != newScreenPosition) | |||||
| { | |||||
| screenPosition = newScreenPosition; | |||||
| bounds = r; | |||||
| unitySetScreenBounds (instanceID, screenPosition.x, screenPosition.y, bounds.width, bounds.height); | |||||
| setupTexture(); | |||||
| } | |||||
| GL.IssuePluginEvent (getRenderCallback(), instanceID); | |||||
| texture.SetPixels32 (pixels); | |||||
| texture.Apply(); | |||||
| EditorGUI.DrawPreviewTexture (bounds, texture); | |||||
| } | |||||
| public bool handleMouseEvent (EventType eventType) | |||||
| { | |||||
| Vector2 mousePos = Event.current.mousePosition; | |||||
| EventModifiers mods = Event.current.modifiers; | |||||
| if (! bounds.Contains (mousePos)) | |||||
| return false; | |||||
| Vector2 relativePos = new Vector2 (mousePos.x - bounds.x, mousePos.y - bounds.y); | |||||
| if (eventType == EventType.MouseDown) | |||||
| { | |||||
| unityMouseDown (instanceID, relativePos.x, relativePos.y, mods, Event.current.button); | |||||
| GUIUtility.hotControl = GUIUtility.GetControlID (FocusType.Passive); | |||||
| } | |||||
| else if (eventType == EventType.MouseUp) | |||||
| { | |||||
| unityMouseUp (instanceID, relativePos.x, relativePos.y, mods); | |||||
| GUIUtility.hotControl = 0; | |||||
| } | |||||
| else if (eventType == EventType.MouseDrag) | |||||
| { | |||||
| unityMouseDrag (instanceID, relativePos.x, relativePos.y, mods, Event.current.button); | |||||
| } | |||||
| Event.current.Use(); | |||||
| return true; | |||||
| } | |||||
| public void handleKeyEvent (EventType eventType) | |||||
| { | |||||
| if (eventType == EventType.KeyDown) | |||||
| { | |||||
| KeyCode code = Event.current.keyCode; | |||||
| if (code == KeyCode.None) | |||||
| return; | |||||
| EventModifiers mods = Event.current.modifiers; | |||||
| unityKeyEvent (instanceID, code, mods, code.ToString()); | |||||
| } | |||||
| } | |||||
| private void setupTexture() | |||||
| { | |||||
| if (pixelHandle.IsAllocated) | |||||
| pixelHandle.Free(); | |||||
| texture = new Texture2D ((int) bounds.width, (int) bounds.height, TextureFormat.ARGB32, false); | |||||
| pixels = texture.GetPixels32(); | |||||
| pixelHandle = GCHandle.Alloc (pixels, GCHandleType.Pinned); | |||||
| unityInitialiseTexture (instanceID, pixelHandle.AddrOfPinnedObject(), texture.width, texture.height); | |||||
| } | |||||
| public int instanceID = -1; | |||||
| public bool hasEditor; | |||||
| private Vector2 screenPosition; | |||||
| private Rect bounds; | |||||
| private Texture2D texture; | |||||
| private Color32[] pixels; | |||||
| private GCHandle pixelHandle; | |||||
| } | |||||
| List<PluginGUIInstance> guis = new List<PluginGUIInstance>(); | |||||
| private PluginGUIInstance getGUIInstanceForPlugin (ref IAudioEffectPlugin plugin) | |||||
| { | |||||
| float[] idArray; | |||||
| plugin.GetFloatBuffer ("ID", out idArray, 1); | |||||
| int id = (int) idArray[0]; | |||||
| for (int i = 0; i < guis.Count; ++i) | |||||
| { | |||||
| if (guis[i].instanceID == id) | |||||
| return guis[i]; | |||||
| } | |||||
| PluginGUIInstance newInstance = new PluginGUIInstance (ref plugin, id); | |||||
| guis.Add (newInstance); | |||||
| return guis[guis.Count - 1]; | |||||
| } | |||||
| //============================================================================== | |||||
| public override bool OnGUI (IAudioEffectPlugin plugin) | |||||
| { | |||||
| PluginGUIInstance guiInstance = getGUIInstanceForPlugin (ref plugin); | |||||
| if (! guiInstance.hasEditor) | |||||
| return true; | |||||
| float[] arr; | |||||
| plugin.GetFloatBuffer ("Size", out arr, 6); | |||||
| Rect r = GUILayoutUtility.GetRect (arr[0], arr[1], | |||||
| new GUILayoutOption[] { GUILayout.MinWidth (arr[2]), GUILayout.MinHeight (arr[3]), | |||||
| GUILayout.MaxWidth (arr[4]), GUILayout.MaxHeight (arr[5]) }); | |||||
| int controlID = GUIUtility.GetControlID (FocusType.Passive); | |||||
| Event currentEvent = Event.current; | |||||
| EventType currentEventType = currentEvent.GetTypeForControl (controlID); | |||||
| if (currentEventType == EventType.Repaint) | |||||
| guiInstance.repaint (r); | |||||
| else if (currentEvent.isMouse) | |||||
| guiInstance.handleMouseEvent (currentEventType); | |||||
| else if (currentEvent.isKey) | |||||
| guiInstance.handleKeyEvent (currentEventType); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| #endif | |||||
| @@ -822,6 +822,8 @@ bool Project::shouldBuildTargetType (ProjectType::Target::Type targetType) const | |||||
| return shouldBuildAUv3(); | return shouldBuildAUv3(); | ||||
| case ProjectType::Target::StandalonePlugIn: | case ProjectType::Target::StandalonePlugIn: | ||||
| return shouldBuildStandalonePlugin(); | return shouldBuildStandalonePlugin(); | ||||
| case ProjectType::Target::UnityPlugIn: | |||||
| return shouldBuildUnityPlugin(); | |||||
| case ProjectType::Target::AggregateTarget: | case ProjectType::Target::AggregateTarget: | ||||
| case ProjectType::Target::SharedCodeTarget: | case ProjectType::Target::SharedCodeTarget: | ||||
| return projectType.isAudioPlugin(); | return projectType.isAudioPlugin(); | ||||
| @@ -843,6 +845,7 @@ ProjectType::Target::Type Project::getTargetTypeFromFilePath (const File& file, | |||||
| else if (LibraryModule::CompileUnit::hasSuffix (file, "_VST2")) return ProjectType::Target::VSTPlugIn; | else if (LibraryModule::CompileUnit::hasSuffix (file, "_VST2")) return ProjectType::Target::VSTPlugIn; | ||||
| else if (LibraryModule::CompileUnit::hasSuffix (file, "_VST3")) return ProjectType::Target::VST3PlugIn; | else if (LibraryModule::CompileUnit::hasSuffix (file, "_VST3")) return ProjectType::Target::VST3PlugIn; | ||||
| else if (LibraryModule::CompileUnit::hasSuffix (file, "_Standalone")) return ProjectType::Target::StandalonePlugIn; | else if (LibraryModule::CompileUnit::hasSuffix (file, "_Standalone")) return ProjectType::Target::StandalonePlugIn; | ||||
| else if (LibraryModule::CompileUnit::hasSuffix (file, "_Unity")) return ProjectType::Target::UnityPlugIn; | |||||
| return (returnSharedTargetIfNoValidSuffix ? ProjectType::Target::SharedCodeTarget : ProjectType::Target::unspecified); | return (returnSharedTargetIfNoValidSuffix ? ProjectType::Target::SharedCodeTarget : ProjectType::Target::unspecified); | ||||
| } | } | ||||
| @@ -862,6 +865,7 @@ const char* ProjectType::Target::getName() const noexcept | |||||
| case AudioUnitv3PlugIn: return "AUv3 AppExtension"; | case AudioUnitv3PlugIn: return "AUv3 AppExtension"; | ||||
| case AAXPlugIn: return "AAX"; | case AAXPlugIn: return "AAX"; | ||||
| case RTASPlugIn: return "RTAS"; | case RTASPlugIn: return "RTAS"; | ||||
| case UnityPlugIn: return "Unity Plugin"; | |||||
| case SharedCodeTarget: return "Shared Code"; | case SharedCodeTarget: return "Shared Code"; | ||||
| case AggregateTarget: return "All"; | case AggregateTarget: return "All"; | ||||
| default: return "undefined"; | default: return "undefined"; | ||||
| @@ -883,6 +887,7 @@ ProjectType::Target::TargetFileType ProjectType::Target::getTargetFileType() con | |||||
| case AudioUnitv3PlugIn: return macOSAppex; | case AudioUnitv3PlugIn: return macOSAppex; | ||||
| case AAXPlugIn: return pluginBundle; | case AAXPlugIn: return pluginBundle; | ||||
| case RTASPlugIn: return pluginBundle; | case RTASPlugIn: return pluginBundle; | ||||
| case UnityPlugIn: return pluginBundle; | |||||
| case SharedCodeTarget: return staticLibrary; | case SharedCodeTarget: return staticLibrary; | ||||
| default: | default: | ||||
| break; | break; | ||||
| @@ -1016,9 +1021,10 @@ void Project::createPropertyEditors (PropertyListBuilder& props) | |||||
| void Project::createAudioPluginPropertyEditors (PropertyListBuilder& props) | void Project::createAudioPluginPropertyEditors (PropertyListBuilder& props) | ||||
| { | { | ||||
| props.add (new MultiChoicePropertyComponent (pluginFormatsValue, "Plugin Formats", | props.add (new MultiChoicePropertyComponent (pluginFormatsValue, "Plugin Formats", | ||||
| { "VST", "VST3", "AU", "AUv3", "RTAS", "AAX", "Standalone", "Enable IAA" }, | |||||
| { "VST", "VST3", "AU", "AUv3", "RTAS", "AAX", "Standalone", "Unity", "Enable IAA" }, | |||||
| { Ids::buildVST.toString(), Ids::buildVST3.toString(), Ids::buildAU.toString(), Ids::buildAUv3.toString(), | { Ids::buildVST.toString(), Ids::buildVST3.toString(), Ids::buildAU.toString(), Ids::buildAUv3.toString(), | ||||
| Ids::buildRTAS.toString(), Ids::buildAAX.toString(), Ids::buildStandalone.toString(), Ids::enableIAA.toString() }), | |||||
| Ids::buildRTAS.toString(), Ids::buildAAX.toString(), Ids::buildStandalone.toString(), Ids::buildUnity.toString(), | |||||
| Ids::enableIAA.toString() }), | |||||
| "Plugin formats to build."); | "Plugin formats to build."); | ||||
| props.add (new MultiChoicePropertyComponent (pluginCharacteristicsValue, "Plugin Characteristics", | props.add (new MultiChoicePropertyComponent (pluginCharacteristicsValue, "Plugin Characteristics", | ||||
| { "Plugin is a Synth", "Plugin MIDI Input", "Plugin MIDI Output", "MIDI Effect Plugin", "Plugin Editor Requires Keyboard Focus", | { "Plugin is a Synth", "Plugin MIDI Input", "Plugin MIDI Output", "MIDI Effect Plugin", "Plugin Editor Requires Keyboard Focus", | ||||
| @@ -158,6 +158,7 @@ public: | |||||
| bool shouldBuildRTAS() const { return checkMultiChoiceVar (pluginFormatsValue, Ids::buildRTAS); } | bool shouldBuildRTAS() const { return checkMultiChoiceVar (pluginFormatsValue, Ids::buildRTAS); } | ||||
| bool shouldBuildAAX() const { return checkMultiChoiceVar (pluginFormatsValue, Ids::buildAAX); } | bool shouldBuildAAX() const { return checkMultiChoiceVar (pluginFormatsValue, Ids::buildAAX); } | ||||
| bool shouldBuildStandalonePlugin() const { return checkMultiChoiceVar (pluginFormatsValue, Ids::buildStandalone); } | bool shouldBuildStandalonePlugin() const { return checkMultiChoiceVar (pluginFormatsValue, Ids::buildStandalone); } | ||||
| bool shouldBuildUnityPlugin() const { return checkMultiChoiceVar (pluginFormatsValue, Ids::buildUnity); } | |||||
| bool shouldEnableIAA() const { return checkMultiChoiceVar (pluginFormatsValue, Ids::enableIAA); } | bool shouldEnableIAA() const { return checkMultiChoiceVar (pluginFormatsValue, Ids::enableIAA); } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -199,6 +200,15 @@ public: | |||||
| String getIAATypeCode(); | String getIAATypeCode(); | ||||
| String getIAAPluginName(); | String getIAAPluginName(); | ||||
| String getUnityScriptName() const { return addUnityPluginPrefixIfNecessary (getProjectNameString()) + "_UnityScript.cs"; } | |||||
| static String addUnityPluginPrefixIfNecessary (const String& name) | |||||
| { | |||||
| if (! name.startsWithIgnoreCase ("audioplugin")) | |||||
| return "audioplugin_" + name; | |||||
| return name; | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| bool isAUPluginHost(); | bool isAUPluginHost(); | ||||
| bool isVSTPluginHost(); | bool isVSTPluginHost(); | ||||
| @@ -67,6 +67,7 @@ public: | |||||
| AudioUnitPlugIn = 14, | AudioUnitPlugIn = 14, | ||||
| AudioUnitv3PlugIn = 15, | AudioUnitv3PlugIn = 15, | ||||
| StandalonePlugIn = 16, | StandalonePlugIn = 16, | ||||
| UnityPlugIn = 17, | |||||
| SharedCodeTarget = 20, // internal | SharedCodeTarget = 20, // internal | ||||
| AggregateTarget = 21, | AggregateTarget = 21, | ||||
| @@ -186,6 +187,7 @@ struct ProjectType_AudioPlugin : public ProjectType | |||||
| case Target::AudioUnitPlugIn: | case Target::AudioUnitPlugIn: | ||||
| case Target::AudioUnitv3PlugIn: | case Target::AudioUnitv3PlugIn: | ||||
| case Target::StandalonePlugIn: | case Target::StandalonePlugIn: | ||||
| case Target::UnityPlugIn: | |||||
| case Target::SharedCodeTarget: | case Target::SharedCodeTarget: | ||||
| case Target::AggregateTarget: | case Target::AggregateTarget: | ||||
| return true; | return true; | ||||
| @@ -158,7 +158,8 @@ public: | |||||
| vstBinaryLocation (config, Ids::vstBinaryLocation, getUndoManager()), | vstBinaryLocation (config, Ids::vstBinaryLocation, getUndoManager()), | ||||
| vst3BinaryLocation (config, Ids::vst3BinaryLocation, getUndoManager()), | vst3BinaryLocation (config, Ids::vst3BinaryLocation, getUndoManager()), | ||||
| rtasBinaryLocation (config, Ids::rtasBinaryLocation, getUndoManager()), | rtasBinaryLocation (config, Ids::rtasBinaryLocation, getUndoManager()), | ||||
| aaxBinaryLocation (config, Ids::aaxBinaryLocation, getUndoManager()) | |||||
| aaxBinaryLocation (config, Ids::aaxBinaryLocation, getUndoManager()), | |||||
| unityPluginBinaryLocation (config, Ids::unityPluginBinaryLocation, getUndoManager(), {}) | |||||
| { | { | ||||
| if (! isDebug()) | if (! isDebug()) | ||||
| updateOldLTOSetting(); | updateOldLTOSetting(); | ||||
| @@ -203,6 +204,7 @@ public: | |||||
| String getVST3BinaryLocationString() const { return vst3BinaryLocation.get(); } | String getVST3BinaryLocationString() const { return vst3BinaryLocation.get(); } | ||||
| String getRTASBinaryLocationString() const { return rtasBinaryLocation.get();} | String getRTASBinaryLocationString() const { return rtasBinaryLocation.get();} | ||||
| String getAAXBinaryLocationString() const { return aaxBinaryLocation.get();} | String getAAXBinaryLocationString() const { return aaxBinaryLocation.get();} | ||||
| String getUnityPluginBinaryLocationString() const { return unityPluginBinaryLocation.get(); } | |||||
| //============================================================================== | //============================================================================== | ||||
| String createMSVCConfigName() const | String createMSVCConfigName() const | ||||
| @@ -210,9 +212,9 @@ public: | |||||
| return getName() + "|" + (is64Bit() ? "x64" : "Win32"); | return getName() + "|" + (is64Bit() ? "x64" : "Win32"); | ||||
| } | } | ||||
| String getOutputFilename (const String& suffix, bool forceSuffix) const | |||||
| String getOutputFilename (const String& suffix, bool forceSuffix, bool forceUnityPrefix) const | |||||
| { | { | ||||
| auto target = File::createLegalFileName (getTargetBinaryNameString().trim()); | |||||
| auto target = File::createLegalFileName (getTargetBinaryNameString (forceUnityPrefix).trim()); | |||||
| if (forceSuffix || ! target.containsChar ('.')) | if (forceSuffix || ! target.containsChar ('.')) | ||||
| return target.upToLastOccurrenceOf (".", false, false) + suffix; | return target.upToLastOccurrenceOf (".", false, false) + suffix; | ||||
| @@ -308,7 +310,7 @@ public: | |||||
| generateManifestValue, enableIncrementalLinkingValue, useRuntimeLibDLLValue, intermediatesPathValue, | generateManifestValue, enableIncrementalLinkingValue, useRuntimeLibDLLValue, intermediatesPathValue, | ||||
| characterSetValue, architectureTypeValue, fastMathValue, debugInformationFormatValue, pluginBinaryCopyStepValue; | characterSetValue, architectureTypeValue, fastMathValue, debugInformationFormatValue, pluginBinaryCopyStepValue; | ||||
| ValueWithDefault vstBinaryLocation, vst3BinaryLocation, rtasBinaryLocation, aaxBinaryLocation; | |||||
| ValueWithDefault vstBinaryLocation, vst3BinaryLocation, rtasBinaryLocation, aaxBinaryLocation, unityPluginBinaryLocation; | |||||
| Value architectureValueToListenTo; | Value architectureValueToListenTo; | ||||
| @@ -321,8 +323,8 @@ public: | |||||
| void addVisualStudioPluginInstallPathProperties (PropertyListBuilder& props) | void addVisualStudioPluginInstallPathProperties (PropertyListBuilder& props) | ||||
| { | { | ||||
| auto isBuildingAnyPlugins = (project.shouldBuildVST() || project.shouldBuildVST3() | |||||
| || project.shouldBuildRTAS() || project.shouldBuildAAX()); | |||||
| auto isBuildingAnyPlugins = (project.shouldBuildVST() || project.shouldBuildVST3() || project.shouldBuildRTAS() | |||||
| || project.shouldBuildAAX() || project.shouldBuildUnityPlugin()); | |||||
| if (isBuildingAnyPlugins) | if (isBuildingAnyPlugins) | ||||
| props.add (new ChoicePropertyComponent (pluginBinaryCopyStepValue, "Enable Plugin Copy Step"), | props.add (new ChoicePropertyComponent (pluginBinaryCopyStepValue, "Enable Plugin Copy Step"), | ||||
| @@ -348,6 +350,11 @@ public: | |||||
| 1024, false), | 1024, false), | ||||
| "The folder in which the compiled AAX binary should be placed."); | "The folder in which the compiled AAX binary should be placed."); | ||||
| if (project.shouldBuildUnityPlugin()) | |||||
| props.add (new TextPropertyComponentWithEnablement (unityPluginBinaryLocation, pluginBinaryCopyStepValue, "Unity Binary Location", | |||||
| 1024, false), | |||||
| "The folder in which the compiled Unity plugin binary and associated C# GUI script should be placed."); | |||||
| } | } | ||||
| void setPluginBinaryCopyLocationDefaults() | void setPluginBinaryCopyLocationDefaults() | ||||
| @@ -497,7 +504,7 @@ public: | |||||
| { | { | ||||
| auto* targetName = props->createNewChildElement ("TargetName"); | auto* targetName = props->createNewChildElement ("TargetName"); | ||||
| setConditionAttribute (*targetName, config); | setConditionAttribute (*targetName, config); | ||||
| targetName->addTextElement (config.getOutputFilename ("", false)); | |||||
| targetName->addTextElement (config.getOutputFilename ("", false, type == UnityPlugIn)); | |||||
| } | } | ||||
| { | { | ||||
| @@ -608,12 +615,12 @@ public: | |||||
| { | { | ||||
| auto* link = group->createNewChildElement ("Link"); | auto* link = group->createNewChildElement ("Link"); | ||||
| link->createNewChildElement ("OutputFile")->addTextElement (getOutputFilePath (config)); | |||||
| link->createNewChildElement ("OutputFile")->addTextElement (getOutputFilePath (config, type == UnityPlugIn)); | |||||
| link->createNewChildElement ("SuppressStartupBanner")->addTextElement ("true"); | link->createNewChildElement ("SuppressStartupBanner")->addTextElement ("true"); | ||||
| link->createNewChildElement ("IgnoreSpecificDefaultLibraries")->addTextElement (isDebug ? "libcmt.lib; msvcrt.lib;;%(IgnoreSpecificDefaultLibraries)" | link->createNewChildElement ("IgnoreSpecificDefaultLibraries")->addTextElement (isDebug ? "libcmt.lib; msvcrt.lib;;%(IgnoreSpecificDefaultLibraries)" | ||||
| : "%(IgnoreSpecificDefaultLibraries)"); | : "%(IgnoreSpecificDefaultLibraries)"); | ||||
| link->createNewChildElement ("GenerateDebugInformation")->addTextElement ((isDebug || config.shouldGenerateDebugSymbols()) ? "true" : "false"); | link->createNewChildElement ("GenerateDebugInformation")->addTextElement ((isDebug || config.shouldGenerateDebugSymbols()) ? "true" : "false"); | ||||
| link->createNewChildElement ("ProgramDatabaseFile")->addTextElement (getOwner().getIntDirFile (config, config.getOutputFilename (".pdb", true))); | |||||
| link->createNewChildElement ("ProgramDatabaseFile")->addTextElement (getOwner().getIntDirFile (config, config.getOutputFilename (".pdb", true, type == UnityPlugIn))); | |||||
| link->createNewChildElement ("SubSystem")->addTextElement (type == ConsoleApp ? "Console" : "Windows"); | link->createNewChildElement ("SubSystem")->addTextElement (type == ConsoleApp ? "Console" : "Windows"); | ||||
| if (! config.is64Bit()) | if (! config.is64Bit()) | ||||
| @@ -654,7 +661,7 @@ public: | |||||
| { | { | ||||
| auto* bsc = group->createNewChildElement ("Bscmake"); | auto* bsc = group->createNewChildElement ("Bscmake"); | ||||
| bsc->createNewChildElement ("SuppressStartupBanner")->addTextElement ("true"); | bsc->createNewChildElement ("SuppressStartupBanner")->addTextElement ("true"); | ||||
| bsc->createNewChildElement ("OutputFile")->addTextElement (getOwner().getIntDirFile (config, config.getOutputFilename (".bsc", true))); | |||||
| bsc->createNewChildElement ("OutputFile")->addTextElement (getOwner().getIntDirFile (config, config.getOutputFilename (".bsc", true, type == UnityPlugIn))); | |||||
| } | } | ||||
| if (type != SharedCodeTarget) | if (type != SharedCodeTarget) | ||||
| @@ -1078,13 +1085,13 @@ public: | |||||
| RelativePath bundleScript = aaxSDK.getChildFile ("Utilities").getChildFile ("CreatePackage.bat"); | RelativePath bundleScript = aaxSDK.getChildFile ("Utilities").getChildFile ("CreatePackage.bat"); | ||||
| RelativePath iconFilePath = getAAXIconFile(); | RelativePath iconFilePath = getAAXIconFile(); | ||||
| auto outputFilename = config.getOutputFilename (".aaxplugin", true); | |||||
| auto outputFilename = config.getOutputFilename (".aaxplugin", true, false); | |||||
| auto bundleDir = getOwner().getOutDirFile (config, outputFilename); | auto bundleDir = getOwner().getOutDirFile (config, outputFilename); | ||||
| auto bundleContents = bundleDir + "\\Contents"; | auto bundleContents = bundleDir + "\\Contents"; | ||||
| auto archDir = bundleContents + String ("\\") + (config.is64Bit() ? "x64" : "Win32"); | auto archDir = bundleContents + String ("\\") + (config.is64Bit() ? "x64" : "Win32"); | ||||
| auto executable = archDir + String ("\\") + outputFilename; | auto executable = archDir + String ("\\") + outputFilename; | ||||
| auto pkgScript = String ("copy /Y ") + getOutputFilePath (config).quoted() + String (" ") + executable.quoted() + String ("\r\ncall ") | |||||
| auto pkgScript = String ("copy /Y ") + getOutputFilePath (config, false).quoted() + String (" ") + executable.quoted() + String ("\r\ncall ") | |||||
| + createRebasedPath (bundleScript) + String (" ") + archDir.quoted() + String (" ") + createRebasedPath (iconFilePath); | + createRebasedPath (bundleScript) + String (" ") + archDir.quoted() + String (" ") + createRebasedPath (iconFilePath); | ||||
| if (config.isPluginBinaryCopyStepEnabled()) | if (config.isPluginBinaryCopyStepEnabled()) | ||||
| @@ -1093,6 +1100,24 @@ public: | |||||
| return pkgScript; | return pkgScript; | ||||
| } | } | ||||
| else if (type == UnityPlugIn) | |||||
| { | |||||
| RelativePath scriptPath (config.project.getGeneratedCodeFolder().getChildFile (config.project.getUnityScriptName()), | |||||
| getOwner().getTargetFolder(), | |||||
| RelativePath::projectFolder); | |||||
| auto pkgScript = String ("copy /Y ") + scriptPath.toWindowsStyle().quoted() + " \"$(OutDir)\""; | |||||
| if (config.isPluginBinaryCopyStepEnabled()) | |||||
| { | |||||
| auto copyLocation = config.getUnityPluginBinaryLocationString(); | |||||
| pkgScript += "\r\ncopy /Y \"$(OutDir)$(TargetFileName)\" " + String (copyLocation + "\\$(TargetFileName)").quoted(); | |||||
| pkgScript += "\r\ncopy /Y " + String ("$(OutDir)" + config.project.getUnityScriptName()).quoted() + " " + String (copyLocation + "\\" + config.project.getUnityScriptName()).quoted(); | |||||
| } | |||||
| return pkgScript; | |||||
| } | |||||
| else if (config.isPluginBinaryCopyStepEnabled()) | else if (config.isPluginBinaryCopyStepEnabled()) | ||||
| { | { | ||||
| auto copyScript = String ("copy /Y \"$(OutDir)$(TargetFileName)\"") + String (" \"$COPYDIR$\\$(TargetFileName)\""); | auto copyScript = String ("copy /Y \"$(OutDir)$(TargetFileName)\"") + String (" \"$COPYDIR$\\$(TargetFileName)\""); | ||||
| @@ -1111,7 +1136,7 @@ public: | |||||
| { | { | ||||
| String script; | String script; | ||||
| auto bundleDir = getOwner().getOutDirFile (config, config.getOutputFilename (".aaxplugin", false)); | |||||
| auto bundleDir = getOwner().getOutDirFile (config, config.getOutputFilename (".aaxplugin", false, false)); | |||||
| auto bundleContents = bundleDir + "\\Contents"; | auto bundleContents = bundleDir + "\\Contents"; | ||||
| auto archDir = bundleContents + String ("\\") + (config.is64Bit() ? "x64" : "Win32"); | auto archDir = bundleContents + String ("\\") + (config.is64Bit() ? "x64" : "Win32"); | ||||
| @@ -1210,14 +1235,14 @@ public: | |||||
| return searchPaths; | return searchPaths; | ||||
| } | } | ||||
| String getBinaryNameWithSuffix (const MSVCBuildConfiguration& config) const | |||||
| String getBinaryNameWithSuffix (const MSVCBuildConfiguration& config, bool forceUnityPrefix) const | |||||
| { | { | ||||
| return config.getOutputFilename (getTargetSuffix(), true); | |||||
| return config.getOutputFilename (getTargetSuffix(), true, forceUnityPrefix); | |||||
| } | } | ||||
| String getOutputFilePath (const MSVCBuildConfiguration& config) const | |||||
| String getOutputFilePath (const MSVCBuildConfiguration& config, bool forceUnityPrefix) const | |||||
| { | { | ||||
| return getOwner().getOutDirFile (config, getBinaryNameWithSuffix (config)); | |||||
| return getOwner().getOutDirFile (config, getBinaryNameWithSuffix (config, forceUnityPrefix)); | |||||
| } | } | ||||
| StringArray getLibrarySearchPaths (const BuildConfiguration& config) const | StringArray getLibrarySearchPaths (const BuildConfiguration& config) const | ||||
| @@ -1244,7 +1269,7 @@ public: | |||||
| if (type != SharedCodeTarget) | if (type != SharedCodeTarget) | ||||
| if (auto* shared = getOwner().getSharedCodeTarget()) | if (auto* shared = getOwner().getSharedCodeTarget()) | ||||
| libraries.add (shared->getBinaryNameWithSuffix (config)); | |||||
| libraries.add (shared->getBinaryNameWithSuffix (config, false)); | |||||
| return libraries.joinIntoString (";"); | return libraries.joinIntoString (";"); | ||||
| } | } | ||||
| @@ -1325,6 +1350,7 @@ public: | |||||
| case ProjectType::Target::VST3PlugIn: | case ProjectType::Target::VST3PlugIn: | ||||
| case ProjectType::Target::AAXPlugIn: | case ProjectType::Target::AAXPlugIn: | ||||
| case ProjectType::Target::RTASPlugIn: | case ProjectType::Target::RTASPlugIn: | ||||
| case ProjectType::Target::UnityPlugIn: | |||||
| case ProjectType::Target::DynamicLibrary: | case ProjectType::Target::DynamicLibrary: | ||||
| return true; | return true; | ||||
| default: | default: | ||||
| @@ -1344,8 +1370,6 @@ public: | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| const String& getProjectName() const { return projectName; } | |||||
| bool launchProject() override | bool launchProject() override | ||||
| { | { | ||||
| #if JUCE_WINDOWS | #if JUCE_WINDOWS | ||||
| @@ -179,6 +179,7 @@ public: | |||||
| switch (type) | switch (type) | ||||
| { | { | ||||
| case VSTPlugIn: | case VSTPlugIn: | ||||
| case UnityPlugIn: | |||||
| case DynamicLibrary: return ".so"; | case DynamicLibrary: return ".so"; | ||||
| case SharedCodeTarget: | case SharedCodeTarget: | ||||
| case StaticLibrary: return ".a"; | case StaticLibrary: return ".a"; | ||||
| @@ -362,6 +363,7 @@ public: | |||||
| case ProjectType::Target::VSTPlugIn: | case ProjectType::Target::VSTPlugIn: | ||||
| case ProjectType::Target::StandalonePlugIn: | case ProjectType::Target::StandalonePlugIn: | ||||
| case ProjectType::Target::DynamicLibrary: | case ProjectType::Target::DynamicLibrary: | ||||
| case ProjectType::Target::UnityPlugIn: | |||||
| return true; | return true; | ||||
| default: | default: | ||||
| break; | break; | ||||
| @@ -179,6 +179,7 @@ public: | |||||
| case ProjectType::Target::RTASPlugIn: | case ProjectType::Target::RTASPlugIn: | ||||
| case ProjectType::Target::AudioUnitPlugIn: | case ProjectType::Target::AudioUnitPlugIn: | ||||
| case ProjectType::Target::DynamicLibrary: | case ProjectType::Target::DynamicLibrary: | ||||
| case ProjectType::Target::UnityPlugIn: | |||||
| return ! iOS; | return ! iOS; | ||||
| default: | default: | ||||
| break; | break; | ||||
| @@ -442,7 +443,8 @@ protected: | |||||
| vst3BinaryLocation (config, Ids::vst3BinaryLocation, getUndoManager(), "$(HOME)/Library/Audio/Plug-Ins/VST3/"), | vst3BinaryLocation (config, Ids::vst3BinaryLocation, getUndoManager(), "$(HOME)/Library/Audio/Plug-Ins/VST3/"), | ||||
| auBinaryLocation (config, Ids::auBinaryLocation, getUndoManager(), "$(HOME)/Library/Audio/Plug-Ins/Components/"), | auBinaryLocation (config, Ids::auBinaryLocation, getUndoManager(), "$(HOME)/Library/Audio/Plug-Ins/Components/"), | ||||
| rtasBinaryLocation (config, Ids::rtasBinaryLocation, getUndoManager(), "/Library/Application Support/Digidesign/Plug-Ins/"), | rtasBinaryLocation (config, Ids::rtasBinaryLocation, getUndoManager(), "/Library/Application Support/Digidesign/Plug-Ins/"), | ||||
| aaxBinaryLocation (config, Ids::aaxBinaryLocation, getUndoManager(), "/Library/Application Support/Avid/Audio/Plug-Ins/") | |||||
| aaxBinaryLocation (config, Ids::aaxBinaryLocation, getUndoManager(), "/Library/Application Support/Avid/Audio/Plug-Ins/"), | |||||
| unityPluginBinaryLocation (config, Ids::unityPluginBinaryLocation, getUndoManager()) | |||||
| { | { | ||||
| updateOldPluginBinaryLocations(); | updateOldPluginBinaryLocations(); | ||||
| updateOldSDKDefaults(); | updateOldSDKDefaults(); | ||||
| @@ -539,6 +541,7 @@ protected: | |||||
| String getAUBinaryLocationString() const { return auBinaryLocation.get(); } | String getAUBinaryLocationString() const { return auBinaryLocation.get(); } | ||||
| String getRTASBinaryLocationString() const { return rtasBinaryLocation.get();} | String getRTASBinaryLocationString() const { return rtasBinaryLocation.get();} | ||||
| String getAAXBinaryLocationString() const { return aaxBinaryLocation.get();} | String getAAXBinaryLocationString() const { return aaxBinaryLocation.get();} | ||||
| String getUnityPluginBinaryLocationString() const { return unityPluginBinaryLocation.get(); } | |||||
| private: | private: | ||||
| //========================================================================== | //========================================================================== | ||||
| @@ -547,7 +550,8 @@ protected: | |||||
| ValueWithDefault osxSDKVersion, osxDeploymentTarget, iosDeploymentTarget, osxArchitecture, | ValueWithDefault osxSDKVersion, osxDeploymentTarget, iosDeploymentTarget, osxArchitecture, | ||||
| customXcodeFlags, plistPreprocessorDefinitions, codeSignIdentity, | customXcodeFlags, plistPreprocessorDefinitions, codeSignIdentity, | ||||
| fastMathEnabled, stripLocalSymbolsEnabled, pluginBinaryCopyStepEnabled, | fastMathEnabled, stripLocalSymbolsEnabled, pluginBinaryCopyStepEnabled, | ||||
| vstBinaryLocation, vst3BinaryLocation, auBinaryLocation, rtasBinaryLocation, aaxBinaryLocation; | |||||
| vstBinaryLocation, vst3BinaryLocation, auBinaryLocation, rtasBinaryLocation, | |||||
| aaxBinaryLocation, unityPluginBinaryLocation; | |||||
| //========================================================================== | //========================================================================== | ||||
| void addXcodePluginInstallPathProperties (PropertyListBuilder& props) | void addXcodePluginInstallPathProperties (PropertyListBuilder& props) | ||||
| @@ -583,6 +587,11 @@ protected: | |||||
| props.add (new TextPropertyComponentWithEnablement (aaxBinaryLocation, pluginBinaryCopyStepEnabled, "AAX Binary Location", | props.add (new TextPropertyComponentWithEnablement (aaxBinaryLocation, pluginBinaryCopyStepEnabled, "AAX Binary Location", | ||||
| 1024, false), | 1024, false), | ||||
| "The folder in which the compiled AAX binary should be placed."); | "The folder in which the compiled AAX binary should be placed."); | ||||
| if (project.shouldBuildUnityPlugin()) | |||||
| props.add (new TextPropertyComponentWithEnablement (unityPluginBinaryLocation, pluginBinaryCopyStepEnabled, "Unity Binary Location", | |||||
| 1024, false), | |||||
| "The folder in which the compiled Unity plugin binary and associated C# GUI script should be placed."); | |||||
| } | } | ||||
| void updateOldPluginBinaryLocations() | void updateOldPluginBinaryLocations() | ||||
| @@ -734,6 +743,15 @@ public: | |||||
| xcodeCopyToProductInstallPathAfterBuild = true; | xcodeCopyToProductInstallPathAfterBuild = true; | ||||
| break; | break; | ||||
| case UnityPlugIn: | |||||
| xcodePackageType = "BNDL"; | |||||
| xcodeBundleSignature = "????"; | |||||
| xcodeFileType = "wrapper.cfbundle"; | |||||
| xcodeBundleExtension = ".bundle"; | |||||
| xcodeProductType = "com.apple.product-type.bundle"; | |||||
| xcodeCopyToProductInstallPathAfterBuild = true; | |||||
| break; | |||||
| case SharedCodeTarget: | case SharedCodeTarget: | ||||
| xcodeFileType = "archive.ar"; | xcodeFileType = "archive.ar"; | ||||
| xcodeBundleExtension = ".a"; | xcodeBundleExtension = ".a"; | ||||
| @@ -822,7 +840,7 @@ public: | |||||
| if (ProjectExporter::BuildConfiguration::Ptr config = owner.getConfiguration(0)) | if (ProjectExporter::BuildConfiguration::Ptr config = owner.getConfiguration(0)) | ||||
| { | { | ||||
| auto productName = owner.replacePreprocessorTokens (*config, config->getTargetBinaryNameString()); | |||||
| auto productName = owner.replacePreprocessorTokens (*config, config->getTargetBinaryNameString (type == UnityPlugIn)); | |||||
| if (xcodeFileType == "archive.ar") | if (xcodeFileType == "archive.ar") | ||||
| productName = getStaticLibbedFilename (productName); | productName = getStaticLibbedFilename (productName); | ||||
| @@ -995,6 +1013,7 @@ public: | |||||
| return s; | return s; | ||||
| } | } | ||||
| s.set ("PRODUCT_NAME", owner.replacePreprocessorTokens (config, config.getTargetBinaryNameString (type == UnityPlugIn)).quoted()); | |||||
| s.set ("PRODUCT_BUNDLE_IDENTIFIER", getBundleIdentifier()); | s.set ("PRODUCT_BUNDLE_IDENTIFIER", getBundleIdentifier()); | ||||
| auto arch = (! owner.isiOS() && type == Target::AudioUnitv3PlugIn) ? osxArch_64Bit | auto arch = (! owner.isiOS() && type == Target::AudioUnitv3PlugIn) ? osxArch_64Bit | ||||
| @@ -1231,6 +1250,7 @@ public: | |||||
| case AudioUnitPlugIn: return config.isPluginBinaryCopyStepEnabled() ? config.getAUBinaryLocationString() : String(); | case AudioUnitPlugIn: return config.isPluginBinaryCopyStepEnabled() ? config.getAUBinaryLocationString() : String(); | ||||
| case RTASPlugIn: return config.isPluginBinaryCopyStepEnabled() ? config.getRTASBinaryLocationString() : String(); | case RTASPlugIn: return config.isPluginBinaryCopyStepEnabled() ? config.getRTASBinaryLocationString() : String(); | ||||
| case AAXPlugIn: return config.isPluginBinaryCopyStepEnabled() ? config.getAAXBinaryLocationString() : String(); | case AAXPlugIn: return config.isPluginBinaryCopyStepEnabled() ? config.getAAXBinaryLocationString() : String(); | ||||
| case UnityPlugIn: return config.isPluginBinaryCopyStepEnabled() ? config.getUnityPluginBinaryLocationString() : String(); | |||||
| case SharedCodeTarget: return owner.isiOS() ? "@executable_path/Frameworks" : "@executable_path/../Frameworks"; | case SharedCodeTarget: return owner.isiOS() ? "@executable_path/Frameworks" : "@executable_path/../Frameworks"; | ||||
| default: return {}; | default: return {}; | ||||
| } | } | ||||
| @@ -1927,6 +1947,10 @@ private: | |||||
| && project.shouldBuildStandalonePlugin() && target->type == XcodeTarget::StandalonePlugIn) | && project.shouldBuildStandalonePlugin() && target->type == XcodeTarget::StandalonePlugIn) | ||||
| embedAppExtension(); | embedAppExtension(); | ||||
| if (project.getProjectType().isAudioPlugin() && project.shouldBuildUnityPlugin() | |||||
| && target->type == XcodeTarget::UnityPlugIn) | |||||
| embedUnityScript(); | |||||
| addTargetObject (*target); | addTargetObject (*target); | ||||
| } | } | ||||
| } | } | ||||
| @@ -1944,6 +1968,25 @@ private: | |||||
| } | } | ||||
| } | } | ||||
| void embedUnityScript() const | |||||
| { | |||||
| if (auto* unityTarget = getTargetOfType (XcodeTarget::UnityPlugIn)) | |||||
| { | |||||
| RelativePath scriptPath (getProject().getGeneratedCodeFolder().getChildFile (getProject().getUnityScriptName()), | |||||
| getTargetFolder(), | |||||
| RelativePath::buildTargetFolder); | |||||
| auto path = scriptPath.toUnixStyle(); | |||||
| auto refID = addFileReference (path); | |||||
| auto fileID = addBuildFile (path, refID, false, false); | |||||
| resourceIDs.add (fileID); | |||||
| resourceFileRefs.add (refID); | |||||
| unityTarget->addCopyFilesPhase ("Embed Unity Script", fileID, kWrapperFolder); | |||||
| } | |||||
| } | |||||
| static Image fixMacIconImageSize (Drawable& image) | static Image fixMacIconImageSize (Drawable& image) | ||||
| { | { | ||||
| const int validSizes[] = { 16, 32, 48, 128, 256, 512, 1024 }; | const int validSizes[] = { 16, 32, 48, 128, 256, 512, 1024 }; | ||||
| @@ -1992,6 +2035,7 @@ private: | |||||
| v->setProperty ("dependencies", indentParenthesisedList (getTargetDependencies (target)), nullptr); | v->setProperty ("dependencies", indentParenthesisedList (getTargetDependencies (target)), nullptr); | ||||
| v->setProperty (Ids::name, target.getXcodeSchemeName(), nullptr); | v->setProperty (Ids::name, target.getXcodeSchemeName(), nullptr); | ||||
| v->setProperty ("productName", projectName, nullptr); | v->setProperty ("productName", projectName, nullptr); | ||||
| if (target.type != XcodeTarget::AggregateTarget) | if (target.type != XcodeTarget::AggregateTarget) | ||||
| @@ -450,7 +450,8 @@ void ProjectExporter::addTargetSpecificPreprocessorDefs (StringPairArray& defs, | |||||
| {"JucePlugin_Build_AUv3", ProjectType::Target::AudioUnitv3PlugIn}, | {"JucePlugin_Build_AUv3", ProjectType::Target::AudioUnitv3PlugIn}, | ||||
| {"JucePlugin_Build_RTAS", ProjectType::Target::RTASPlugIn}, | {"JucePlugin_Build_RTAS", ProjectType::Target::RTASPlugIn}, | ||||
| {"JucePlugin_Build_AAX", ProjectType::Target::AAXPlugIn}, | {"JucePlugin_Build_AAX", ProjectType::Target::AAXPlugIn}, | ||||
| {"JucePlugin_Build_Standalone", ProjectType::Target::StandalonePlugIn} | |||||
| {"JucePlugin_Build_Standalone", ProjectType::Target::StandalonePlugIn}, | |||||
| {"JucePlugin_Build_Unity", ProjectType::Target::UnityPlugIn} | |||||
| }; | }; | ||||
| if (targetType == ProjectType::Target::SharedCodeTarget) | if (targetType == ProjectType::Target::SharedCodeTarget) | ||||
| @@ -244,8 +244,12 @@ public: | |||||
| String getName() const { return configNameValue.get(); } | String getName() const { return configNameValue.get(); } | ||||
| bool isDebug() const { return isDebugValue.get(); } | bool isDebug() const { return isDebugValue.get(); } | ||||
| String getTargetBinaryNameString() const { return targetNameValue.get(); } | |||||
| String getTargetBinaryRelativePathString() const { return targetBinaryPathValue.get(); } | String getTargetBinaryRelativePathString() const { return targetBinaryPathValue.get(); } | ||||
| String getTargetBinaryNameString (bool isUnityPlugin = false) const | |||||
| { | |||||
| return (isUnityPlugin ? Project::addUnityPluginPrefixIfNecessary (targetNameValue.get().toString()) | |||||
| : targetNameValue.get().toString()); | |||||
| } | |||||
| int getOptimisationLevelInt() const { return optimisationLevelValue.get(); } | int getOptimisationLevelInt() const { return optimisationLevelValue.get(); } | ||||
| String getGCCOptimisationFlag() const; | String getGCCOptimisationFlag() const; | ||||
| @@ -83,6 +83,7 @@ void ProjectSaver::writePluginCharacteristicsFile() | |||||
| flags.set ("JucePlugin_Build_RTAS", boolToString (project.shouldBuildRTAS())); | flags.set ("JucePlugin_Build_RTAS", boolToString (project.shouldBuildRTAS())); | ||||
| flags.set ("JucePlugin_Build_AAX", boolToString (project.shouldBuildAAX())); | flags.set ("JucePlugin_Build_AAX", boolToString (project.shouldBuildAAX())); | ||||
| flags.set ("JucePlugin_Build_Standalone", boolToString (project.shouldBuildStandalonePlugin())); | flags.set ("JucePlugin_Build_Standalone", boolToString (project.shouldBuildStandalonePlugin())); | ||||
| flags.set ("JucePlugin_Build_Unity", boolToString (project.shouldBuildUnityPlugin())); | |||||
| flags.set ("JucePlugin_Enable_IAA", boolToString (project.shouldEnableIAA())); | flags.set ("JucePlugin_Enable_IAA", boolToString (project.shouldEnableIAA())); | ||||
| flags.set ("JucePlugin_Name", toStringLiteral (project.getPluginNameString())); | flags.set ("JucePlugin_Name", toStringLiteral (project.getPluginNameString())); | ||||
| flags.set ("JucePlugin_Desc", toStringLiteral (project.getPluginDescriptionString())); | flags.set ("JucePlugin_Desc", toStringLiteral (project.getPluginDescriptionString())); | ||||
| @@ -94,8 +94,13 @@ public: | |||||
| auto projectRootHash = project.getProjectRoot().toXmlString().hashCode(); | auto projectRootHash = project.getProjectRoot().toXmlString().hashCode(); | ||||
| if (project.getProjectType().isAudioPlugin()) | if (project.getProjectType().isAudioPlugin()) | ||||
| { | |||||
| writePluginCharacteristicsFile(); | writePluginCharacteristicsFile(); | ||||
| if (project.shouldBuildUnityPlugin()) | |||||
| writeUnityScriptFile(); | |||||
| } | |||||
| writeAppConfigFile (modules, appConfigUserContent); | writeAppConfigFile (modules, appConfigUserContent); | ||||
| writeBinaryDataFiles(); | writeBinaryDataFiles(); | ||||
| writeAppHeader (modules); | writeAppHeader (modules); | ||||
| @@ -669,6 +674,24 @@ private: | |||||
| void writePluginCharacteristicsFile(); | void writePluginCharacteristicsFile(); | ||||
| void writeUnityScriptFile() | |||||
| { | |||||
| String unityScriptContents (BinaryData::jucer_UnityPluginGUIScript_cs); | |||||
| auto projectName = Project::addUnityPluginPrefixIfNecessary (project.getProjectNameString()); | |||||
| unityScriptContents = unityScriptContents.replace ("%%plugin_name%%", projectName) | |||||
| .replace ("%%plugin_vendor%%", project.getPluginManufacturerString()) | |||||
| .replace ("%%plugin_description%%", project.getPluginDescriptionString()); | |||||
| auto f = getGeneratedCodeFolder().getChildFile (project.getUnityScriptName()); | |||||
| MemoryOutputStream out; | |||||
| out << unityScriptContents; | |||||
| replaceFileIfDifferent (f, out); | |||||
| } | |||||
| void writeProjects (const OwnedArray<LibraryModule>&, const String&, bool); | void writeProjects (const OwnedArray<LibraryModule>&, const String&, bool); | ||||
| void saveExporter (ProjectExporter* exporter, const OwnedArray<LibraryModule>& modules) | void saveExporter (ProjectExporter* exporter, const OwnedArray<LibraryModule>& modules) | ||||
| @@ -118,6 +118,7 @@ namespace Ids | |||||
| DECLARE_ID (auBinaryLocation); | DECLARE_ID (auBinaryLocation); | ||||
| DECLARE_ID (rtasBinaryLocation); | DECLARE_ID (rtasBinaryLocation); | ||||
| DECLARE_ID (aaxBinaryLocation); | DECLARE_ID (aaxBinaryLocation); | ||||
| DECLARE_ID (unityPluginBinaryLocation); | |||||
| DECLARE_ID (enablePluginBinaryCopyStep); | DECLARE_ID (enablePluginBinaryCopyStep); | ||||
| DECLARE_ID (stripLocalSymbols); | DECLARE_ID (stripLocalSymbols); | ||||
| DECLARE_ID (osxSDK); | DECLARE_ID (osxSDK); | ||||
| @@ -298,6 +299,7 @@ namespace Ids | |||||
| DECLARE_ID (buildRTAS); | DECLARE_ID (buildRTAS); | ||||
| DECLARE_ID (buildAAX); | DECLARE_ID (buildAAX); | ||||
| DECLARE_ID (buildStandalone); | DECLARE_ID (buildStandalone); | ||||
| DECLARE_ID (buildUnity); | |||||
| DECLARE_ID (enableIAA); | DECLARE_ID (enableIAA); | ||||
| DECLARE_ID (pluginName); | DECLARE_ID (pluginName); | ||||
| DECLARE_ID (pluginDesc); | DECLARE_ID (pluginDesc); | ||||
| @@ -0,0 +1,191 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCE library. | |||||
| Copyright (c) 2017 - ROLI Ltd. | |||||
| JUCE is an open source library subject to commercial or open-source | |||||
| licensing. | |||||
| By using JUCE, you agree to the terms of both the JUCE 5 End-User License | |||||
| Agreement and JUCE 5 Privacy Policy (both updated and effective as of the | |||||
| 27th April 2017). | |||||
| End User License Agreement: www.juce.com/juce-5-licence | |||||
| Privacy Policy: www.juce.com/juce-5-privacy-policy | |||||
| Or: You may also use this code under the terms of the GPL v3 (see | |||||
| www.gnu.org/licenses). | |||||
| JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER | |||||
| EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE | |||||
| DISCLAIMED. | |||||
| ============================================================================== | |||||
| */ | |||||
| #pragma once | |||||
| //============================================================================== | |||||
| #define UNITY_AUDIO_PLUGIN_API_VERSION 0x010401 | |||||
| #if JUCE_WINDOWS | |||||
| #define UNITY_INTERFACE_API __stdcall | |||||
| #define UNITY_INTERFACE_EXPORT __declspec(dllexport) | |||||
| #else | |||||
| #define UNITY_INTERFACE_API | |||||
| #define UNITY_INTERFACE_EXPORT __attribute__ ((visibility("default"))) | |||||
| #endif | |||||
| //============================================================================== | |||||
| struct UnityAudioEffectState; | |||||
| typedef int (UNITY_INTERFACE_API * createCallback) (UnityAudioEffectState* state); | |||||
| typedef int (UNITY_INTERFACE_API * releaseCallback) (UnityAudioEffectState* state); | |||||
| typedef int (UNITY_INTERFACE_API * resetCallback) (UnityAudioEffectState* state); | |||||
| typedef int (UNITY_INTERFACE_API * processCallback) (UnityAudioEffectState* state, float* inBuffer, float* outBuffer, unsigned int bufferSize, | |||||
| int numInChannels, int numOutChannels); | |||||
| typedef int (UNITY_INTERFACE_API * setPositionCallback) (UnityAudioEffectState* state, unsigned int pos); | |||||
| typedef int (UNITY_INTERFACE_API * setFloatParameterCallback) (UnityAudioEffectState* state, int index, float value); | |||||
| typedef int (UNITY_INTERFACE_API * getFloatParameterCallback) (UnityAudioEffectState* state, int index, float* value, char* valuestr); | |||||
| typedef int (UNITY_INTERFACE_API * getFloatBufferCallback) (UnityAudioEffectState* state, const char* name, float* buffer, int numsamples); | |||||
| typedef int (UNITY_INTERFACE_API * distanceAttenuationCallback) (UnityAudioEffectState* state, float distanceIn, float attenuationIn, float* attenuationOut); | |||||
| typedef void (UNITY_INTERFACE_API * renderCallback) (int eventId); | |||||
| //============================================================================== | |||||
| enum UnityAudioEffectDefinitionFlags | |||||
| { | |||||
| isSideChainTarget = 1, | |||||
| isSpatializer = 2, | |||||
| isAmbisonicDecoder = 4, | |||||
| appliesDistanceAttenuation = 8 | |||||
| }; | |||||
| enum UnityAudioEffectStateFlags | |||||
| { | |||||
| stateIsPlaying = 1, | |||||
| stateIsPaused = 2, | |||||
| stateIsMuted = 8, | |||||
| statIsSideChainTarget = 16 | |||||
| }; | |||||
| enum UnityEventModifiers | |||||
| { | |||||
| shift = 1, | |||||
| control = 2, | |||||
| alt = 4, | |||||
| command = 8, | |||||
| numeric = 16, | |||||
| capsLock = 32, | |||||
| functionKey = 64 | |||||
| }; | |||||
| //============================================================================== | |||||
| struct UnityAudioSpatializerData | |||||
| { | |||||
| float listenerMatrix[16]; | |||||
| float sourceMatrix[16]; | |||||
| float spatialBlend; | |||||
| float reverbZoneMix; | |||||
| float spread; | |||||
| float stereoPan; | |||||
| distanceAttenuationCallback distanceAttenuationCallback; | |||||
| float minDistance; | |||||
| float maxDistance; | |||||
| }; | |||||
| struct UnityAudioAmbisonicData | |||||
| { | |||||
| float listenerMatrix[16]; | |||||
| float sourceMatrix[16]; | |||||
| float spatialBlend; | |||||
| float reverbZoneMix; | |||||
| float spread; | |||||
| float stereoPan; | |||||
| distanceAttenuationCallback distanceAttenuationCallback; | |||||
| int ambisonicOutChannels; | |||||
| float volume; | |||||
| }; | |||||
| struct UnityAudioEffectState | |||||
| { | |||||
| juce::uint32 structSize; | |||||
| juce::uint32 sampleRate; | |||||
| juce::uint64 dspCurrentTick; | |||||
| juce::uint64 dspPreviousTick; | |||||
| float* sidechainBuffer; | |||||
| void* effectData; | |||||
| juce::uint32 flags; | |||||
| void* internal; | |||||
| UnityAudioSpatializerData* spatializerData; | |||||
| juce::uint32 dspBufferSize; | |||||
| juce::uint32 hostAPIVersion; | |||||
| UnityAudioAmbisonicData* ambisonicData; | |||||
| template<typename T> | |||||
| inline T* getEffectData() const | |||||
| { | |||||
| jassert (effectData != nullptr); | |||||
| jassert (internal != nullptr); | |||||
| return (T*) effectData; | |||||
| } | |||||
| }; | |||||
| struct UnityAudioParameterDefinition | |||||
| { | |||||
| char name[16]; | |||||
| char unit[16]; | |||||
| const char* description; | |||||
| float min; | |||||
| float max; | |||||
| float defaultVal; | |||||
| float displayScale; | |||||
| float displayExponent; | |||||
| }; | |||||
| struct UnityAudioEffectDefinition | |||||
| { | |||||
| juce::uint32 structSize; | |||||
| juce::uint32 parameterStructSize; | |||||
| juce::uint32 apiVersion; | |||||
| juce::uint32 pluginVersion; | |||||
| juce::uint32 channels; | |||||
| juce::uint32 numParameters; | |||||
| juce::uint64 flags; | |||||
| char name[32]; | |||||
| createCallback create; | |||||
| releaseCallback release; | |||||
| resetCallback reset; | |||||
| processCallback process; | |||||
| setPositionCallback setPosition; | |||||
| UnityAudioParameterDefinition* parameterDefintions; | |||||
| setFloatParameterCallback setFloatParameter; | |||||
| getFloatParameterCallback getFloatParameter; | |||||
| getFloatBufferCallback getFloatBuffer; | |||||
| }; | |||||
| //============================================================================== | |||||
| // Unity callback | |||||
| extern "C" UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API UnityGetAudioEffectDefinitions (UnityAudioEffectDefinition*** definitionsPtr); | |||||
| // GUI script callbacks | |||||
| extern "C" UNITY_INTERFACE_EXPORT renderCallback UNITY_INTERFACE_API getRenderCallback(); | |||||
| extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityInitialiseTexture (int id, void* textureHandle, int w, int h); | |||||
| extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityMouseDown (int id, float x, float y, UnityEventModifiers mods, int button); | |||||
| extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityMouseDrag (int id, float x, float y, UnityEventModifiers mods, int button); | |||||
| extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityMouseUp (int id, float x, float y, UnityEventModifiers mods); | |||||
| extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityKeyEvent (int id, int code, UnityEventModifiers mods, const char* name); | |||||
| extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unitySetScreenBounds (int id, float x, float y, float w, float h); | |||||
| @@ -0,0 +1,779 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCE library. | |||||
| Copyright (c) 2017 - ROLI Ltd. | |||||
| JUCE is an open source library subject to commercial or open-source | |||||
| licensing. | |||||
| By using JUCE, you agree to the terms of both the JUCE 5 End-User License | |||||
| Agreement and JUCE 5 Privacy Policy (both updated and effective as of the | |||||
| 27th April 2017). | |||||
| End User License Agreement: www.juce.com/juce-5-licence | |||||
| Privacy Policy: www.juce.com/juce-5-privacy-policy | |||||
| Or: You may also use this code under the terms of the GPL v3 (see | |||||
| www.gnu.org/licenses). | |||||
| JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER | |||||
| EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE | |||||
| DISCLAIMED. | |||||
| ============================================================================== | |||||
| */ | |||||
| #if JucePlugin_Build_Unity | |||||
| #include "../../juce_core/system/juce_TargetPlatform.h" | |||||
| #include "../utility/juce_IncludeModuleHeaders.h" | |||||
| #include "../../juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp" | |||||
| #if JUCE_WINDOWS | |||||
| #include "../utility/juce_IncludeSystemHeaders.h" | |||||
| #endif | |||||
| #include "juce_UnityPluginInterface.h" | |||||
| //============================================================================== | |||||
| namespace juce | |||||
| { | |||||
| typedef ComponentPeer* (*createUnityPeerFunctionType) (Component&); | |||||
| extern createUnityPeerFunctionType juce_createUnityPeerFn; | |||||
| //============================================================================== | |||||
| class UnityPeer : public ComponentPeer, | |||||
| public AsyncUpdater | |||||
| { | |||||
| public: | |||||
| UnityPeer (Component& ed) | |||||
| : ComponentPeer (ed, 0), | |||||
| mouseWatcher (*this) | |||||
| { | |||||
| getEditor().setResizable (false, false); | |||||
| } | |||||
| //============================================================================== | |||||
| Rectangle<int> getBounds() const override { return bounds; } | |||||
| Point<float> localToGlobal (Point<float> relativePosition) override { return relativePosition + getBounds().getPosition().toFloat(); } | |||||
| Point<float> globalToLocal (Point<float> screenPosition) override { return screenPosition - getBounds().getPosition().toFloat(); } | |||||
| StringArray getAvailableRenderingEngines() override { return StringArray ("Software Renderer"); } | |||||
| void setBounds (const Rectangle<int>& newBounds, bool) override | |||||
| { | |||||
| bounds = newBounds; | |||||
| mouseWatcher.setBoundsToWatch (bounds); | |||||
| } | |||||
| bool contains (Point<int> localPos, bool) const override | |||||
| { | |||||
| if (isPositiveAndBelow (localPos.getX(), getBounds().getWidth()) | |||||
| && isPositiveAndBelow (localPos.getY(), getBounds().getHeight())) | |||||
| return true; | |||||
| return false; | |||||
| } | |||||
| void handleAsyncUpdate() override | |||||
| { | |||||
| fillPixels(); | |||||
| } | |||||
| //============================================================================== | |||||
| AudioProcessorEditor& getEditor() { return *dynamic_cast<AudioProcessorEditor*> (&getComponent()); } | |||||
| void setPixelDataHandle (uint8* handle, int width, int height) | |||||
| { | |||||
| pixelData = handle; | |||||
| textureWidth = width; | |||||
| textureHeight = height; | |||||
| renderImage = Image (new UnityBitmapImage (pixelData, width, height)); | |||||
| } | |||||
| // N.B. This is NOT an efficient way to do this and you shouldn't use this method in your own code. | |||||
| // It works for our purposes here but a much more efficient way would be to use a GL texture. | |||||
| void fillPixels() | |||||
| { | |||||
| if (pixelData == nullptr) | |||||
| return; | |||||
| LowLevelGraphicsSoftwareRenderer renderer (renderImage); | |||||
| renderer.addTransform (AffineTransform::verticalFlip ((float) getComponent().getHeight())); | |||||
| handlePaint (renderer); | |||||
| for (int i = 0; i < textureWidth * textureHeight * 4; i += 4) | |||||
| { | |||||
| auto r = pixelData[i + 2]; | |||||
| auto g = pixelData[i + 1]; | |||||
| auto b = pixelData[i + 0]; | |||||
| pixelData[i + 0] = r; | |||||
| pixelData[i + 1] = g; | |||||
| pixelData[i + 2] = b; | |||||
| } | |||||
| } | |||||
| void forwardMouseEvent (Point<float> position, ModifierKeys mods) | |||||
| { | |||||
| ModifierKeys::currentModifiers = mods; | |||||
| handleMouseEvent (juce::MouseInputSource::mouse, position, mods, juce::MouseInputSource::invalidPressure, | |||||
| juce::MouseInputSource::invalidOrientation, juce::Time::currentTimeMillis()); | |||||
| } | |||||
| void forwardKeyPress (int code, String name, ModifierKeys mods) | |||||
| { | |||||
| ModifierKeys::currentModifiers = mods; | |||||
| handleKeyPress (getKeyPress (code, name)); | |||||
| } | |||||
| private: | |||||
| //============================================================================== | |||||
| struct UnityBitmapImage : public ImagePixelData | |||||
| { | |||||
| UnityBitmapImage (uint8* data, int w, int h) | |||||
| : ImagePixelData (Image::PixelFormat::ARGB, w, h), | |||||
| imageData (data), | |||||
| lineStride (width * pixelStride) | |||||
| { | |||||
| } | |||||
| ImageType* createType() const override { return new SoftwareImageType(); } | |||||
| LowLevelGraphicsContext* createLowLevelContext() override { return new LowLevelGraphicsSoftwareRenderer (Image (this)); } | |||||
| void initialiseBitmapData (Image::BitmapData& bitmap, int x, int y, Image::BitmapData::ReadWriteMode mode) override | |||||
| { | |||||
| ignoreUnused (mode); | |||||
| bitmap.data = imageData + x * pixelStride + y * lineStride; | |||||
| bitmap.pixelFormat = pixelFormat; | |||||
| bitmap.lineStride = lineStride; | |||||
| bitmap.pixelStride = pixelStride; | |||||
| } | |||||
| ImagePixelData::Ptr clone() override | |||||
| { | |||||
| auto im = new UnityBitmapImage (imageData, width, height); | |||||
| for (int i = 0; i < height; ++i) | |||||
| memcpy (im->imageData + i * lineStride, imageData + i * lineStride, (size_t) lineStride); | |||||
| return im; | |||||
| } | |||||
| uint8* imageData; | |||||
| int pixelStride = 4, lineStride; | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UnityBitmapImage) | |||||
| }; | |||||
| //============================================================================== | |||||
| struct MouseWatcher : public Timer | |||||
| { | |||||
| MouseWatcher (ComponentPeer& o) : owner (o) {} | |||||
| void timerCallback() override | |||||
| { | |||||
| auto pos = Desktop::getMousePosition(); | |||||
| if (boundsToWatch.contains (pos) && pos != lastMousePos) | |||||
| { | |||||
| auto ms = Desktop::getInstance().getMainMouseSource(); | |||||
| if (! ms.getCurrentModifiers().isLeftButtonDown()) | |||||
| owner.handleMouseEvent (juce::MouseInputSource::mouse, owner.globalToLocal (pos.toFloat()), {}, | |||||
| juce::MouseInputSource::invalidPressure, juce::MouseInputSource::invalidOrientation, juce::Time::currentTimeMillis()); | |||||
| lastMousePos = pos; | |||||
| } | |||||
| } | |||||
| void setBoundsToWatch (Rectangle<int> b) | |||||
| { | |||||
| if (boundsToWatch != b) | |||||
| boundsToWatch = b; | |||||
| startTimer (250); | |||||
| } | |||||
| ComponentPeer& owner; | |||||
| Rectangle<int> boundsToWatch; | |||||
| Point<int> lastMousePos; | |||||
| }; | |||||
| //============================================================================== | |||||
| KeyPress getKeyPress (int keyCode, String name) | |||||
| { | |||||
| if (keyCode >= 32 && keyCode <= 64) | |||||
| return { keyCode, ModifierKeys::currentModifiers, juce::juce_wchar (keyCode) }; | |||||
| if (keyCode >= 91 && keyCode <= 122) | |||||
| return { keyCode, ModifierKeys::currentModifiers, name[0] }; | |||||
| if (keyCode >= 256 && keyCode <= 265) | |||||
| return { juce::KeyPress::numberPad0 + (keyCode - 256), ModifierKeys::currentModifiers, juce::String (keyCode - 256).getCharPointer()[0] }; | |||||
| if (keyCode == 8) return { juce::KeyPress::backspaceKey, ModifierKeys::currentModifiers, {} }; | |||||
| if (keyCode == 127) return { juce::KeyPress::deleteKey, ModifierKeys::currentModifiers, {} }; | |||||
| if (keyCode == 9) return { juce::KeyPress::tabKey, ModifierKeys::currentModifiers, {} }; | |||||
| if (keyCode == 13) return { juce::KeyPress::returnKey, ModifierKeys::currentModifiers, {} }; | |||||
| if (keyCode == 27) return { juce::KeyPress::escapeKey, ModifierKeys::currentModifiers, {} }; | |||||
| if (keyCode == 32) return { juce::KeyPress::spaceKey, ModifierKeys::currentModifiers, {} }; | |||||
| if (keyCode == 266) return { juce::KeyPress::numberPadDecimalPoint, ModifierKeys::currentModifiers, {} }; | |||||
| if (keyCode == 267) return { juce::KeyPress::numberPadDivide, ModifierKeys::currentModifiers, {} }; | |||||
| if (keyCode == 268) return { juce::KeyPress::numberPadMultiply, ModifierKeys::currentModifiers, {} }; | |||||
| if (keyCode == 269) return { juce::KeyPress::numberPadSubtract, ModifierKeys::currentModifiers, {} }; | |||||
| if (keyCode == 270) return { juce::KeyPress::numberPadAdd, ModifierKeys::currentModifiers, {} }; | |||||
| if (keyCode == 272) return { juce::KeyPress::numberPadEquals, ModifierKeys::currentModifiers, {} }; | |||||
| if (keyCode == 273) return { juce::KeyPress::upKey, ModifierKeys::currentModifiers, {} }; | |||||
| if (keyCode == 274) return { juce::KeyPress::downKey, ModifierKeys::currentModifiers, {} }; | |||||
| if (keyCode == 275) return { juce::KeyPress::rightKey, ModifierKeys::currentModifiers, {} }; | |||||
| if (keyCode == 276) return { juce::KeyPress::leftKey, ModifierKeys::currentModifiers, {} }; | |||||
| return {}; | |||||
| } | |||||
| //============================================================================== | |||||
| Rectangle<int> bounds; | |||||
| MouseWatcher mouseWatcher; | |||||
| uint8* pixelData = nullptr; | |||||
| int textureWidth, textureHeight; | |||||
| Image renderImage; | |||||
| //============================================================================== | |||||
| void setMinimised (bool) override {} | |||||
| bool isMinimised() const override { return false; } | |||||
| void setFullScreen (bool) override {} | |||||
| bool isFullScreen() const override { return false; } | |||||
| bool setAlwaysOnTop (bool) override { return false; } | |||||
| void toFront (bool) override {} | |||||
| void toBehind (ComponentPeer*) override {} | |||||
| bool isFocused() const override { return true; } | |||||
| void grabFocus() override {} | |||||
| void* getNativeHandle() const override { return nullptr; } | |||||
| BorderSize<int> getFrameSize() const override { return {}; } | |||||
| void setVisible (bool) override {} | |||||
| void setTitle (const String&) override {} | |||||
| void setIcon (const Image&) override {} | |||||
| void textInputRequired (Point<int>, TextInputTarget&) override {} | |||||
| void setAlpha (float) override {} | |||||
| void performAnyPendingRepaintsNow() override {} | |||||
| void repaint (const Rectangle<int>&) override {} | |||||
| //============================================================================== | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UnityPeer) | |||||
| }; | |||||
| ComponentPeer* createUnityPeer (Component& c) { return new UnityPeer (c); } | |||||
| //============================================================================== | |||||
| class AudioProcessorUnityWrapper | |||||
| { | |||||
| public: | |||||
| AudioProcessorUnityWrapper (bool isTemporary) | |||||
| { | |||||
| pluginInstance.reset (createPluginFilterOfType (AudioProcessor::wrapperType_Unity)); | |||||
| if (! isTemporary && pluginInstance->hasEditor()) | |||||
| { | |||||
| pluginInstanceEditor.reset (pluginInstance->createEditorIfNeeded()); | |||||
| pluginInstanceEditor->setVisible (true); | |||||
| pluginInstanceEditor->addToDesktop (0); | |||||
| } | |||||
| juceParameters.update (*pluginInstance, false); | |||||
| } | |||||
| ~AudioProcessorUnityWrapper() | |||||
| { | |||||
| if (pluginInstanceEditor != nullptr) | |||||
| { | |||||
| pluginInstanceEditor->removeFromDesktop(); | |||||
| PopupMenu::dismissAllActiveMenus(); | |||||
| pluginInstanceEditor->processor.editorBeingDeleted (pluginInstanceEditor.get()); | |||||
| pluginInstanceEditor = nullptr; | |||||
| } | |||||
| } | |||||
| void create (UnityAudioEffectState* state) | |||||
| { | |||||
| // only supported in Unity plugin API > 1.0 | |||||
| if (state->structSize >= sizeof (UnityAudioEffectState)) | |||||
| samplesPerBlock = state->dspBufferSize; | |||||
| pluginInstance->setRateAndBufferSizeDetails (state->sampleRate, samplesPerBlock); | |||||
| pluginInstance->prepareToPlay (state->sampleRate, samplesPerBlock); | |||||
| scratchBuffer.setSize (jmax (pluginInstance->getTotalNumInputChannels(), pluginInstance->getTotalNumOutputChannels()), samplesPerBlock); | |||||
| } | |||||
| void release() | |||||
| { | |||||
| pluginInstance->releaseResources(); | |||||
| } | |||||
| void reset() | |||||
| { | |||||
| pluginInstance->reset(); | |||||
| } | |||||
| void process (float* inBuffer, float* outBuffer, unsigned int bufferSize, int numInChannels, int numOutChannels, bool isBypassed) | |||||
| { | |||||
| for (int pos = 0; pos < static_cast<int> (bufferSize);) | |||||
| { | |||||
| auto max = jmin (static_cast<int> (bufferSize) - pos, samplesPerBlock); | |||||
| processBuffers (inBuffer + (pos * numInChannels), outBuffer + (pos * numOutChannels), max, numInChannels, numOutChannels, isBypassed); | |||||
| pos += max; | |||||
| } | |||||
| } | |||||
| void declareParameters (UnityAudioEffectDefinition& definition) | |||||
| { | |||||
| static std::unique_ptr<UnityAudioParameterDefinition> parametersPtr; | |||||
| static int numParams = 0; | |||||
| if (parametersPtr == nullptr) | |||||
| { | |||||
| auto paramsCopy = juceParameters.params; | |||||
| for (auto* parameter : paramsCopy) | |||||
| { | |||||
| // Unity only displays parameters using a slider so remove any choice parameters | |||||
| if (! parameter->getAllValueStrings().isEmpty()) | |||||
| paramsCopy.remove (paramsCopy.indexOf (parameter)); | |||||
| } | |||||
| numParams = paramsCopy.size(); | |||||
| parametersPtr.reset (static_cast<UnityAudioParameterDefinition*> (std::calloc (static_cast<size_t> (numParams), | |||||
| sizeof (UnityAudioParameterDefinition)))); | |||||
| parameterDescriptions.clear(); | |||||
| for (int i = 0; i < numParams; ++i) | |||||
| { | |||||
| auto* parameter = paramsCopy[i]; | |||||
| auto& paramDef = parametersPtr.get()[i]; | |||||
| strncpy (paramDef.name, parameter->getName (15).toRawUTF8(), 15); | |||||
| if (parameter->getLabel().isNotEmpty()) | |||||
| strncpy (paramDef.unit, parameter->getLabel().toRawUTF8(), 15); | |||||
| parameterDescriptions.add (parameter->getName (15)); | |||||
| paramDef.description = parameterDescriptions[i].toRawUTF8(); | |||||
| paramDef.defaultVal = parameter->getDefaultValue(); | |||||
| paramDef.min = 0.0f; | |||||
| paramDef.max = 1.0f; | |||||
| float scale = 1.0f; | |||||
| float exp = 1.0f; | |||||
| if (auto* floatParam = dynamic_cast<AudioParameterFloat*> (parameter)) | |||||
| { | |||||
| scale = floatParam->range.end; | |||||
| exp = floatParam->range.skew; | |||||
| } | |||||
| else if (auto* intParam = dynamic_cast<AudioParameterInt*> (parameter)) | |||||
| { | |||||
| scale = (float) intParam->getRange().getEnd(); | |||||
| } | |||||
| paramDef.displayScale = scale; | |||||
| paramDef.displayExponent = exp; | |||||
| } | |||||
| } | |||||
| definition.numParameters = numParams; | |||||
| definition.parameterDefintions = parametersPtr.get(); | |||||
| } | |||||
| void setParameter (int index, float value) { juceParameters.getParamForIndex (index)->setValue (value); } | |||||
| float getParameter (int index) const noexcept { return juceParameters.getParamForIndex (index)->getValue(); } | |||||
| String getParameterString (int index) const noexcept | |||||
| { | |||||
| auto* param = juceParameters.getParamForIndex (index); | |||||
| return param->getText (param->getValue(), 16); | |||||
| } | |||||
| int getNumInputChannels() const noexcept { return pluginInstance->getTotalNumInputChannels(); } | |||||
| int getNumOutputChannels() const noexcept { return pluginInstance->getTotalNumOutputChannels(); } | |||||
| bool hasEditor() const noexcept { return pluginInstance->hasEditor(); } | |||||
| UnityPeer& getEditorPeer() const | |||||
| { | |||||
| auto* peer = dynamic_cast<UnityPeer*> (pluginInstanceEditor->getPeer()); | |||||
| jassert (peer != nullptr); | |||||
| return *peer; | |||||
| } | |||||
| private: | |||||
| //============================================================================== | |||||
| void processBuffers (float* inBuffer, float* outBuffer, unsigned int bufferSize, int numInChannels, int numOutChannels, bool isBypassed) | |||||
| { | |||||
| int ch; | |||||
| for (ch = 0; ch < numInChannels; ++ch) | |||||
| { | |||||
| using DstSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::NonConst>; | |||||
| using SrcSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::Interleaved, AudioData::Const>; | |||||
| DstSampleType dstData (scratchBuffer.getWritePointer (ch)); | |||||
| SrcSampleType srcData (inBuffer + ch, numInChannels); | |||||
| dstData.convertSamples (srcData, bufferSize); | |||||
| } | |||||
| for (; ch < numOutChannels; ++ch) | |||||
| scratchBuffer.clear (ch, 0, bufferSize); | |||||
| { | |||||
| const ScopedLock sl (pluginInstance->getCallbackLock()); | |||||
| if (pluginInstance->isSuspended()) | |||||
| { | |||||
| scratchBuffer.clear(); | |||||
| } | |||||
| else | |||||
| { | |||||
| MidiBuffer mb; | |||||
| if (isBypassed) | |||||
| pluginInstance->processBlockBypassed (scratchBuffer, mb); | |||||
| else | |||||
| pluginInstance->processBlock (scratchBuffer, mb); | |||||
| } | |||||
| } | |||||
| for (ch = 0; ch < numOutChannels; ++ch) | |||||
| { | |||||
| using DstSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::Interleaved, AudioData::NonConst>; | |||||
| using SrcSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::Const>; | |||||
| DstSampleType dstData (outBuffer + ch, numOutChannels); | |||||
| SrcSampleType srcData (scratchBuffer.getReadPointer (ch)); | |||||
| dstData.convertSamples (srcData, bufferSize); | |||||
| } | |||||
| } | |||||
| //============================================================================== | |||||
| std::unique_ptr<AudioProcessor> pluginInstance; | |||||
| std::unique_ptr<AudioProcessorEditor> pluginInstanceEditor; | |||||
| int samplesPerBlock = 1024; | |||||
| StringArray parameterDescriptions; | |||||
| AudioBuffer<float> scratchBuffer; | |||||
| LegacyAudioParametersWrapper juceParameters; | |||||
| //============================================================================== | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessorUnityWrapper) | |||||
| }; | |||||
| //============================================================================== | |||||
| HashMap<int, AudioProcessorUnityWrapper*>& getWrapperMap() | |||||
| { | |||||
| static HashMap<int, AudioProcessorUnityWrapper*> wrapperMap; | |||||
| return wrapperMap; | |||||
| } | |||||
| static void onWrapperCreation (AudioProcessorUnityWrapper* wrapperToAdd) | |||||
| { | |||||
| getWrapperMap().set (std::abs (Random::getSystemRandom().nextInt (65536)), wrapperToAdd); | |||||
| } | |||||
| static void onWrapperDeletion (AudioProcessorUnityWrapper* wrapperToRemove) | |||||
| { | |||||
| getWrapperMap().removeValue (wrapperToRemove); | |||||
| } | |||||
| //============================================================================== | |||||
| namespace UnityCallbacks | |||||
| { | |||||
| int UNITY_INTERFACE_API createCallback (UnityAudioEffectState* state) | |||||
| { | |||||
| if (getWrapperMap().size() == 0) | |||||
| initialiseJuce_GUI(); | |||||
| auto* pluginInstance = new AudioProcessorUnityWrapper (false); | |||||
| pluginInstance->create (state); | |||||
| state->effectData = pluginInstance; | |||||
| onWrapperCreation (pluginInstance); | |||||
| return 0; | |||||
| } | |||||
| int UNITY_INTERFACE_API releaseCallback (UnityAudioEffectState* state) | |||||
| { | |||||
| auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>(); | |||||
| pluginInstance->release(); | |||||
| onWrapperDeletion (pluginInstance); | |||||
| delete pluginInstance; | |||||
| if (getWrapperMap().size() == 0) | |||||
| shutdownJuce_GUI(); | |||||
| return 0; | |||||
| } | |||||
| int UNITY_INTERFACE_API resetCallback (UnityAudioEffectState* state) | |||||
| { | |||||
| auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>(); | |||||
| pluginInstance->reset(); | |||||
| return 0; | |||||
| } | |||||
| int UNITY_INTERFACE_API setPositionCallback (UnityAudioEffectState* state, unsigned int pos) | |||||
| { | |||||
| ignoreUnused (state, pos); | |||||
| return 0; | |||||
| } | |||||
| int UNITY_INTERFACE_API setFloatParameterCallback (UnityAudioEffectState* state, int index, float value) | |||||
| { | |||||
| auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>(); | |||||
| pluginInstance->setParameter (index, value); | |||||
| return 0; | |||||
| } | |||||
| int UNITY_INTERFACE_API getFloatParameterCallback (UnityAudioEffectState* state, int index, float* value, char* valueStr) | |||||
| { | |||||
| auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>(); | |||||
| *value = pluginInstance->getParameter (index); | |||||
| strncpy (valueStr, pluginInstance->getParameterString (index).toRawUTF8(), 15); | |||||
| return 0; | |||||
| } | |||||
| int UNITY_INTERFACE_API getFloatBufferCallback (UnityAudioEffectState* state, const char* name, float* buffer, int numSamples) | |||||
| { | |||||
| ignoreUnused (numSamples); | |||||
| auto nameStr = String (name); | |||||
| if (nameStr == "Editor") | |||||
| { | |||||
| auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>(); | |||||
| buffer[0] = pluginInstance->hasEditor() ? 1.0f : 0.0f; | |||||
| } | |||||
| else if (nameStr == "ID") | |||||
| { | |||||
| auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>(); | |||||
| for (HashMap<int, AudioProcessorUnityWrapper*>::Iterator i (getWrapperMap()); i.next();) | |||||
| { | |||||
| if (i.getValue() == pluginInstance) | |||||
| { | |||||
| buffer[0] = (float) i.getKey(); | |||||
| break; | |||||
| } | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| else if (nameStr == "Size") | |||||
| { | |||||
| auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>(); | |||||
| auto& editor = pluginInstance->getEditorPeer().getEditor(); | |||||
| buffer[0] = (float) editor.getBounds().getWidth(); | |||||
| buffer[1] = (float) editor.getBounds().getHeight(); | |||||
| buffer[2] = (float) editor.getConstrainer()->getMinimumWidth(); | |||||
| buffer[3] = (float) editor.getConstrainer()->getMinimumHeight(); | |||||
| buffer[4] = (float) editor.getConstrainer()->getMaximumWidth(); | |||||
| buffer[5] = (float) editor.getConstrainer()->getMaximumHeight(); | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| int UNITY_INTERFACE_API processCallback (UnityAudioEffectState* state, float* inBuffer, float* outBuffer, | |||||
| unsigned int bufferSize, int numInChannels, int numOutChannels) | |||||
| { | |||||
| auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>(); | |||||
| if (pluginInstance != nullptr) | |||||
| { | |||||
| auto isPlaying = ((state->flags & stateIsPlaying) != 0); | |||||
| auto isMuted = ((state->flags & stateIsMuted) != 0); | |||||
| auto isPaused = ((state->flags & stateIsPaused) != 0); | |||||
| auto bypassed = ! isPlaying || (isMuted || isPaused); | |||||
| pluginInstance->process (inBuffer, outBuffer, bufferSize, numInChannels, numOutChannels, bypassed); | |||||
| } | |||||
| else | |||||
| { | |||||
| FloatVectorOperations::clear (outBuffer, bufferSize * numOutChannels); | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| //============================================================================== | |||||
| static void declareEffect (UnityAudioEffectDefinition& definition) | |||||
| { | |||||
| memset (&definition, 0, sizeof (definition)); | |||||
| std::unique_ptr<AudioProcessorUnityWrapper> wrapper = std::make_unique<AudioProcessorUnityWrapper> (true); | |||||
| String name (JucePlugin_Name); | |||||
| if (! name.startsWithIgnoreCase ("audioplugin")) | |||||
| name = "audioplugin_" + name; | |||||
| strcpy (definition.name, name.toRawUTF8()); | |||||
| definition.structSize = sizeof (UnityAudioEffectDefinition); | |||||
| definition.parameterStructSize = sizeof (UnityAudioParameterDefinition); | |||||
| definition.apiVersion = UNITY_AUDIO_PLUGIN_API_VERSION; | |||||
| definition.pluginVersion = JucePlugin_VersionCode; | |||||
| // effects must set this to 0, generators > 0 | |||||
| definition.channels = (wrapper->getNumInputChannels() != 0 ? 0 : wrapper->getNumOutputChannels()); | |||||
| wrapper->declareParameters (definition); | |||||
| definition.create = UnityCallbacks::createCallback; | |||||
| definition.release = UnityCallbacks::releaseCallback; | |||||
| definition.reset = UnityCallbacks::resetCallback; | |||||
| definition.setPosition = UnityCallbacks::setPositionCallback; | |||||
| definition.process = UnityCallbacks::processCallback; | |||||
| definition.setFloatParameter = UnityCallbacks::setFloatParameterCallback; | |||||
| definition.getFloatParameter = UnityCallbacks::getFloatParameterCallback; | |||||
| definition.getFloatBuffer = UnityCallbacks::getFloatBufferCallback; | |||||
| } | |||||
| } // namespace juce | |||||
| UNITY_INTERFACE_EXPORT int UnityGetAudioEffectDefinitions (UnityAudioEffectDefinition*** definitionsPtr) | |||||
| { | |||||
| static bool hasSetWrapperType = false; | |||||
| if (! hasSetWrapperType) | |||||
| { | |||||
| juce::PluginHostType::jucePlugInClientCurrentWrapperType = juce::AudioProcessor::wrapperType_Unity; | |||||
| juce::juce_createUnityPeerFn = juce::createUnityPeer; | |||||
| hasSetWrapperType = true; | |||||
| } | |||||
| auto* definition = new UnityAudioEffectDefinition(); | |||||
| juce::declareEffect (*definition); | |||||
| *definitionsPtr = &definition; | |||||
| return 1; | |||||
| } | |||||
| //============================================================================== | |||||
| static juce::ModifierKeys unityModifiersToJUCE (UnityEventModifiers mods, bool mouseDown, int mouseButton = -1) | |||||
| { | |||||
| int flags = 0; | |||||
| if (mouseDown) | |||||
| { | |||||
| if (mouseButton == 0) | |||||
| flags |= juce::ModifierKeys::leftButtonModifier; | |||||
| else if (mouseButton == 1) | |||||
| flags |= juce::ModifierKeys::rightButtonModifier; | |||||
| else if (mouseButton == 2) | |||||
| flags |= juce::ModifierKeys::middleButtonModifier; | |||||
| } | |||||
| if (mods == 0) | |||||
| return flags; | |||||
| if ((mods & UnityEventModifiers::shift) != 0) flags |= juce::ModifierKeys::shiftModifier; | |||||
| if ((mods & UnityEventModifiers::control) != 0) flags |= juce::ModifierKeys::ctrlModifier; | |||||
| if ((mods & UnityEventModifiers::alt) != 0) flags |= juce::ModifierKeys::altModifier; | |||||
| if ((mods & UnityEventModifiers::command) != 0) flags |= juce::ModifierKeys::commandModifier; | |||||
| return { flags }; | |||||
| } | |||||
| //============================================================================== | |||||
| static juce::AudioProcessorUnityWrapper* getWrapperChecked (int id) | |||||
| { | |||||
| auto* wrapper = juce::getWrapperMap()[id]; | |||||
| jassert (wrapper != nullptr); | |||||
| return wrapper; | |||||
| } | |||||
| //============================================================================== | |||||
| static void UNITY_INTERFACE_API onRenderEvent (int id) | |||||
| { | |||||
| getWrapperChecked (id)->getEditorPeer().triggerAsyncUpdate(); | |||||
| } | |||||
| UNITY_INTERFACE_EXPORT renderCallback UNITY_INTERFACE_API getRenderCallback() | |||||
| { | |||||
| return onRenderEvent; | |||||
| } | |||||
| UNITY_INTERFACE_EXPORT void unityInitialiseTexture (int id, void* data, int w, int h) | |||||
| { | |||||
| getWrapperChecked (id)->getEditorPeer().setPixelDataHandle (reinterpret_cast<juce::uint8*> (data), w, h); | |||||
| } | |||||
| UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityMouseDown (int id, float x, float y, UnityEventModifiers unityMods, int button) | |||||
| { | |||||
| getWrapperChecked (id)->getEditorPeer().forwardMouseEvent ({ x, y }, unityModifiersToJUCE (unityMods, true, button)); | |||||
| } | |||||
| UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityMouseDrag (int id, float x, float y, UnityEventModifiers unityMods, int button) | |||||
| { | |||||
| getWrapperChecked (id)->getEditorPeer().forwardMouseEvent ({ x, y }, unityModifiersToJUCE (unityMods, true, button)); | |||||
| } | |||||
| UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityMouseUp (int id, float x, float y, UnityEventModifiers unityMods) | |||||
| { | |||||
| getWrapperChecked (id)->getEditorPeer().forwardMouseEvent ({ x, y }, unityModifiersToJUCE (unityMods, false)); | |||||
| } | |||||
| UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityKeyEvent (int id, int code, UnityEventModifiers mods, const char* name) | |||||
| { | |||||
| getWrapperChecked (id)->getEditorPeer().forwardKeyPress (code, name, unityModifiersToJUCE (mods, false)); | |||||
| } | |||||
| UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unitySetScreenBounds (int id, float x, float y, float w, float h) | |||||
| { | |||||
| getWrapperChecked (id)->getEditorPeer().getEditor().setBounds ({ (int) x, (int) y, (int) w, (int) h }); | |||||
| } | |||||
| //============================================================================== | |||||
| #if JUCE_WINDOWS | |||||
| extern "C" BOOL WINAPI DllMain (HINSTANCE instance, DWORD reason, LPVOID) | |||||
| { | |||||
| if (reason == DLL_PROCESS_ATTACH) | |||||
| juce::Process::setCurrentModuleInstanceHandle (instance); | |||||
| return true; | |||||
| } | |||||
| #endif | |||||
| #endif | |||||
| @@ -0,0 +1,27 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCE library. | |||||
| Copyright (c) 2017 - ROLI Ltd. | |||||
| JUCE is an open source library subject to commercial or open-source | |||||
| licensing. | |||||
| By using JUCE, you agree to the terms of both the JUCE 5 End-User License | |||||
| Agreement and JUCE 5 Privacy Policy (both updated and effective as of the | |||||
| 27th April 2017). | |||||
| End User License Agreement: www.juce.com/juce-5-licence | |||||
| Privacy Policy: www.juce.com/juce-5-privacy-policy | |||||
| Or: You may also use this code under the terms of the GPL v3 (see | |||||
| www.gnu.org/licenses). | |||||
| JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER | |||||
| EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE | |||||
| DISCLAIMED. | |||||
| ============================================================================== | |||||
| */ | |||||
| #include "Unity/juce_Unity_Wrapper.cpp" | |||||
| @@ -30,7 +30,8 @@ | |||||
| #if ! (JucePlugin_Build_VST || JucePlugin_Build_VST3 \ | #if ! (JucePlugin_Build_VST || JucePlugin_Build_VST3 \ | ||||
| || JucePlugin_Build_AU || JucePlugin_Build_AUv3 \ | || JucePlugin_Build_AU || JucePlugin_Build_AUv3 \ | ||||
| ||JucePlugin_Build_RTAS || JucePlugin_Build_AAX \ | ||JucePlugin_Build_RTAS || JucePlugin_Build_AAX \ | ||||
| || JucePlugin_Build_Standalone || JucePlugin_Build_LV2) | |||||
| || JucePlugin_Build_Standalone || JucePlugin_Build_LV2 \ | |||||
| || JucePlugin_Build_Unity) | |||||
| #error "You need to enable at least one plugin format!" | #error "You need to enable at least one plugin format!" | ||||
| #endif | #endif | ||||
| @@ -39,6 +39,10 @@ namespace juce | |||||
| AudioProcessor::WrapperType PluginHostType::jucePlugInClientCurrentWrapperType = AudioProcessor::wrapperType_Undefined; | AudioProcessor::WrapperType PluginHostType::jucePlugInClientCurrentWrapperType = AudioProcessor::wrapperType_Undefined; | ||||
| #if JucePlugin_Build_Unity | |||||
| bool juce_isRunningInUnity() { return PluginHostType::getPluginLoadedAs() == AudioProcessor::wrapperType_Unity; } | |||||
| #endif | |||||
| #ifndef JUCE_VST3_CAN_REPLACE_VST2 | #ifndef JUCE_VST3_CAN_REPLACE_VST2 | ||||
| #define JUCE_VST3_CAN_REPLACE_VST2 1 | #define JUCE_VST3_CAN_REPLACE_VST2 1 | ||||
| #endif | #endif | ||||
| @@ -1352,7 +1352,8 @@ public: | |||||
| wrapperType_AudioUnitv3, | wrapperType_AudioUnitv3, | ||||
| wrapperType_RTAS, | wrapperType_RTAS, | ||||
| wrapperType_AAX, | wrapperType_AAX, | ||||
| wrapperType_Standalone | |||||
| wrapperType_Standalone, | |||||
| wrapperType_Unity | |||||
| }; | }; | ||||
| /** When loaded by a plugin wrapper, this flag will be set to indicate the type | /** When loaded by a plugin wrapper, this flag will be set to indicate the type | ||||
| @@ -207,4 +207,23 @@ void AudioProcessorEditor::setScaleFactor (float newScale) | |||||
| editorResized (true); | editorResized (true); | ||||
| } | } | ||||
| //============================================================================== | |||||
| #if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client && JucePlugin_Build_Unity | |||||
| typedef ComponentPeer* (*createUnityPeerFunctionType) (Component&); | |||||
| createUnityPeerFunctionType juce_createUnityPeerFn = nullptr; | |||||
| #endif | |||||
| ComponentPeer* AudioProcessorEditor::createNewPeer (int styleFlags, void* nativeWindow) | |||||
| { | |||||
| #if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client && JucePlugin_Build_Unity | |||||
| if (juce_createUnityPeerFn != nullptr) | |||||
| { | |||||
| ignoreUnused (styleFlags, nativeWindow); | |||||
| return juce_createUnityPeerFn (*this); | |||||
| } | |||||
| #endif | |||||
| return Component::createNewPeer (styleFlags, nativeWindow); | |||||
| } | |||||
| } // namespace juce | } // namespace juce | ||||
| @@ -193,6 +193,8 @@ private: | |||||
| JUCE_DECLARE_NON_COPYABLE (AudioProcessorEditorListener) | JUCE_DECLARE_NON_COPYABLE (AudioProcessorEditorListener) | ||||
| }; | }; | ||||
| ComponentPeer* createNewPeer (int styleFlags, void*) override; | |||||
| //============================================================================== | //============================================================================== | ||||
| void initialise(); | void initialise(); | ||||
| void editorResized (bool wasResized); | void editorResized (bool wasResized); | ||||
| @@ -31,6 +31,10 @@ CheckEventBlockedByModalComps isEventBlockedByModalComps = nullptr; | |||||
| typedef void (*SettingChangeCallbackFunc) (void); | typedef void (*SettingChangeCallbackFunc) (void); | ||||
| SettingChangeCallbackFunc settingChangeCallback = nullptr; | SettingChangeCallbackFunc settingChangeCallback = nullptr; | ||||
| #if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client && JucePlugin_Build_Unity | |||||
| bool juce_isRunningInUnity(); | |||||
| #endif | |||||
| //============================================================================== | //============================================================================== | ||||
| namespace WindowsMessageHelpers | namespace WindowsMessageHelpers | ||||
| { | { | ||||
| @@ -168,6 +172,12 @@ bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPend | |||||
| bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* const message) | bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* const message) | ||||
| { | { | ||||
| message->incReferenceCount(); | message->incReferenceCount(); | ||||
| #if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client && JucePlugin_Build_Unity | |||||
| if (juce_isRunningInUnity()) | |||||
| return SendNotifyMessage (juce_messageWindowHandle, WindowsMessageHelpers::customMessageID, 0, (LPARAM) message) != 0; | |||||
| else | |||||
| #endif | |||||
| return PostMessage (juce_messageWindowHandle, WindowsMessageHelpers::customMessageID, 0, (LPARAM) message) != 0; | return PostMessage (juce_messageWindowHandle, WindowsMessageHelpers::customMessageID, 0, (LPARAM) message) != 0; | ||||
| } | } | ||||