Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
172 changes: 168 additions & 4 deletions NeuralAmpModeler/NeuralAmpModelerControls.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
#pragma once

#include <cmath> // std::round
#include <cstdio> // FILE, fclose
#include <sstream> // std::stringstream
#include <unordered_map> // std::unordered_map
#include "IControls.h"
#include "IPlugPaths.h"

#ifdef OS_WIN
#include <Windows.h>
#include <Shellapi.h>
#endif

#define PLUG() static_cast<PLUG_CLASS_NAME*>(GetDelegate())
#define NAM_KNOB_HEIGHT 120.0f
Expand Down Expand Up @@ -902,19 +909,176 @@ class NAMSettingsPageControl : public IContainerBaseWithNamedChildren

buildInfoStr.SetFormatted(100, "Version %s %s %s", verStr.Get(), PLUG()->GetArchStr(), PLUG()->GetAPIStr());

AddChildControl(new IVLabelControl(GetRECT().SubRectVertical(5, 0), "NEURAL AMP MODELER", mStyle));
AddChildControl(new IURLControl(GetRECT().SubRectVertical(5, 0), "NEURAL AMP MODELER",
"https://www.neuralampmodeler.com", mText, COLOR_TRANSPARENT,
PluginColors::HELP_TEXT_MO, PluginColors::HELP_TEXT_CLICKED));
AddChildControl(new IVLabelControl(GetRECT().SubRectVertical(5, 1), "By Steven Atkinson", mStyle));
AddChildControl(new IVLabelControl(GetRECT().SubRectVertical(5, 2), buildInfoStr.Get(), mStyle));
AddChildControl(new IURLControl(GetRECT().SubRectVertical(5, 3),
"Plug-in development: Steve Atkinson, Oli Larkin, ... ",
"https://github.com/sdatkinson/NeuralAmpModelerPlugin/graphs/contributors", mText,
COLOR_TRANSPARENT, PluginColors::HELP_TEXT_MO, PluginColors::HELP_TEXT_CLICKED));
AddChildControl(new IURLControl(GetRECT().SubRectVertical(5, 4), "www.neuralampmodeler.com",
"https://www.neuralampmodeler.com", mText, COLOR_TRANSPARENT,
PluginColors::HELP_TEXT_MO, PluginColors::HELP_TEXT_CLICKED));
AddChildControl(new ThirdPartyNoticesControl(GetRECT().SubRectVertical(5, 4), mText));
};

private:
class ThirdPartyNoticesControl : public IURLControl
{
public:
ThirdPartyNoticesControl(const IRECT& bounds, const IText& text)
: IURLControl(bounds, "Third party notices", "", text, COLOR_TRANSPARENT, PluginColors::HELP_TEXT_MO,
PluginColors::HELP_TEXT_CLICKED)
{
}

void OnMouseDown(float x, float y, const IMouseMod& mod) override
{
WDL_String path;
bool opened = false;

if (ResolveNoticesPath(GetUI(), path))
opened = OpenNoticesPath(GetUI(), path);

if (!opened)
ShowOpenError(GetUI());

GetUI()->ReleaseMouseCapture();
mClicked = true;
SetDirty(false);
}

private:
static bool FileExists(const WDL_String& path)
{
if (!CStringHasContents(path.Get()))
return false;

FILE* file = WDL_fopenA(path.Get(), "rb");
if (file == nullptr)
return false;

fclose(file);
return true;
}

static bool TryNoticePathInDirectory(WDL_String& result, const WDL_String& directory)
{
if (!CStringHasContents(directory.Get()))
return false;

WDL_String candidate(directory);
const char lastChar = candidate.Get()[candidate.GetLength() - 1];

if (!WDL_IS_DIRCHAR(lastChar))
candidate.Append(WDL_DIRCHAR_STR);

candidate.Append(kNoticesFileName);

if (!FileExists(candidate))
return false;

result.Set(candidate.Get());
return true;
}

// AAX (and similar) load the binary from Contents\x64 or Contents\Win32 while notices live in
// Contents\Resources. Same layout as a VST3 bundle; this path is not covered by BundleResourcePath
// when the plug-in is built as AAX_API only (no VST3_API).
static bool TryNoticePathSiblingResources(WDL_String& result, const WDL_String& moduleDirectory)
{
if (!CStringHasContents(moduleDirectory.Get()))
return false;

WDL_String candidate(moduleDirectory);
const char lastChar = candidate.Get()[candidate.GetLength() - 1];
if (!WDL_IS_DIRCHAR(lastChar))
candidate.Append(WDL_DIRCHAR_STR);

candidate.Append("..");
candidate.Append(WDL_DIRCHAR_STR);
candidate.Append("Resources");
candidate.Append(WDL_DIRCHAR_STR);
candidate.Append(kNoticesFileName);

if (!FileExists(candidate))
return false;

result.Set(candidate.Get());
return true;
}

static bool ResolveNoticesPath(IGraphics* pGraphics, WDL_String& path)
{
path.Set("");

if (pGraphics == nullptr)
return false;

#ifdef OS_WIN
WDL_String directory;
const auto moduleHandle = static_cast<PluginIDType>(pGraphics->GetWinModuleHandle());

BundleResourcePath(directory, moduleHandle);
if (TryNoticePathInDirectory(path, directory))
return true;

directory.Set("");
PluginPath(directory, moduleHandle);
if (TryNoticePathInDirectory(path, directory))
return true;

if (TryNoticePathSiblingResources(path, directory))
return true;
#endif

const auto resourceLocation =
LocateResource(kNoticesFileName, "txt", path, pGraphics->GetBundleID(), pGraphics->GetWinModuleHandle(),
pGraphics->GetSharedResourcesSubPath());

return resourceLocation == EResourceLocation::kAbsolutePath && FileExists(path);
}

static bool OpenNoticesPath(IGraphics* pGraphics, const WDL_String& path)
{
if (pGraphics == nullptr || !CStringHasContents(path.Get()))
return false;

#ifdef OS_WIN
WCHAR pathWide[IPLUG_WIN_MAX_WIDE_PATH];
UTF8ToUTF16(pathWide, path.Get(), IPLUG_WIN_MAX_WIDE_PATH);

if (pathWide[0] == 0)
return false;

WCHAR canon[IPLUG_WIN_MAX_WIDE_PATH];
const DWORD nCanon = GetFullPathNameW(pathWide, IPLUG_WIN_MAX_WIDE_PATH, canon, nullptr);
const WCHAR* const launchPath =
(nCanon > 0 && nCanon < IPLUG_WIN_MAX_WIDE_PATH) ? canon : pathWide;

return ShellExecuteW(nullptr, L"open", launchPath, nullptr, nullptr, SW_SHOWNORMAL) > HINSTANCE(32);
#else
return pGraphics->OpenURL(path.Get());
#endif
}

static void ShowOpenError(IGraphics* pGraphics)
{
if (pGraphics == nullptr)
return;

const char* const title = "Third party notices";
const char* const message = "Could not open ThirdPartyNotices.txt.";

#ifdef OS_MAC
pGraphics->ShowMessageBox(title, message, kMB_OK);
#else
pGraphics->ShowMessageBox(message, title, kMB_OK);
#endif
}

static constexpr const char* kNoticesFileName = "ThirdPartyNotices.txt";
};

IVStyle mStyle;
IText mText;
};
Expand Down
9 changes: 6 additions & 3 deletions NeuralAmpModeler/installer/NeuralAmpModeler.iss
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[Setup]
AppName=NeuralAmpModeler
AppContact=neuralampmodeler@gmail.com
AppCopyright=Copyright (C) 2024 Steven Atkinson
AppCopyright=Copyright (C) 2022 Steven Atkinson
AppPublisher=Steven Atkinson
AppPublisherURL=https://www.neuralampmodeler.com/
AppSupportURL=https://www.neuralampmodeler.com/
AppVersion=0.7.14
VersionInfoVersion=1.0.0
VersionInfoVersion=0.7.14
DefaultDirName={pf}\NeuralAmpModeler
DefaultGroupName=NeuralAmpModeler
Compression=lzma2
Expand Down Expand Up @@ -49,6 +49,7 @@ Name: "{cf64}\VST3\NeuralAmpModeler.vst3\"; Attribs: readonly; Check: Is64BitIns
[Files]
;Source: "..\build-win\NeuralAmpModeler_Win32.exe"; DestDir: "{app}"; Check: not Is64BitInstallMode; Components:app; Flags: ignoreversion;
Source: "..\build-win\NeuralAmpModeler_x64.exe"; DestDir: "{app}"; Check: Is64BitInstallMode; Components:app; Flags: ignoreversion;
Source: "ThirdPartyNotices.txt"; DestDir: "{app}"; Components:app; Flags: ignoreversion;

;Source: "..\build-win\NeuralAmpModeler_Win32.dll"; DestDir: {code:GetVST2Dir_32}; Check: not Is64BitInstallMode; Components:vst2_32; Flags: ignoreversion;
;Source: "..\build-win\NeuralAmpModeler_Win32.dll"; DestDir: {code:GetVST2Dir_32}; Check: Is64BitInstallMode; Components:vst2_32; Flags: ignoreversion;
Expand All @@ -58,9 +59,11 @@ Source: "..\build-win\NeuralAmpModeler_x64.exe"; DestDir: "{app}"; Check: Is64Bi
;Source: "..\build-win\NeuralAmpModeler.vst3\Desktop.ini"; DestDir: "{cf32}\VST3\NeuralAmpModeler.vst3\"; Components:vst3_32; Flags: overwritereadonly ignoreversion; Attribs: hidden system;
;Source: "..\build-win\NeuralAmpModeler.vst3\PlugIn.ico"; DestDir: "{cf32}\VST3\NeuralAmpModeler.vst3\"; Components:vst3_32; Flags: overwritereadonly ignoreversion; Attribs: hidden system;

Source: "..\build-win\NeuralAmpModeler.vst3\*.*"; Excludes: "\Contents\x86\*,*.pdb,*.exp,*.lib,*.ilk,*.ico,*.ini"; DestDir: "{cf64}\VST3\NeuralAmpModeler.vst3\"; Check: Is64BitInstallMode; Components:vst3_64; Flags: ignoreversion recursesubdirs;
; 64-bit install: exclude 32-bit arch folder only (iPlug uses x86-win / x86_64-win, not "x86").
Source: "..\build-win\NeuralAmpModeler.vst3\*.*"; Excludes: "\Contents\x86-win\*,*.pdb,*.exp,*.lib,*.ilk,*.ico,*.ini"; DestDir: "{cf64}\VST3\NeuralAmpModeler.vst3\"; Check: Is64BitInstallMode; Components:vst3_64; Flags: ignoreversion recursesubdirs;
Source: "..\build-win\NeuralAmpModeler.vst3\Desktop.ini"; DestDir: "{cf64}\VST3\NeuralAmpModeler.vst3\"; Check: Is64BitInstallMode; Components:vst3_64; Flags: overwritereadonly ignoreversion; Attribs: hidden system;
Source: "..\build-win\NeuralAmpModeler.vst3\PlugIn.ico"; DestDir: "{cf64}\VST3\NeuralAmpModeler.vst3\"; Check: Is64BitInstallMode; Components:vst3_64; Flags: overwritereadonly ignoreversion; Attribs: hidden system;
Source: "ThirdPartyNotices.txt"; DestDir: "{cf64}\VST3\NeuralAmpModeler.vst3\Contents\Resources"; Check: Is64BitInstallMode; Components:vst3_64; Flags: ignoreversion;

;Source: "..\build-win\aax\bin\NeuralAmpModeler.aaxplugin\*.*"; Excludes: "\Contents\x64\*,*.pdb,*.exp,*.lib,*.ilk,*.ico,*.ini"; DestDir: "{cf32}\Avid\Audio\Plug-Ins\NeuralAmpModeler.aaxplugin\"; Components:aax_32; Flags: ignoreversion recursesubdirs;
;Source: "..\build-win\aax\bin\NeuralAmpModeler.aaxplugin\Desktop.ini"; DestDir: "{cf32}\Avid\Audio\Plug-Ins\NeuralAmpModeler.aaxplugin\"; Components:aax_32; Flags: overwritereadonly ignoreversion; Attribs: hidden system;
Expand Down
28 changes: 28 additions & 0 deletions NeuralAmpModeler/installer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Installer Identity

The checked-in Windows installer uses the Neural Amp Modeler product metadata. Before publishing a pre-built installer from a private release fork, replace `license.rtf` with the product's real license and override the installer identity if needed.

The Windows distribution script calls `scripts/update_installer-win.py`, which accepts these environment variable overrides:

- `INSTALLER_DISPLAY_NAME`
- `INSTALLER_APP_CONTACT`
- `INSTALLER_APP_COPYRIGHT`
- `INSTALLER_APP_PUBLISHER`
- `INSTALLER_APP_PUBLISHER_URL`
- `INSTALLER_APP_SUPPORT_URL`
- `INSTALLER_OUTPUT_BASE_FILENAME`
- `INSTALLER_WELCOME_LABEL`
- `INSTALLER_SETUP_WINDOW_TITLE`

The macOS installer package identifiers default to `com.StevenAtkinson.*`. Set `INSTALLER_PKG_ID_PREFIX` to use your own reverse-DNS prefix, for example `com.example.myproduct`.

`ThirdPartyNotices.txt` is installed with the standalone application and inside the VST3/AU bundle resources. Keep it current when adding, removing, or replacing dependencies. Private/product forks should update any source-availability language that points at this public repository.

For notarized macOS release builds, `scripts/makedist-mac.sh` also accepts:

- `NOTARIZE_BUNDLE_ID`
- `NOTARIZE_BUNDLE_ID_DEMO`
- `APP_SPECIFIC_ID`
- `APP_SPECIFIC_PWD`

These settings only affect installer/package identity. Plug-in identity, DAW compatibility, and saved-session compatibility are controlled elsewhere, including `config.h`, Xcode bundle identifiers, and plug-in format metadata.
Loading
Loading