beginning of JSON schema + now vst3 plugin factory is good
This commit is contained in:
parent
6cab6e8516
commit
33c743a3a2
54
schema.json
Normal file
54
schema.json
Normal file
@ -0,0 +1,54 @@
|
||||
{
|
||||
"title": "Tibia data",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"company": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Company name",
|
||||
"pattern": "^[\u0000-\ud7ff\ue000-\uffff]+$"
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "Company website URL",
|
||||
"pattern": "^[\u0000-\ud7ff\ue000-\uffff]+$"
|
||||
},
|
||||
"email": {
|
||||
"type": "string",
|
||||
"description": "Company email",
|
||||
"pattern": "^[\u0000-\ud7ff\ue000-\uffff]+$"
|
||||
}
|
||||
},
|
||||
"required" : [ "name", "url", "email" ]
|
||||
},
|
||||
"product": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Product name",
|
||||
"pattern": "^[\u0000-\ud7ff\ue000-\uffff]+$"
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "Product version in MAJOR.MINOR.PATCH format (all numeric decimal)",
|
||||
"pattern": "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$"
|
||||
},
|
||||
"buildVersion": {
|
||||
"type": "string",
|
||||
"description": "Product build version (numeric decimal)",
|
||||
"pattern": "^(0|[1-9][0-9]*)$"
|
||||
},
|
||||
"bundleName": {
|
||||
"type": "string",
|
||||
"description": "Product bundle name base",
|
||||
"pattern": "^[_0-9a-zA-Z]+$"
|
||||
}
|
||||
},
|
||||
"required": [ "name", "version", "buildVersion", "bundleName" ]
|
||||
}
|
||||
},
|
||||
"required": [ "company", "product" ]
|
||||
}
|
@ -3,10 +3,10 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleName</key>
|
||||
<string>{{=it.plugin.bundleName}}</string>
|
||||
<string>{{=it.product.bundleName}}</string>
|
||||
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>{{=it.plugin.bundleName}}</string>
|
||||
<string>{{=it.product.bundleName}}</string>
|
||||
|
||||
</dict>
|
||||
</plist>
|
||||
|
@ -1,2 +1,2 @@
|
||||
BUNDLE_NAME := {{=it.plugin.bundleName}}
|
||||
BUNDLE_NAME := {{=it.product.bundleName}}
|
||||
VST3_C_API_DIR := ../../vst3_c_api
|
||||
|
@ -1,9 +1,17 @@
|
||||
#define DATA_COMPANY_NAME "{{=it.company.name}}"
|
||||
#define DATA_COMPANY_URL "{{=it.company.url}}"
|
||||
#define DATA_COMPANY_EMAIL "{{=it.company.email}}"
|
||||
#define DATA_COMPANY_NAME "{{=it.tibia.CGetUTF8StringLiteral(it.company.name, 63)}}"
|
||||
#define DATA_COMPANY_URL "{{=it.tibia.CGetUTF8StringLiteral(it.company.url, 255)}}"
|
||||
#define DATA_COMPANY_EMAIL "{{=it.tibia.CGetUTF8StringLiteral(it.company.email, 127)}}"
|
||||
|
||||
#define DATA_PLUGIN_NAME "{{=it.plugin.name}}"
|
||||
#define DATA_PLUGIN_VERSION "{{=it.plugin.version}}"
|
||||
#define DATA_PRODUCT_NAME "{{=it.tibia.CGetUTF8StringLiteral(it.product.name, 63)}}"
|
||||
#define DATA_PRODUCT_VERSION "{{=(it.product.version + '.' + it.product.buildVersion).substring(0, 63)}}"
|
||||
|
||||
static Steinberg_char16 dataProductNameW[64] = { {{~Array.from(it.product.name).slice(0, 63) :c}}0x{{=c.charCodeAt(0).toString(16)}}, {{~}}0 };
|
||||
static Steinberg_char16 dataProductVersionW[64] = { {{~Array.from(it.product.version + "." + it.product.buildVersion).slice(0, 63) :c}}0x{{=c.charCodeAt(0).toString(16)}}, {{~}}0 };
|
||||
|
||||
#define DATA_VST3_SDK_VERSION "VST 3.7.4 | Tibia"
|
||||
static Steinberg_char16 dataVST3SDKVersionW[64] = { {{~Array.from("VST 3.7.4 | Tibia") :c}}0x{{=c.charCodeAt(0).toString(16)}}, {{~}}0 };
|
||||
|
||||
static Steinberg_char16 dataVST3ControllerNameW[64] = { {{~Array.from(it.product.name + " Controller").slice(0, 63) :c}}0x{{=c.charCodeAt(0).toString(16)}}, {{~}}0 };
|
||||
|
||||
#define DATA_VST3_PLUGIN_CID_1 0x{{=it.vst3.plugin.cid.substring(0, 8)}}
|
||||
#define DATA_VST3_PLUGIN_CID_2 0x{{=it.vst3.plugin.cid.substring(8, 16)}}
|
||||
@ -17,14 +25,14 @@
|
||||
|
||||
#define DATA_VST3_SUBCATEGORY "{{=it.vst3.subCategory}}"
|
||||
|
||||
#define DATA_PLUGIN_BUSES_AUDIO_INPUT_N {{=it.plugin.buses.filter(x => x.type == "audio" && x.direction == "input").length}}
|
||||
#define DATA_PLUGIN_BUSES_AUDIO_OUTPUT_N {{=it.plugin.buses.filter(x => x.type == "audio" && x.direction == "output").length}}
|
||||
#define DATA_PLUGIN_BUSES_EVENT_INPUT_N {{=it.plugin.buses.filter(x => x.type == "event" && x.direction == "input").length}}
|
||||
#define DATA_PLUGIN_BUSES_EVENT_OUTPUT_N {{=it.plugin.buses.filter(x => x.type == "event" && x.direction == "output").length}}
|
||||
#define DATA_PLUGIN_BUSES_AUDIO_INPUT_N {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "input").length}}
|
||||
#define DATA_PLUGIN_BUSES_AUDIO_OUTPUT_N {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "output").length}}
|
||||
#define DATA_PLUGIN_BUSES_EVENT_INPUT_N {{=it.product.buses.filter(x => x.type == "event" && x.direction == "input").length}}
|
||||
#define DATA_PLUGIN_BUSES_EVENT_OUTPUT_N {{=it.product.buses.filter(x => x.type == "event" && x.direction == "output").length}}
|
||||
|
||||
#if DATA_PLUGIN_BUSES_AUDIO_INPUT_N > 0
|
||||
static struct Steinberg_Vst_BusInfo busInfoAudioInput[DATA_PLUGIN_BUSES_AUDIO_INPUT_N] = {
|
||||
{{~it.plugin.buses.filter(x => x.type == "audio" && x.direction == "input") :b}}
|
||||
{{~it.product.buses.filter(x => x.type == "audio" && x.direction == "input") :b}}
|
||||
{
|
||||
/* .mediaType = */ Steinberg_Vst_MediaTypes_kAudio,
|
||||
/* .direction = */ Steinberg_Vst_BusDirections_kInput,
|
||||
@ -39,7 +47,7 @@ static struct Steinberg_Vst_BusInfo busInfoAudioInput[DATA_PLUGIN_BUSES_AUDIO_IN
|
||||
|
||||
#if DATA_PLUGIN_BUSES_AUDIO_OUTPUT_N > 0
|
||||
static struct Steinberg_Vst_BusInfo busInfoAudioOutput[DATA_PLUGIN_BUSES_AUDIO_OUTPUT_N] = {
|
||||
{{~it.plugin.buses.filter(x => x.type == "audio" && x.direction == "output") :b}}
|
||||
{{~it.product.buses.filter(x => x.type == "audio" && x.direction == "output") :b}}
|
||||
{
|
||||
/* .mediaType = */ Steinberg_Vst_MediaTypes_kAudio,
|
||||
/* .direction = */ Steinberg_Vst_BusDirections_kOutput,
|
||||
@ -54,7 +62,7 @@ static struct Steinberg_Vst_BusInfo busInfoAudioOutput[DATA_PLUGIN_BUSES_AUDIO_O
|
||||
|
||||
#if DATA_PLUGIN_BUSES_EVENT_INPUT_N > 0
|
||||
static struct Steinberg_Vst_BusInfo busInfoEventInput[DATA_PLUGIN_BUSES_EVENT_INPUT_N] = {
|
||||
{{~it.plugin.buses.filter(x => x.type == "event" && x.direction == "input") :b}}
|
||||
{{~it.product.buses.filter(x => x.type == "event" && x.direction == "input") :b}}
|
||||
{
|
||||
/* .mediaType = */ Steinberg_Vst_MediaTypes_kEvent,
|
||||
/* .direction = */ Steinberg_Vst_BusDirections_kInput,
|
||||
@ -69,7 +77,7 @@ static struct Steinberg_Vst_BusInfo busInfoEventInput[DATA_PLUGIN_BUSES_EVENT_IN
|
||||
|
||||
#if DATA_PLUGIN_BUSES_EVENT_OUTPUT_N > 0
|
||||
static struct Steinberg_Vst_BusInfo busInfoAudioInput[DATA_PLUGIN_BUSES_EVENT_OUTPUT_N] = {
|
||||
{{~it.plugin.buses.filter(x => x.type == "event" && x.direction == "output") :b}}
|
||||
{{~it.product.buses.filter(x => x.type == "event" && x.direction == "output") :b}}
|
||||
{
|
||||
/* .mediaType = */ Steinberg_Vst_MediaTypes_kEvent,
|
||||
/* .direction = */ Steinberg_Vst_BusDirections_kOutput,
|
||||
@ -82,11 +90,11 @@ static struct Steinberg_Vst_BusInfo busInfoAudioInput[DATA_PLUGIN_BUSES_EVENT_OU
|
||||
};
|
||||
#endif
|
||||
|
||||
#define DATA_PLUGIN_PARAMETERS_N {{=it.plugin.parameters.length}}
|
||||
#define DATA_PLUGIN_PARAMETERS_N {{=it.product.parameters.length}}
|
||||
|
||||
#if DATA_PLUGIN_PARAMETERS_N > 0
|
||||
static struct Steinberg_Vst_ParameterInfo parameterInfo[DATA_PLUGIN_PARAMETERS_N] = {
|
||||
{{~it.plugin.parameters :p:i}}
|
||||
{{~it.product.parameters :p:i}}
|
||||
{
|
||||
/* .id = */ {{=i}},
|
||||
/* .title = */ { {{~Array.from(p.name) :c}}0x{{=c.charCodeAt(0).toString(16)}}, {{~}}0 },
|
||||
|
@ -9,6 +9,7 @@
|
||||
// https://github.com/rubberduck-vba/Rubberduck/wiki/COM-in-plain-C
|
||||
// https://devblogs.microsoft.com/oldnewthing/20040205-00/?p=40733
|
||||
|
||||
|
||||
#ifdef NDEBUG
|
||||
# define TRACE(...) /* do nothing */
|
||||
#else
|
||||
@ -683,8 +684,8 @@ static Steinberg_tresult factoryQueryInterface(void *thisInterface, const Steinb
|
||||
TRACE("factory queryInterface\n");
|
||||
if (memcmp(iid, Steinberg_FUnknown_iid, sizeof(Steinberg_TUID))
|
||||
&& memcmp(iid, Steinberg_IPluginFactory_iid, sizeof(Steinberg_TUID))
|
||||
&& memcmp(iid, Steinberg_IPluginFactory2_iid, sizeof(Steinberg_TUID))) {
|
||||
//&& memcmp(iid, Steinberg_IPluginFactory3_iid, sizeof(Steinberg_TUID))) {
|
||||
&& memcmp(iid, Steinberg_IPluginFactory2_iid, sizeof(Steinberg_TUID))
|
||||
&& memcmp(iid, Steinberg_IPluginFactory3_iid, sizeof(Steinberg_TUID))) {
|
||||
TRACE(" not supported\n");
|
||||
*obj = NULL;
|
||||
return Steinberg_kNoInterface;
|
||||
@ -725,14 +726,14 @@ static Steinberg_tresult factoryGetClassInfo(void *thisInterface, Steinberg_int3
|
||||
memcpy(info->cid, pluginCID, sizeof(Steinberg_TUID));
|
||||
info->cardinality = Steinberg_PClassInfo_ClassCardinality_kManyInstances;
|
||||
strcpy(info->category, "Audio Module Class");
|
||||
strcpy(info->name, DATA_PLUGIN_NAME);
|
||||
strcpy(info->name, DATA_PRODUCT_NAME);
|
||||
break;
|
||||
case 1:
|
||||
TRACE(" class 1\n");
|
||||
memcpy(info->cid, controllerCID, sizeof(Steinberg_TUID));
|
||||
info->cardinality = Steinberg_PClassInfo_ClassCardinality_kManyInstances;
|
||||
strcpy(info->category, "Component Controller Class");
|
||||
strcpy(info->name, DATA_PLUGIN_NAME " Controller");
|
||||
strcpy(info->name, DATA_PRODUCT_NAME " Controller");
|
||||
break;
|
||||
default:
|
||||
return Steinberg_kInvalidArgument;
|
||||
@ -804,24 +805,24 @@ static Steinberg_tresult factoryGetClassInfo2(void* thisInterface, Steinberg_int
|
||||
memcpy(info->cid, pluginCID, sizeof(Steinberg_TUID));
|
||||
info->cardinality = Steinberg_PClassInfo_ClassCardinality_kManyInstances;
|
||||
strcpy(info->category, "Audio Module Class");
|
||||
strcpy(info->name, DATA_PLUGIN_NAME);
|
||||
strcpy(info->name, DATA_PRODUCT_NAME);
|
||||
info->classFlags = Steinberg_Vst_ComponentFlags_kDistributable;
|
||||
strcpy(info->subCategories, DATA_VST3_SUBCATEGORY);
|
||||
*info->vendor = '\0';
|
||||
strcpy(info->version, DATA_PLUGIN_VERSION);
|
||||
strcpy(info->sdkVersion, "VST 3.7.4 | Tibia");
|
||||
strcpy(info->version, DATA_PRODUCT_VERSION);
|
||||
strcpy(info->sdkVersion, "VST " DATA_VST3_SDK_VERSION " | Tibia");
|
||||
break;
|
||||
case 1:
|
||||
TRACE(" class 1\n");
|
||||
memcpy(info->cid, controllerCID, sizeof(Steinberg_TUID));
|
||||
info->cardinality = Steinberg_PClassInfo_ClassCardinality_kManyInstances;
|
||||
strcpy(info->category, "Component Controller Class");
|
||||
strcpy(info->name, DATA_PLUGIN_NAME " Controller");
|
||||
strcpy(info->name, DATA_PRODUCT_NAME " Controller");
|
||||
info->classFlags = 0;
|
||||
*info->subCategories = '\0';
|
||||
*info->vendor = '\0';
|
||||
strcpy(info->version, DATA_PLUGIN_VERSION);
|
||||
strcpy(info->sdkVersion, "VST 3.7.4 | Tibia");
|
||||
strcpy(info->version, DATA_PRODUCT_VERSION);
|
||||
strcpy(info->sdkVersion, "VST " DATA_VST3_SDK_VERSION " | Tibia");
|
||||
break;
|
||||
default:
|
||||
return Steinberg_kInvalidArgument;
|
||||
@ -832,6 +833,35 @@ static Steinberg_tresult factoryGetClassInfo2(void* thisInterface, Steinberg_int
|
||||
|
||||
static Steinberg_tresult factoryGetClassInfoUnicode(void* thisInterface, Steinberg_int32 index, struct Steinberg_PClassInfoW* info) {
|
||||
TRACE("getClassInfo unicode\n");
|
||||
switch (index) {
|
||||
case 0:
|
||||
TRACE(" class 0\n");
|
||||
memcpy(info->cid, pluginCID, sizeof(Steinberg_TUID));
|
||||
info->cardinality = Steinberg_PClassInfo_ClassCardinality_kManyInstances;
|
||||
strcpy(info->category, "Audio Module Class");
|
||||
memcpy(info->name, dataProductNameW, 64 * sizeof(Steinberg_char16));
|
||||
info->classFlags = Steinberg_Vst_ComponentFlags_kDistributable;
|
||||
strcpy(info->subCategories, DATA_VST3_SUBCATEGORY);
|
||||
*info->vendor = '\0';
|
||||
memcpy(info->version, dataProductVersionW, 64 * sizeof(Steinberg_char16));
|
||||
memcpy(info->sdkVersion, dataVST3SDKVersionW, 64 * sizeof(Steinberg_char16));
|
||||
break;
|
||||
case 1:
|
||||
TRACE(" class 1\n");
|
||||
memcpy(info->cid, controllerCID, sizeof(Steinberg_TUID));
|
||||
info->cardinality = Steinberg_PClassInfo_ClassCardinality_kManyInstances;
|
||||
strcpy(info->category, "Component Controller Class");
|
||||
memcpy(info->name, dataVST3ControllerNameW, 64 * sizeof(Steinberg_char16));
|
||||
info->classFlags = 0;
|
||||
*info->subCategories = '\0';
|
||||
*info->vendor = '\0';
|
||||
memcpy(info->version, dataProductVersionW, 64 * sizeof(Steinberg_char16));
|
||||
memcpy(info->sdkVersion, dataVST3SDKVersionW, 64 * sizeof(Steinberg_char16));
|
||||
break;
|
||||
default:
|
||||
return Steinberg_kInvalidArgument;
|
||||
break;
|
||||
}
|
||||
return Steinberg_kResultOk;
|
||||
}
|
||||
|
||||
@ -840,7 +870,7 @@ static Steinberg_tresult factorySetHostContext(void* thisInterface, struct Stein
|
||||
return Steinberg_kResultOk;
|
||||
}
|
||||
|
||||
static Steinberg_IPluginFactory2Vtbl factoryVtbl = {
|
||||
static Steinberg_IPluginFactory3Vtbl factoryVtbl = {
|
||||
/* FUnknown */
|
||||
/* .queryInterface = */ factoryQueryInterface,
|
||||
/* .addRef = */ factoryAddRef,
|
||||
@ -856,10 +886,10 @@ static Steinberg_IPluginFactory2Vtbl factoryVtbl = {
|
||||
/* .getClassInfo2 = */ factoryGetClassInfo2,
|
||||
|
||||
/* IPluginFactory3 */
|
||||
/* .getClassInfoUnicode = */ //factoryGetClassInfoUnicode,
|
||||
/* .setHostContext = */ //factorySetHostContext
|
||||
/* .getClassInfoUnicode = */ factoryGetClassInfoUnicode,
|
||||
/* .setHostContext = */ factorySetHostContext
|
||||
};
|
||||
static Steinberg_IPluginFactory2 factory = { &factoryVtbl };
|
||||
static Steinberg_IPluginFactory3 factory = { &factoryVtbl };
|
||||
|
||||
Steinberg_IPluginFactory * GetPluginFactory() {
|
||||
return (Steinberg_IPluginFactory *)&factory;
|
||||
|
@ -1,7 +1,8 @@
|
||||
{
|
||||
"plugin": {
|
||||
"name": "Tibia test plugin",
|
||||
"version": "1.0.0.1",
|
||||
"product": {
|
||||
"name": "Tibia test product",
|
||||
"version": "1.0.0",
|
||||
"buildVersion": "1",
|
||||
"bundleName": "tibia_test",
|
||||
"buses": [
|
||||
{
|
||||
|
55
tibia
55
tibia
@ -12,6 +12,11 @@ var jsonFiles = process.argv[2].split(",");
|
||||
var template = process.argv[3];
|
||||
var outputDir = process.argv[4];
|
||||
|
||||
var schema = JSON.parse(fs.readFileSync(__dirname + path.sep + "schema.json", { encoding: "utf-8" }));
|
||||
var Ajv = require("ajv");
|
||||
var ajv = new Ajv();
|
||||
var ajvValidate = ajv.compile(schema);
|
||||
|
||||
var data = {};
|
||||
for (var i = 0; i < jsonFiles.length; i++) {
|
||||
var d = JSON.parse(fs.readFileSync(jsonFiles[i], { encoding: "utf-8" }));
|
||||
@ -19,6 +24,12 @@ for (var i = 0; i < jsonFiles.length; i++) {
|
||||
data[k] = d[k];
|
||||
}
|
||||
|
||||
var ajvValid = ajvValidate(data);
|
||||
if (!ajvValid) {
|
||||
console.log(ajvValidate.errors);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var doT = require("dot");
|
||||
doT.templateSettings.strip = false;
|
||||
|
||||
@ -63,4 +74,48 @@ var api = {
|
||||
}
|
||||
};
|
||||
|
||||
data.tibia = {
|
||||
CGetUTF8StringLiteral: function (string, maxLength) {
|
||||
if (!maxLength)
|
||||
maxLength = Infinity;
|
||||
var v = (new TextEncoder()).encode(string);
|
||||
var s = "";
|
||||
for (var i = 0; i < maxLength && i < v.length; ) {
|
||||
if (!(v[i] & 0x80)) {
|
||||
if (v[i] < 0x20 || v[i] == 0x7f) {
|
||||
s += "\\" + v[i].toString(8).padStart(3, "0");
|
||||
} else if (v[i] == 0x22)
|
||||
s += "\\\"";
|
||||
else if (v[i] == 0x5c)
|
||||
s += "\\\\";
|
||||
else
|
||||
s += String.fromCharCode(v[i]);
|
||||
i++;
|
||||
} else if ((v[i] & 0xe0) == 0xc0) {
|
||||
if (maxLength - i < 2)
|
||||
break;
|
||||
for (var j = 0; j < 2; j++) {
|
||||
s += "\\" + v[i].toString(8).padStart(3, "0");
|
||||
i++;
|
||||
}
|
||||
} else if ((v[i] & 0xf0) == 0xe0) {
|
||||
if (maxLength - i < 3)
|
||||
break;
|
||||
for (var j = 0; j < 3; j++) {
|
||||
s += "\\" + v[i].toString(8).padStart(3, "0");
|
||||
i++;
|
||||
}
|
||||
} else if ((v[i] & 0xf8) == 0xf0) {
|
||||
if (maxLength - i < 4)
|
||||
break;
|
||||
for (var j = 0; j < 4; j++) {
|
||||
s += "\\" + v[i].toString(8).padStart(3, "0");
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
};
|
||||
|
||||
require(path.resolve(template + path.sep + "tibia-index.js"))(data, api);
|
||||
|
Loading…
Reference in New Issue
Block a user