From ce965acc9b26768dd46fe3d8f2b280e47030fdc4 Mon Sep 17 00:00:00 2001 From: Mattia Marini <122118033+mattia-marini@users.noreply.github.com> Date: Tue, 30 Jan 2024 12:05:44 +0100 Subject: [PATCH 1/5] Release Link FX chains of 2 different tracks (GUI) v1.0 --- FX/ReaLink.lua | 30 + FX/ReaLink/Marini_ReaLink_Background.lua | 623 ++++++++++++++++++ .../Marini_ReaLink_Toggle_Autostart.lua | 81 +++ FX/ReaLink/Marini_ReaLink_Ui_Toggle.lua | 10 + 4 files changed, 744 insertions(+) create mode 100644 FX/ReaLink.lua create mode 100644 FX/ReaLink/Marini_ReaLink_Background.lua create mode 100644 FX/ReaLink/Marini_ReaLink_Toggle_Autostart.lua create mode 100644 FX/ReaLink/Marini_ReaLink_Ui_Toggle.lua diff --git a/FX/ReaLink.lua b/FX/ReaLink.lua new file mode 100644 index 000000000..f5bdb1869 --- /dev/null +++ b/FX/ReaLink.lua @@ -0,0 +1,30 @@ +@description Link FX chains of 2 different tracks (GUI) +@author Marini Mattia +@version 1.0 +@metapackage +@provides + [darwin main] ReaLink/Marini_ReaLink_Background.lua + [darwin main] ReaLink/Marini_ReaLink_Toggle_Autostart.lua + [darwin main] ReaLink/Marini_ReaLink_Ui_Toggle.lua +@about + ### A GUI based lua script to link FX parameters across different tracks + This plugin runs a backgound task that links the selected tracks, ensuring that the plugin configurations of the 2 FX chains match + + _A full Guide can be found [here](https://github.com/mattia-marini/ReaperLink/blob/main/Guide.pdf)_ + + #### Usage: + - Install either from ReaPack or from [this repo](ttps://github.com/mattia-marini/ReaperLink) + - Run _"Marini_Realink_Background"_ or configure automatic startup (see below) + - Toggle Ui with _"Marini_Realink_Toggle_UI"_ to create/remove links + + #### Features: + - Linking **every** parameters of **every** plugin across different tracks + - Linking state is saved on project basis + - GUI based link managment + - Multiple tabs support and hot project reloading + - Flexible and roboust linking + - **Zero dependency script** + + #### Automatic startup: + In order for the script to work, a background task should be running i.e., to make synching happen, you have to run the "Marini_Realink_Background" script every time you open Reaper. To make that happen automatically you can run the "Marini_Realink_Toggle_Autostart". (you can see a script state next to its description in action list. Once set to on, the script will automatically launch on next startup) + diff --git a/FX/ReaLink/Marini_ReaLink_Background.lua b/FX/ReaLink/Marini_ReaLink_Background.lua new file mode 100644 index 000000000..98ef78c46 --- /dev/null +++ b/FX/ReaLink/Marini_ReaLink_Background.lua @@ -0,0 +1,623 @@ +-- @noindex + +local count = 0 +function GetActionCommandIDByFilename(searchfilename) + for k in io.lines(reaper.GetResourcePath() .. "/reaper-kb.ini") do + if k:match("SCR") and k:match(searchfilename) then + return "_" .. k:match("SCR %d+ %d+ (%S*) ") + end + end + return nil +end + +local fontSize = 12 +gfx.setfont(1) + +--local currProject, currProjectName = reaper.EnumProjects(-1) +--reaper.ShowConsoleMsg(currProject) +local uiToggleCommand = GetActionCommandIDByFilename("Marini_ReaLink_Ui_Toggle.lua") +local uiToggleCommandId = reaper.NamedCommandLookup(uiToggleCommand) +reaper.SetToggleCommandState(0, uiToggleCommandId, 0) + +local pluginName = "Marini_ReaLink" + +local lastP, lastPName = reaper.EnumProjects(-1) + +local projects = {} +local linkPairs = {} + +local windowSize = nil +local firstInit = true +local scale = 1 +local padding = 20 +local innerPadding = 10 +local trackNamesLeft = 2.5 +local trackNamesSpacing = 25 +local rowHeight = 20 + +local button1W, button1H = 100, 25 +local button2W, button2H = 25, 25 +local buttonSpacing = 10 + +local tableBounds = {} + +local b1Bounds, b2Bounds + +local buttonHover +local tableSelection = nil +local tableHover = nil + + + +local function applyDpiToConstants() + padding = padding * scale + innerPadding = innerPadding * scale + trackNamesLeft = trackNamesLeft * scale + trackNamesSpacing = trackNamesSpacing * scale + rowHeight = rowHeight * scale + + button1W, button1H = button1W * scale, button1H * scale + button2W, button2H = button2W * scale, button2H * scale + buttonSpacing = buttonSpacing * scale + + if reaper.GetOS():match("^Win") == nil then + gfx.setfont(1, "Verdana", fontSize * scale) + else + gfx.setfont(1, "Calibri", fontSize * scale) + end +end + +local function applyDpi(bounds) + for _, value in pairs(bounds) do + value = value * scale + end +end + + +local function parseTracks(project) + local allTracks = {} + + for i = 0, reaper.CountTracks(project) - 1 do + local track = reaper.GetTrack(project, i) + --reaper.ShowConsoleMsg(tostring(track) .. "\n") + allTracks[reaper.GetTrackGUID(track)] = track + end + + local rv = {} + local _, size = reaper.GetProjExtState(project, pluginName, "nLinks") + + if size ~= "" then + for linkIndex = 1, tonumber(size) do + local _, link = reaper.GetProjExtState(project, pluginName, tostring(linkIndex)) + + local masterGUID, slaveGUID = string.match(link, "(%S+),"), string.match(link, ",(%S+)") + + local master, slave = allTracks[masterGUID], allTracks[slaveGUID] + + --reaper.ShowConsoleMsg(masterGUID .. " ".. slaveGUID .. "\n") + if master and slave then + --reaper.ShowConsoleMsg("carico traccia\n") + table.insert(rv, { master, slave }) + end + end + end + + return rv +end + +local function parseAllTracks() + local p, pname = reaper.EnumProjects(0) + local i = 1 + + while p do + --reaper.ShowConsoleMsg("progetto " .. pname .. "\n") + projects[p] = parseTracks(p) + p, pname = reaper.EnumProjects(i) + i = i + 1 + end + + linkPairs = projects[reaper.EnumProjects(-1)] +end + +function saveState() + --reaper.ShowConsoleMsg( tostring(#linkPairs)) + --reaper.SetProjExtState(0, pluginName, "nLinks", tostring()) + reaper.SetProjExtState(0, pluginName, "", "") --cancella stato + reaper.SetProjExtState(0, pluginName, "nLinks", tostring(#linkPairs)) + for i, pair in ipairs(linkPairs) do + --reaper.ShowConsoleMsg(tostring(i)) + + reaper.SetProjExtState(0, pluginName, tostring(i), + reaper.GetTrackGUID(pair[1]) .. "," .. reaper.GetTrackGUID(pair[2])) + --reaper.ShowConsoleMsg("{" .. n1 .. "," .. n2 .. "}\n") + end + + + --file:close() + --reaper.Main_SaveProject(0, false) +end + +function tableView() + tableBounds = { x = padding, y = padding, width = gfx.w - 2 * padding, height = gfx.h - 3 * padding - button1H } + applyDpi(tableBounds) + + gfx.set(0.15, 0.15, 0.15) + gfx.rect(0, 0, gfx.w, gfx.h) + gfx.set(0.1, 0.1, 0.1) + + gfx.rect(padding, padding, gfx.w - 2 * padding, gfx.h - 3 * padding - button1H) + + + if tableHover then + gfx.set(0.15, 0.15, 0.15) + gfx.rect( + tableBounds.x + innerPadding, + tableBounds.y + innerPadding + rowHeight * tableHover, + tableBounds.width - 2 * innerPadding, + rowHeight) + end + + if tableSelection then + gfx.set(0.2, 0.2, 0.2) + gfx.rect( + tableBounds.x + innerPadding, + tableBounds.y + innerPadding + rowHeight * tableSelection, + tableBounds.width - 2 * innerPadding, + rowHeight) + end + + local removeDeletedTracks = {} + for i, pair in ipairs(linkPairs) do + if reaper.ValidatePtr(pair[1], "MediaTrack*") and + reaper.ValidatePtr(pair[2], "MediaTrack*") then + table.insert(removeDeletedTracks, pair) + end + end + linkPairs = removeDeletedTracks + + gfx.set(1, 1, 1) + local maxTrackNameLength = -1 + + + for i, pair in ipairs(linkPairs) do + local _, masterTrack = reaper.GetTrackName(pair[1]) + + if gfx.measurestr(masterTrack) > maxTrackNameLength then + maxTrackNameLength = gfx.measurestr(masterTrack) + end + end + + for i, pair in ipairs(linkPairs) do + local masterTrack, slaveTrack = pair[1], pair[2] + local _, masterTrackName = reaper.GetTrackName(masterTrack) + local _, slaveTrackName = reaper.GetTrackName(slaveTrack) + + --gui stuff + gfx.x, gfx.y = padding + innerPadding + trackNamesLeft, padding + (i - 1) * rowHeight + innerPadding + gfx.drawstr(masterTrackName, 4, tableBounds.x + tableBounds.width - innerPadding, gfx.y + rowHeight) + gfx.x = maxTrackNameLength + padding + trackNamesSpacing + gfx.drawstr(slaveTrackName, 4, tableBounds.x + tableBounds.width - innerPadding, gfx.y + rowHeight) + + --linking FX parameters + + local masterHash, slaveHash = {}, {} + for fxIndex = 0, reaper.TrackFX_GetCount(masterTrack) - 1 do + local _, fxName = reaper.TrackFX_GetFXName(masterTrack, fxIndex) + if masterHash[fxName] == nil then masterHash[fxName] = {} end + table.insert(masterHash[fxName], fxIndex) + end + for fxIndex = 0, reaper.TrackFX_GetCount(slaveTrack) - 1 do + local _, fxName = reaper.TrackFX_GetFXName(slaveTrack, fxIndex) + if slaveHash[fxName] == nil then slaveHash[fxName] = {} end + table.insert(slaveHash[fxName], fxIndex) + end + + for key, value in pairs(masterHash) do + if slaveHash[key] ~= nil then + for fxIndex = 1, math.min(#value, #slaveHash[key]) do + local masterFX, slaveFX = value[fxIndex], slaveHash[key][fxIndex] + for parIndex = 0, reaper.TrackFX_GetNumParams(masterTrack, masterFX) - 1 do + local param1 = reaper.TrackFX_GetParamNormalized(masterTrack, masterFX, parIndex) + local param2 = reaper.TrackFX_GetParamNormalized(slaveTrack, slaveFX, parIndex) + if param1 ~= param2 then + reaper.TrackFX_SetParamNormalized(slaveTrack, slaveFX, parIndex, param1) + end + end + end + end + end + end + + gfx.set(0.15, 0.15, 0.15) + gfx.rect(0, gfx.h - 2 * padding - button1H, gfx.w, 2 * padding + button1H) +end + +local function adjustDpi() +end + +local function buttons() + local button1x, button1y = gfx.w - padding - button1W, gfx.h - padding - button1H + local button2x, button2y = button1x - buttonSpacing - button2W, button1y + b1Bounds = { x1 = button1x, y1 = button1y, x2 = button1x + button1W, y2 = button1y + button1H } + b2Bounds = { x1 = button2x, y1 = button2y, x2 = button2x + button2W, y2 = button2y + button2H } + + --background + gfx.set(0.3, 0.3, 0.3) + gfx.rect(button1x, button1y, button1W, button1H, true) + gfx.rect(button2x, button2y, button2W, button2H, true) + + --hover + if buttonHover then + gfx.set(0.5, 0.5, 0.5, 1) + gfx.rect(buttonHover.x1, buttonHover.y1, buttonHover.x2 - buttonHover.x1, buttonHover.y2 - buttonHover.y1, true) + end + + --lineart + gfx.set(0, 0, 0) + gfx.rect(button1x, button1y, button1W, button1H, false) + gfx.rect(button2x, button2y, button2W, button2H, false) + + --testo + gfx.set(1, 1, 1) + gfx.x, gfx.y = button1x, button1y + gfx.drawstr("Link", 5, gfx.x + button1W, gfx.y + button1H) + + gfx.x, gfx.y = button2x, button2y + gfx.drawstr("-", 5, gfx.x + button2W, gfx.y + button2H) +end + + +local function inBounds(bounds) + gfx.getchar() + local x, y = gfx.mouse_x, gfx.mouse_y + + if bounds.width then + return x > bounds.x and x < bounds.x + bounds.width + and y > bounds.y and y < bounds.y + bounds.height + else + return (x > bounds.x1 and x < bounds.x2 and y > bounds.y1 and y < bounds.y2) + end +end + + +local function addSelectedTracks() + if reaper.CountSelectedTracks(0) < 2 then + reaper.ShowMessageBox("You need to select at lest 2 tracks!", "ReaperLink error", 0) + return + elseif reaper.CountSelectedTracks(0) > 2 then + reaper.ShowMessageBox("You need to select at least 2 tracks!", "ReaperLink error", 0) + return + end + + local track1, track2 = reaper.GetSelectedTrack(0, 0), reaper.GetSelectedTrack(0, 1) + + for i = 1, #linkPairs do + if linkPairs[i][1] == track1 or linkPairs[i][2] == track1 + or linkPairs[i][1] == track2 or linkPairs[i][2] == track2 + then + reaper.ShowMessageBox("Selected tracks are already linked", "ReaperLink error", 0) + return + end + end + + reaper.MarkProjectDirty() + table.insert(linkPairs, { reaper.GetSelectedTrack(0, 0), reaper.GetSelectedTrack(0, 1) }) + saveState() +end + + +local function removeSelectedLink() + if tableSelection then + reaper.MarkProjectDirty() + table.remove(linkPairs, tableSelection + 1) + tableSelection = tableSelection - 1 + if tableSelection == -1 then tableSelection = 0 end + if #linkPairs == 0 then tableSelection = nil end + end + reaper.MarkProjectDirty() + saveState() +end + + +local prevClick = 0 +function handleMouse() + if gfx.mouse_cap == 1 and prevClick == 0 + then + + elseif prevClick == 1 and gfx.mouse_cap == 0 then + if inBounds(tableBounds) then + if (gfx.mouse_y < padding + innerPadding + #linkPairs * rowHeight) and (gfx.mouse_y > padding + innerPadding) then + tableSelection = math.floor((gfx.mouse_y - innerPadding - padding) / rowHeight) + else + tableSelection = nil + end + elseif inBounds(b1Bounds) then + addSelectedTracks() + --reaper.ShowConsoleMsg(tostring(reaper.EnumProjects(-1)) .. " " .. tostring(reaper.EnumProjects(1)) .. "\n") + --[[ + reaper.ShowConsoleMsg("\n") + for key, value in pairs(projectsHash) do + reaper.ShowConsoleMsg(tostring(key) .. "\n") + end + ]] + -- + elseif inBounds(b2Bounds) then + removeSelectedLink() + end + end + + buttonHover = nil + tableHover = nil + + if inBounds(tableBounds) then + if not buttonHover then + if (gfx.mouse_y < padding + innerPadding + #linkPairs * rowHeight) and (gfx.mouse_y > padding + innerPadding) then + tableHover = math.floor((gfx.mouse_y - innerPadding - padding) / rowHeight) + else + tableHover = nil + end + end + elseif inBounds(b1Bounds) then + buttonHover = b1Bounds + elseif inBounds(b2Bounds) then + buttonHover = b2Bounds + end + prevClick = gfx.mouse_cap +end + +local prevToggle = reaper.GetToggleCommandState(uiToggleCommandId) +local prevChar = gfx.getchar() + +local function updateWindowSize() + local d, x, y, w, h = gfx.dock(-1, 0, 0, 0, 0) + if not (x == 0 and y == 0 and w == 0 and h == 0) then + windowSize = { d = d, x = x, y = y, w = w, h = h } + else + windowSize = nil + end +end + +local function checkForToggleUi() + local toggle = reaper.GetToggleCommandState(uiToggleCommandId) + if toggle == 1 and prevToggle == 0 then + if windowSize then + --reaper.ShowConsoleMsg(windowSize.d .. " " .. windowSize.x .. " ".. windowSize.y .. " ".. windowSize.w .. " ".. windowSize.h) + gfx.init("Links", windowSize.w, windowSize.h, windowSize.d, windowSize.x, windowSize.y) + else + gfx.init("Links") + end + if firstInit then + scale = gfx.ext_retina + applyDpiToConstants() + firstInit = false + end + elseif toggle == 0 and prevToggle == 1 then + if not firstInit then + updateWindowSize() + end + gfx.quit() + elseif gfx.getchar() ~= prevChar and gfx.getchar() == -1 then + reaper.SetToggleCommandState(0, uiToggleCommandId, 0) + reaper.RefreshToolbar(uiToggleCommandId) + if not firstInit then + updateWindowSize() + end + end + prevChar = gfx.getchar() + prevToggle = toggle +end + + +reaper.SetToggleCommandState(0, uiToggleCommandId, 0) +local prevIsDirty = reaper.IsProjectDirty(0) + +local function checkForSaves() + local isDirty = reaper.IsProjectDirty(0) + if (isDirty == 0) and prevIsDirty == 1 then + saveState() + end + prevIsDirty = isDirty +end + +local function quit() + --local file = io.open("/Users/mattia/Desktop/prova.txt", "w") + + --reaper.ShowConsoleMsg("1") + --reaper.SetToggleCommandState(0, uiToggleCommandId, 0) + --reaper.ShowConsoleMsg("\ncarattere:" .. gfx.getchar() .. "\n") + local d, x, y, w, h = gfx.dock(-1, 0, 0, 0, 0) + if not (x == 0 and y == 0 and w == 0 and h == 0) then + --reaper.ShowConsoleMsg("gui aperta: " .. x .. " " .. y .. " " .. w .. " " .. h .."\n") + --file:write("GUI aperta ") + --file:write(d,x,y,w,h) + reaper.SetExtState(pluginName, "dock", d, true) + reaper.SetExtState(pluginName, "wndx", x, true) + reaper.SetExtState(pluginName, "wndy", y, true) + reaper.SetExtState(pluginName, "wndw", w, true) + reaper.SetExtState(pluginName, "wndh", h, true) + gfx.quit() + elseif windowSize then + --reaper.ShowConsoleMsg("gui chiusa: " .. x .. " " .. y .. " " .. w .. " " .. h .."\n") + --reaper.ShowConsoleMsg("3") + --file:write("GUI chiusa") + reaper.SetExtState(pluginName, "dock", windowSize.d, true) + reaper.SetExtState(pluginName, "wndx", windowSize.x, true) + reaper.SetExtState(pluginName, "wndy", windowSize.y, true) + reaper.SetExtState(pluginName, "wndw", windowSize.w, true) + reaper.SetExtState(pluginName, "wndh", windowSize.h, true) + end + --file:close() +end + + +function tprint(tbl, indent) + if not indent then indent = 0 end + local toprint = string.rep(" ", indent) .. "{\r\n" + indent = indent + 2 + for k, v in pairs(tbl) do + toprint = toprint .. string.rep(" ", indent) + if (type(k) == "number") then + toprint = toprint .. "[" .. k .. "] = " + elseif (type(k) == "string") then + toprint = toprint .. k .. "= " + end + if (type(v) == "number") then + toprint = toprint .. v .. ",\r\n" + elseif (type(v) == "string") then + toprint = toprint .. "\"" .. v .. "\",\r\n" + elseif (type(v) == "table") then + toprint = toprint .. tprint(v, indent + 2) .. ",\r\n" + else + toprint = toprint .. "\"" .. tostring(v) .. "\",\r\n" + end + end + toprint = toprint .. string.rep(" ", indent - 2) .. "}" + return toprint +end + +local function copyTable(t) + local res = {} + --reaper.ShowConsoleMsg("\n") + for _, val in ipairs(t) do + table.insert(res, { val[1], val[2] }) + --reaper.ShowConsoleMsg(tostring(val[1]).. " " .. tostring(val[2]) .. "\n") + end + --reaper.ShowConsoleMsg("\n") + return res +end + +--[[ +local function printTable(t) + --reaper.ShowConsoleMsg(#linkPairs .. "\n") + for _, val in ipairs(t) do + table.insert(res, {val[1], val[2]}) + --reaper.ShowConsoleMsg("{"..tostring(val[1]) .. ", " .. tostring(val[2]) .. "}") + end + reaper.ShowConsoleMsg("\n") +end +]] +-- + + + +function loadProjects() + local p = reaper.EnumProjects(0) + local i = 1 + while p do + projects[p] = {visited = false} + p = reaper.EnumProjects(i) + i = i + 1 + end +end + +local function setup() + gfx.ext_retina = 1 + --parseAllTracks() + --linkPairs=parseTracks(reaper.EnumProjects(-1)) + loadProjects() + projects[lastP] = {visited = true, links = parseTracks(lastP)} + linkPairs = projects[lastP].links + + d = reaper.GetExtState(pluginName, "dock") + x, y = tonumber(reaper.GetExtState(pluginName, "wndx")), tonumber(reaper.GetExtState(pluginName, "wndy")) + w, h = tonumber(reaper.GetExtState(pluginName, "wndw")), tonumber(reaper.GetExtState(pluginName, "wndh")) + + if d and x and y and w and h then + windowSize = { d = d, x = x, y = y, w = w, h = h } + --reaper.ShowConsoleMsg("loading from ext: " .. x .. " " .. y .. " " .. w .. " " .. h .."\n") + --reaper.ShowConsoleMsg("loading: " .. windowSize.x .. " " .. windowSize.y .. " " .. windowSize.w .. " " .. windowSize.h .."\n\n") + else + windowSize = nil + end + reaper.atexit(quit) +end + + +function checkForProjectChanges() + local currP, currPName = reaper.EnumProjects(-1) + + --++clear closed tabs + local validTabs = {} + for tab, val in pairs(projects) do + if reaper.ValidatePtr(tab, "ReaProject*") then + validTabs[tab] = val + end + end + projects = validTabs + ----clear closed tabs + if currP ~= lastP then + tableSelection = nil --rimuovo selezione quando cambio prog per evitare selezione di traccia inesistente + if projects[currP] then + --tab changed + if not projects[currP].visited then + projects[currP] = {visited = true, links = parseTracks(currP)} + end + + else + --new blank tab opened + projects[currP] = {visited = true, links = {}} + end + + projects[lastP] = {visited = true, links = linkPairs} + linkPairs = projects[currP].links + + --reaper.ShowConsoleMsg("\n"..tprint(projects, 2)) + + lastP = currP + lastPName = currPName + elseif currPName ~= lastPName then + tableSelection = nil --rimuovo selezione quando cambio prog per evitare selezione di traccia inesistente + --opened new project + projects[currP] = {visited = true, links = parseTracks(currP)} + linkPairs = projects[currP].links + + lastPName = currPName + end +end + +--[[ +local function checkForProjectChanges() + local function hashKey(project, name) + return tostring(project) .. name + end + + + + local newProject, newProjectName = reaper.EnumProjects(-1) + + local currProjectHash = hashKey(currProject, currProjectName) + local newProjectHash = hashKey(newProject, newProjectName) + + if currProjectHash ~= newProjectHash then + projectsHash[currProjectHash] = copyTable(linkPairs) + --reaper.ShowConsoleMsg(tprint(projectsHash)) + + if not projectsHash[newProjectHash] then + reaper.ShowConsoleMsg("nuovo prog") + parseTracks() + else + linkPairs = projectsHash[newProjectHash] + end + currProject = newProject + currProjectName = newProjectName + end +end +]] + -- + +function drawLoop() + checkForProjectChanges() + tableView() + buttons() + handleMouse() + checkForSaves() + + --reaper.ShowConsoleMsg(reaper.GetProjectStateChangeCount(reaper.EnumProjects(-1))) + gfx.update() + checkForToggleUi() + + reaper.defer(drawLoop) +end + +setup() +drawLoop() diff --git a/FX/ReaLink/Marini_ReaLink_Toggle_Autostart.lua b/FX/ReaLink/Marini_ReaLink_Toggle_Autostart.lua new file mode 100644 index 000000000..8bbd39c2b --- /dev/null +++ b/FX/ReaLink/Marini_ReaLink_Toggle_Autostart.lua @@ -0,0 +1,81 @@ +-- @noindex + + +local header = [[ + + +-- >>>> ReaLink +-- This code is generated by ReaLink. It should NOT be modified by the user +-- It starts the background synching task on startup automatically +-- If you don't want it, you can delete this block or run the "Marini_ReaLink_Autostart_Toggle" script +]] + +local body = [[ + + +function GetActionCommandIDByFilename(searchfilename) + for k in io.lines(reaper.GetResourcePath() .. "/reaper-kb.ini") do + if k:match("SCR") and k:match(searchfilename) then + return "_" .. k:match("SCR %d+ %d+ (%S*) ") + end + end + return nil +end + +local commands = { GetActionCommandIDByFilename("Marini_ReaLink_Background.lua") +} + +for _, command in ipairs(commands) do + reaper.Main_OnCommand(reaper.NamedCommandLookup(command), -1) +end + +]] + +local trailer = [[ +-- <<<< ReaLink]] + +local startupFile = reaper.GetResourcePath().."/Scripts/__startup.lua" +local read = io.open(startupFile, "r") +local content = "" +if read then + content = read:read("*all") + read:close() +end + +local pattern = "%-%- >>>> ReaLink.*%-%- <<<< ReaLink" + +function removeTrailingNewlines(inputString) + local cleanedString = inputString:gsub("[\r\n]+$", "") + return cleanedString +end + +local function addAutoStartup() + local write = io.open(startupFile, "w") + if not write then return end + if content:match(pattern) then + print("c'è già autostart") + write:write(content) + return + end + write:write(removeTrailingNewlines(content) .. header .. body .. trailer) + write:close() +end + +local function removeAutoStartup() + local write = io.open(startupFile, "w") + if not write then return end + local newContent = content:gsub(pattern, "") + write:write(removeTrailingNewlines(newContent)) + write:close() +end + +local commandID = ({reaper.get_action_context()})[4] +local toggle = reaper.GetToggleCommandState(commandID) == 1 + +if toggle then removeAutoStartup() +else addAutoStartup() end + +reaper.SetToggleCommandState(0,commandID, toggle and 0 or 1) +reaper.RefreshToolbar(commandID) + + diff --git a/FX/ReaLink/Marini_ReaLink_Ui_Toggle.lua b/FX/ReaLink/Marini_ReaLink_Ui_Toggle.lua new file mode 100644 index 000000000..c08c9e07f --- /dev/null +++ b/FX/ReaLink/Marini_ReaLink_Ui_Toggle.lua @@ -0,0 +1,10 @@ +-- @noindex + +local commandID = ({reaper.get_action_context()})[4] +local toggle = reaper.GetToggleCommandState(commandID) == 1 + +reaper.SetToggleCommandState(0,commandID, toggle and 0 or 1) +reaper.RefreshToolbar(commandID) + + + From 24a4efc643caace034aa7131337e8687e628bb2e Mon Sep 17 00:00:00 2001 From: Mattia Date: Sat, 9 Mar 2024 18:18:20 +0100 Subject: [PATCH 2/5] Fixed naming, removed getActionByName and verified Windows support --- FX/.DS_Store | Bin 0 -> 6148 bytes FX/{ReaLink.lua => Marini_FX linker.lua} | 15 +- .../Marini_FX linker background tasks.lua} | 206 +++--------------- .../Marini_FX linker toggle UI.lua} | 3 - .../Marini_FX linker toggle autostart.lua} | 32 +-- 5 files changed, 41 insertions(+), 215 deletions(-) create mode 100644 FX/.DS_Store rename FX/{ReaLink.lua => Marini_FX linker.lua} (55%) rename FX/{ReaLink/Marini_ReaLink_Background.lua => Marini_FX linker/Marini_FX linker background tasks.lua} (69%) rename FX/{ReaLink/Marini_ReaLink_Ui_Toggle.lua => Marini_FX linker/Marini_FX linker toggle UI.lua} (98%) rename FX/{ReaLink/Marini_ReaLink_Toggle_Autostart.lua => Marini_FX linker/Marini_FX linker toggle autostart.lua} (64%) diff --git a/FX/.DS_Store b/FX/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..ad7d52e8c3b5a478a3ec1f90d3d99e0a69d417aa GIT binary patch literal 6148 zcmeHKy-ve05Wa&BkytV^`W5;HrV5CKsS6uWS^;W8s!Hscco0^egOz9EyC14VjRayq z2;E8cch23}=TD05BO;zXEvG~!5fx~HEXs(;=TXyvJ5PYDb3D=mUC|j`QgYj02g$vp z3%a2#a_{F~>v&Bo+SYf|`EA>5dYkz&rfI8cQMU`k6tCwm&#U*hlkcq6w96mGZSMDS z?4=uOFc1s`1HnKruwwvswn%Yg7=17h3I)oAu4 aI{dO@XDGACcMS)|LqG|ME*SU)20j2Av^j$S literal 0 HcmV?d00001 diff --git a/FX/ReaLink.lua b/FX/Marini_FX linker.lua similarity index 55% rename from FX/ReaLink.lua rename to FX/Marini_FX linker.lua index f5bdb1869..50dd19be6 100644 --- a/FX/ReaLink.lua +++ b/FX/Marini_FX linker.lua @@ -3,19 +3,18 @@ @version 1.0 @metapackage @provides - [darwin main] ReaLink/Marini_ReaLink_Background.lua - [darwin main] ReaLink/Marini_ReaLink_Toggle_Autostart.lua - [darwin main] ReaLink/Marini_ReaLink_Ui_Toggle.lua + [main] Marini_FX linker/Marini_FX linker background tasks.lua + [main] Marini_FX linker/Marini_FX linker toggle autostart.lua + [main] Marini_FX linker/Marini_FX linker toggle UI.lua @about ### A GUI based lua script to link FX parameters across different tracks This plugin runs a backgound task that links the selected tracks, ensuring that the plugin configurations of the 2 FX chains match _A full Guide can be found [here](https://github.com/mattia-marini/ReaperLink/blob/main/Guide.pdf)_ - #### Usage: - - Install either from ReaPack or from [this repo](ttps://github.com/mattia-marini/ReaperLink) - - Run _"Marini_Realink_Background"_ or configure automatic startup (see below) - - Toggle Ui with _"Marini_Realink_Toggle_UI"_ to create/remove links + #### Usage: + - Run _"Marini_FX linker background tasks"_ or configure automatic startup (see below) + - Toggle Ui with _"Marini_FX linker toggle UI.lua"_ to create/remove links #### Features: - Linking **every** parameters of **every** plugin across different tracks @@ -26,5 +25,5 @@ - **Zero dependency script** #### Automatic startup: - In order for the script to work, a background task should be running i.e., to make synching happen, you have to run the "Marini_Realink_Background" script every time you open Reaper. To make that happen automatically you can run the "Marini_Realink_Toggle_Autostart". (you can see a script state next to its description in action list. Once set to on, the script will automatically launch on next startup) + In order for the script to work, a background task should be running i.e., to make synching happen, you have to run the "Marini_FX linker background tasks" script every time you open Reaper. To make that happen automatically you can run the "Marini_FX linker toggle autostart". (you can see a script state next to its description in action list. Once set to on, the script will automatically launch on next startup) diff --git a/FX/ReaLink/Marini_ReaLink_Background.lua b/FX/Marini_FX linker/Marini_FX linker background tasks.lua similarity index 69% rename from FX/ReaLink/Marini_ReaLink_Background.lua rename to FX/Marini_FX linker/Marini_FX linker background tasks.lua index 98ef78c46..d6a47b8ac 100644 --- a/FX/ReaLink/Marini_ReaLink_Background.lua +++ b/FX/Marini_FX linker/Marini_FX linker background tasks.lua @@ -1,25 +1,12 @@ -- @noindex -local count = 0 -function GetActionCommandIDByFilename(searchfilename) - for k in io.lines(reaper.GetResourcePath() .. "/reaper-kb.ini") do - if k:match("SCR") and k:match(searchfilename) then - return "_" .. k:match("SCR %d+ %d+ (%S*) ") - end - end - return nil -end - local fontSize = 12 gfx.setfont(1) ---local currProject, currProjectName = reaper.EnumProjects(-1) ---reaper.ShowConsoleMsg(currProject) -local uiToggleCommand = GetActionCommandIDByFilename("Marini_ReaLink_Ui_Toggle.lua") -local uiToggleCommandId = reaper.NamedCommandLookup(uiToggleCommand) +local uiToggleCommandId = reaper.NamedCommandLookup("_RS40fae185eceabce107d514cae993cb3d5e7512c0") reaper.SetToggleCommandState(0, uiToggleCommandId, 0) -local pluginName = "Marini_ReaLink" +local pluginName = "Marini FX Linker" local lastP, lastPName = reaper.EnumProjects(-1) @@ -73,7 +60,6 @@ local function applyDpi(bounds) end end - local function parseTracks(project) local allTracks = {} @@ -93,7 +79,7 @@ local function parseTracks(project) local masterGUID, slaveGUID = string.match(link, "(%S+),"), string.match(link, ",(%S+)") local master, slave = allTracks[masterGUID], allTracks[slaveGUID] - + --reaper.ShowConsoleMsg(masterGUID .. " ".. slaveGUID .. "\n") if master and slave then --reaper.ShowConsoleMsg("carico traccia\n") @@ -105,39 +91,17 @@ local function parseTracks(project) return rv end -local function parseAllTracks() - local p, pname = reaper.EnumProjects(0) - local i = 1 - - while p do - --reaper.ShowConsoleMsg("progetto " .. pname .. "\n") - projects[p] = parseTracks(p) - p, pname = reaper.EnumProjects(i) - i = i + 1 - end - - linkPairs = projects[reaper.EnumProjects(-1)] -end - -function saveState() - --reaper.ShowConsoleMsg( tostring(#linkPairs)) - --reaper.SetProjExtState(0, pluginName, "nLinks", tostring()) +local function saveState() reaper.SetProjExtState(0, pluginName, "", "") --cancella stato reaper.SetProjExtState(0, pluginName, "nLinks", tostring(#linkPairs)) for i, pair in ipairs(linkPairs) do - --reaper.ShowConsoleMsg(tostring(i)) reaper.SetProjExtState(0, pluginName, tostring(i), reaper.GetTrackGUID(pair[1]) .. "," .. reaper.GetTrackGUID(pair[2])) - --reaper.ShowConsoleMsg("{" .. n1 .. "," .. n2 .. "}\n") end - - - --file:close() - --reaper.Main_SaveProject(0, false) end -function tableView() +local function tableView() tableBounds = { x = padding, y = padding, width = gfx.w - 2 * padding, height = gfx.h - 3 * padding - button1H } applyDpi(tableBounds) @@ -232,9 +196,6 @@ function tableView() gfx.rect(0, gfx.h - 2 * padding - button1H, gfx.w, 2 * padding + button1H) end -local function adjustDpi() -end - local function buttons() local button1x, button1y = gfx.w - padding - button1W, gfx.h - padding - button1H local button2x, button2y = button1x - buttonSpacing - button2W, button1y @@ -266,7 +227,6 @@ local function buttons() gfx.drawstr("-", 5, gfx.x + button2W, gfx.y + button2H) end - local function inBounds(bounds) gfx.getchar() local x, y = gfx.mouse_x, gfx.mouse_y @@ -279,7 +239,6 @@ local function inBounds(bounds) end end - local function addSelectedTracks() if reaper.CountSelectedTracks(0) < 2 then reaper.ShowMessageBox("You need to select at lest 2 tracks!", "ReaperLink error", 0) @@ -305,7 +264,6 @@ local function addSelectedTracks() saveState() end - local function removeSelectedLink() if tableSelection then reaper.MarkProjectDirty() @@ -318,9 +276,8 @@ local function removeSelectedLink() saveState() end - local prevClick = 0 -function handleMouse() +local function handleMouse() if gfx.mouse_cap == 1 and prevClick == 0 then @@ -333,14 +290,6 @@ function handleMouse() end elseif inBounds(b1Bounds) then addSelectedTracks() - --reaper.ShowConsoleMsg(tostring(reaper.EnumProjects(-1)) .. " " .. tostring(reaper.EnumProjects(1)) .. "\n") - --[[ - reaper.ShowConsoleMsg("\n") - for key, value in pairs(projectsHash) do - reaper.ShowConsoleMsg(tostring(key) .. "\n") - end - ]] - -- elseif inBounds(b2Bounds) then removeSelectedLink() end @@ -367,14 +316,13 @@ end local prevToggle = reaper.GetToggleCommandState(uiToggleCommandId) local prevChar = gfx.getchar() - local function updateWindowSize() - local d, x, y, w, h = gfx.dock(-1, 0, 0, 0, 0) - if not (x == 0 and y == 0 and w == 0 and h == 0) then - windowSize = { d = d, x = x, y = y, w = w, h = h } - else - windowSize = nil - end + local d, x, y, w, h = gfx.dock(-1, 0, 0, 0, 0) + if not (x == 0 and y == 0 and w == 0 and h == 0) then + windowSize = { d = d, x = x, y = y, w = w, h = h } + else + windowSize = nil + end end local function checkForToggleUi() @@ -392,14 +340,14 @@ local function checkForToggleUi() firstInit = false end elseif toggle == 0 and prevToggle == 1 then - if not firstInit then + if not firstInit then updateWindowSize() end gfx.quit() elseif gfx.getchar() ~= prevChar and gfx.getchar() == -1 then reaper.SetToggleCommandState(0, uiToggleCommandId, 0) reaper.RefreshToolbar(uiToggleCommandId) - if not firstInit then + if not firstInit then updateWindowSize() end end @@ -410,7 +358,6 @@ end reaper.SetToggleCommandState(0, uiToggleCommandId, 0) local prevIsDirty = reaper.IsProjectDirty(0) - local function checkForSaves() local isDirty = reaper.IsProjectDirty(0) if (isDirty == 0) and prevIsDirty == 1 then @@ -420,16 +367,8 @@ local function checkForSaves() end local function quit() - --local file = io.open("/Users/mattia/Desktop/prova.txt", "w") - - --reaper.ShowConsoleMsg("1") - --reaper.SetToggleCommandState(0, uiToggleCommandId, 0) - --reaper.ShowConsoleMsg("\ncarattere:" .. gfx.getchar() .. "\n") local d, x, y, w, h = gfx.dock(-1, 0, 0, 0, 0) if not (x == 0 and y == 0 and w == 0 and h == 0) then - --reaper.ShowConsoleMsg("gui aperta: " .. x .. " " .. y .. " " .. w .. " " .. h .."\n") - --file:write("GUI aperta ") - --file:write(d,x,y,w,h) reaper.SetExtState(pluginName, "dock", d, true) reaper.SetExtState(pluginName, "wndx", x, true) reaper.SetExtState(pluginName, "wndy", y, true) @@ -437,74 +376,19 @@ local function quit() reaper.SetExtState(pluginName, "wndh", h, true) gfx.quit() elseif windowSize then - --reaper.ShowConsoleMsg("gui chiusa: " .. x .. " " .. y .. " " .. w .. " " .. h .."\n") - --reaper.ShowConsoleMsg("3") - --file:write("GUI chiusa") reaper.SetExtState(pluginName, "dock", windowSize.d, true) reaper.SetExtState(pluginName, "wndx", windowSize.x, true) reaper.SetExtState(pluginName, "wndy", windowSize.y, true) reaper.SetExtState(pluginName, "wndw", windowSize.w, true) reaper.SetExtState(pluginName, "wndh", windowSize.h, true) end - --file:close() -end - - -function tprint(tbl, indent) - if not indent then indent = 0 end - local toprint = string.rep(" ", indent) .. "{\r\n" - indent = indent + 2 - for k, v in pairs(tbl) do - toprint = toprint .. string.rep(" ", indent) - if (type(k) == "number") then - toprint = toprint .. "[" .. k .. "] = " - elseif (type(k) == "string") then - toprint = toprint .. k .. "= " - end - if (type(v) == "number") then - toprint = toprint .. v .. ",\r\n" - elseif (type(v) == "string") then - toprint = toprint .. "\"" .. v .. "\",\r\n" - elseif (type(v) == "table") then - toprint = toprint .. tprint(v, indent + 2) .. ",\r\n" - else - toprint = toprint .. "\"" .. tostring(v) .. "\",\r\n" - end - end - toprint = toprint .. string.rep(" ", indent - 2) .. "}" - return toprint -end - -local function copyTable(t) - local res = {} - --reaper.ShowConsoleMsg("\n") - for _, val in ipairs(t) do - table.insert(res, { val[1], val[2] }) - --reaper.ShowConsoleMsg(tostring(val[1]).. " " .. tostring(val[2]) .. "\n") - end - --reaper.ShowConsoleMsg("\n") - return res end ---[[ -local function printTable(t) - --reaper.ShowConsoleMsg(#linkPairs .. "\n") - for _, val in ipairs(t) do - table.insert(res, {val[1], val[2]}) - --reaper.ShowConsoleMsg("{"..tostring(val[1]) .. ", " .. tostring(val[2]) .. "}") - end - reaper.ShowConsoleMsg("\n") -end -]] --- - - - -function loadProjects() +local function loadProjects() local p = reaper.EnumProjects(0) local i = 1 while p do - projects[p] = {visited = false} + projects[p] = { visited = false } p = reaper.EnumProjects(i) i = i + 1 end @@ -512,28 +396,23 @@ end local function setup() gfx.ext_retina = 1 - --parseAllTracks() - --linkPairs=parseTracks(reaper.EnumProjects(-1)) loadProjects() - projects[lastP] = {visited = true, links = parseTracks(lastP)} + projects[lastP] = { visited = true, links = parseTracks(lastP) } linkPairs = projects[lastP].links - d = reaper.GetExtState(pluginName, "dock") - x, y = tonumber(reaper.GetExtState(pluginName, "wndx")), tonumber(reaper.GetExtState(pluginName, "wndy")) - w, h = tonumber(reaper.GetExtState(pluginName, "wndw")), tonumber(reaper.GetExtState(pluginName, "wndh")) + local d = reaper.GetExtState(pluginName, "dock") + local x, y = tonumber(reaper.GetExtState(pluginName, "wndx")), tonumber(reaper.GetExtState(pluginName, "wndy")) + local w, h = tonumber(reaper.GetExtState(pluginName, "wndw")), tonumber(reaper.GetExtState(pluginName, "wndh")) if d and x and y and w and h then windowSize = { d = d, x = x, y = y, w = w, h = h } - --reaper.ShowConsoleMsg("loading from ext: " .. x .. " " .. y .. " " .. w .. " " .. h .."\n") - --reaper.ShowConsoleMsg("loading: " .. windowSize.x .. " " .. windowSize.y .. " " .. windowSize.w .. " " .. windowSize.h .."\n\n") else windowSize = nil end reaper.atexit(quit) end - -function checkForProjectChanges() +local function checkForProjectChanges() local currP, currPName = reaper.EnumProjects(-1) --++clear closed tabs @@ -549,70 +428,39 @@ function checkForProjectChanges() tableSelection = nil --rimuovo selezione quando cambio prog per evitare selezione di traccia inesistente if projects[currP] then --tab changed - if not projects[currP].visited then - projects[currP] = {visited = true, links = parseTracks(currP)} + if not projects[currP].visited then + projects[currP] = { visited = true, links = parseTracks(currP) } end - else --new blank tab opened - projects[currP] = {visited = true, links = {}} + projects[currP] = { visited = true, links = {} } end - projects[lastP] = {visited = true, links = linkPairs} + projects[lastP] = { visited = true, links = linkPairs } linkPairs = projects[currP].links - --reaper.ShowConsoleMsg("\n"..tprint(projects, 2)) lastP = currP lastPName = currPName elseif currPName ~= lastPName then tableSelection = nil --rimuovo selezione quando cambio prog per evitare selezione di traccia inesistente --opened new project - projects[currP] = {visited = true, links = parseTracks(currP)} + projects[currP] = { visited = true, links = parseTracks(currP) } linkPairs = projects[currP].links lastPName = currPName end end ---[[ -local function checkForProjectChanges() - local function hashKey(project, name) - return tostring(project) .. name - end - - - local newProject, newProjectName = reaper.EnumProjects(-1) - - local currProjectHash = hashKey(currProject, currProjectName) - local newProjectHash = hashKey(newProject, newProjectName) - - if currProjectHash ~= newProjectHash then - projectsHash[currProjectHash] = copyTable(linkPairs) - --reaper.ShowConsoleMsg(tprint(projectsHash)) - - if not projectsHash[newProjectHash] then - reaper.ShowConsoleMsg("nuovo prog") - parseTracks() - else - linkPairs = projectsHash[newProjectHash] - end - currProject = newProject - currProjectName = newProjectName - end -end -]] - -- +local function drawLoop() -function drawLoop() checkForProjectChanges() tableView() buttons() handleMouse() checkForSaves() - --reaper.ShowConsoleMsg(reaper.GetProjectStateChangeCount(reaper.EnumProjects(-1))) gfx.update() checkForToggleUi() diff --git a/FX/ReaLink/Marini_ReaLink_Ui_Toggle.lua b/FX/Marini_FX linker/Marini_FX linker toggle UI.lua similarity index 98% rename from FX/ReaLink/Marini_ReaLink_Ui_Toggle.lua rename to FX/Marini_FX linker/Marini_FX linker toggle UI.lua index c08c9e07f..05b4a5cdd 100644 --- a/FX/ReaLink/Marini_ReaLink_Ui_Toggle.lua +++ b/FX/Marini_FX linker/Marini_FX linker toggle UI.lua @@ -5,6 +5,3 @@ local toggle = reaper.GetToggleCommandState(commandID) == 1 reaper.SetToggleCommandState(0,commandID, toggle and 0 or 1) reaper.RefreshToolbar(commandID) - - - diff --git a/FX/ReaLink/Marini_ReaLink_Toggle_Autostart.lua b/FX/Marini_FX linker/Marini_FX linker toggle autostart.lua similarity index 64% rename from FX/ReaLink/Marini_ReaLink_Toggle_Autostart.lua rename to FX/Marini_FX linker/Marini_FX linker toggle autostart.lua index 8bbd39c2b..d0cfc5eb4 100644 --- a/FX/ReaLink/Marini_ReaLink_Toggle_Autostart.lua +++ b/FX/Marini_FX linker/Marini_FX linker toggle autostart.lua @@ -1,38 +1,22 @@ -- @noindex - local header = [[ --- >>>> ReaLink --- This code is generated by ReaLink. It should NOT be modified by the user +-- >>>> Marini FX Linker +-- This code is generated by Marini FX Linker. It should NOT be modified by the user -- It starts the background synching task on startup automatically --- If you don't want it, you can delete this block or run the "Marini_ReaLink_Autostart_Toggle" script +-- If you don't want it, you can delete this block or run the "Marini_FX linker Autostart Toggle" script ]] local body = [[ - -function GetActionCommandIDByFilename(searchfilename) - for k in io.lines(reaper.GetResourcePath() .. "/reaper-kb.ini") do - if k:match("SCR") and k:match(searchfilename) then - return "_" .. k:match("SCR %d+ %d+ (%S*) ") - end - end - return nil -end - -local commands = { GetActionCommandIDByFilename("Marini_ReaLink_Background.lua") -} - -for _, command in ipairs(commands) do - reaper.Main_OnCommand(reaper.NamedCommandLookup(command), -1) -end +reaper.Main_OnCommand(reaper.NamedCommandLookup("_RS010746d83910eb4dc5d6fbc58d2e166ca30e5180"), -1) ]] local trailer = [[ --- <<<< ReaLink]] +-- <<<< Marini FX Linker]] local startupFile = reaper.GetResourcePath().."/Scripts/__startup.lua" local read = io.open(startupFile, "r") @@ -42,9 +26,9 @@ if read then read:close() end -local pattern = "%-%- >>>> ReaLink.*%-%- <<<< ReaLink" +local pattern = "%-%- >>>> Marini FX Linker.*%-%- <<<< Marini FX Linker" -function removeTrailingNewlines(inputString) +local function removeTrailingNewlines(inputString) local cleanedString = inputString:gsub("[\r\n]+$", "") return cleanedString end @@ -77,5 +61,3 @@ else addAutoStartup() end reaper.SetToggleCommandState(0,commandID, toggle and 0 or 1) reaper.RefreshToolbar(commandID) - - From bf272ca7817a24751880c16221b7504d4c5132bb Mon Sep 17 00:00:00 2001 From: Christian Fillion Date: Tue, 12 Mar 2024 01:36:46 -0400 Subject: [PATCH 3/5] add action name to the package name --- FX/Marini_FX linker.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FX/Marini_FX linker.lua b/FX/Marini_FX linker.lua index 50dd19be6..e9179512b 100644 --- a/FX/Marini_FX linker.lua +++ b/FX/Marini_FX linker.lua @@ -1,4 +1,4 @@ -@description Link FX chains of 2 different tracks (GUI) +@description FX linker: Link FX chains of 2 different tracks (GUI) @author Marini Mattia @version 1.0 @metapackage From 96c8b74d7982114787565486aba844e7c785887d Mon Sep 17 00:00:00 2001 From: cfillion Date: Tue, 12 Mar 2024 01:39:07 -0400 Subject: [PATCH 4/5] remove stray .DS_Store file --- FX/.DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 FX/.DS_Store diff --git a/FX/.DS_Store b/FX/.DS_Store deleted file mode 100644 index ad7d52e8c3b5a478a3ec1f90d3d99e0a69d417aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKy-ve05Wa&BkytV^`W5;HrV5CKsS6uWS^;W8s!Hscco0^egOz9EyC14VjRayq z2;E8cch23}=TD05BO;zXEvG~!5fx~HEXs(;=TXyvJ5PYDb3D=mUC|j`QgYj02g$vp z3%a2#a_{F~>v&Bo+SYf|`EA>5dYkz&rfI8cQMU`k6tCwm&#U*hlkcq6w96mGZSMDS z?4=uOFc1s`1HnKruwwvswn%Yg7=17h3I)oAu4 aI{dO@XDGACcMS)|LqG|ME*SU)20j2Av^j$S From a4a2e09a5d9834a08b3174494fd620f2599e5c52 Mon Sep 17 00:00:00 2001 From: Mattia Marini Date: Tue, 19 Mar 2024 10:51:19 +0100 Subject: [PATCH 5/5] remove stray print statement --- FX/Marini_FX linker/Marini_FX linker toggle autostart.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/FX/Marini_FX linker/Marini_FX linker toggle autostart.lua b/FX/Marini_FX linker/Marini_FX linker toggle autostart.lua index d0cfc5eb4..1e6a5881d 100644 --- a/FX/Marini_FX linker/Marini_FX linker toggle autostart.lua +++ b/FX/Marini_FX linker/Marini_FX linker toggle autostart.lua @@ -37,7 +37,6 @@ local function addAutoStartup() local write = io.open(startupFile, "w") if not write then return end if content:match(pattern) then - print("c'è già autostart") write:write(content) return end