From 2fec79da6b473d2552d43ec01df8f6b09b124139 Mon Sep 17 00:00:00 2001
From: PostScriptReal <149461738+PostScriptReal@users.noreply.github.com>
Date: Wed, 14 May 2025 19:02:51 +1000
Subject: [PATCH 1/9] Script interpreter stub
---
interp.py | 43 +++++++++++++++++++++++++++++++++++++++++--
menus.py | 2 +-
2 files changed, 42 insertions(+), 3 deletions(-)
diff --git a/interp.py b/interp.py
index 49192d3..251dea7 100644
--- a/interp.py
+++ b/interp.py
@@ -2,6 +2,7 @@
import jsonc
from tkinter.filedialog import askopenfilename, askdirectory
import os
+from menus import CompMenu, DecompMenu
# Class that gets information from the script header (the lines of text sandwiched inbetween the dashes)
class SSTVer:
@@ -48,7 +49,7 @@ def __init__(self, dat:dict, opt:dict):
# Reader for SST (Snark ScripT) files
class SSTReader:
- def __init__(self, sst:str, opt:dict):
+ def __init__(self, sst:str, opt:dict, logger):
sstf = open(sst, 'r')
scr = sstf.readlines()
count = -1
@@ -71,4 +72,42 @@ def __init__(self, sst:str, opt:dict):
suffix = ""
if parsedSCR["globalOutput"].startswith("askFolder"):
suffix = "(generated path from askFolder)"
- print(f"Global Output Folder: {scrG.globalOut} {suffix}")
\ No newline at end of file
+ print(f"Global Output Folder: {scrG.globalOut} {suffix}")
+
+
+class SSTInterp:
+
+ def __init__(self, logger, dat, globalVs, header):
+ self.logger = logger
+ self.dat = dat
+ self.globalVs = globalVs
+ self.header = header
+ # This variable stores all available tasks and tells the Interpreter how to handle them
+ self.cmds = {
+ # This command is for compiling models
+ "compile": {
+ "func": self.cmpHnd,
+ "args": [["file", "file", ".mdl"], ["output", "folder"]]
+ },
+ # This command is for decompiling models
+ "decompile": {
+ "func": self.dCMPHnd,
+ "args": [["file", "file", ".mdl"], ["output", "folder"]]
+ },
+ "view": {
+ "func": self.hlmvHnd,
+ "args": [["file", "file+task", ".mdl"]]
+ }
+ }
+
+ def cmpHnd(self):
+ # This is a stub for now.
+ pass
+
+ def dCOMPHnd(self):
+ # This is a stub for now.
+ pass
+
+ def hlmvHnd(self):
+ # This is a stub for now.
+ pass
\ No newline at end of file
diff --git a/menus.py b/menus.py
index 14b334b..fec951b 100644
--- a/menus.py
+++ b/menus.py
@@ -1864,7 +1864,7 @@ def __init__(self, template, master, startHidden:bool=False):
def readScript(self):
selected_scr = self.scripts[int(self.scr_list.curselection()[0])]
- a = SSTReader(os.path.join(self.scr_dir, selected_scr), self.options)
+ a = SSTReader(os.path.join(self.scr_dir, selected_scr), self.options, self.console)
def applyTheme(self, master):
style= ttk.Style()
From 4c1e0defe3efe67a587620ea002b405460906f74 Mon Sep 17 00:00:00 2001
From: PostScriptReal <149461738+PostScriptReal@users.noreply.github.com>
Date: Thu, 22 May 2025 15:26:56 +1000
Subject: [PATCH 2/9] Improvements to Console + Script progress
---
helpers.py | 36 +++++++++++++++++++++++++++++++
interp.py | 62 +++++++++++++++++++++++++++++++++++++++++++++++++-----
menus.py | 3 ++-
3 files changed, 95 insertions(+), 6 deletions(-)
diff --git a/helpers.py b/helpers.py
index ed8a64f..ba8d3d7 100644
--- a/helpers.py
+++ b/helpers.py
@@ -21,6 +21,9 @@ def callback(self, opt):
self.command(opt)
self.name.set(self.text)
+"""
+Widget class that displays an output of anything, including terminal outputs or logs, while disallowing the user to edit the output.
+"""
class Console():
def __init__(self, master, startText:str='', columnn=0, roww=0, widthh=100, heightt=20):
@@ -28,18 +31,49 @@ def __init__(self, master, startText:str='', columnn=0, roww=0, widthh=100, heig
self.row = roww
self.width = widthh
self.height = heightt
+ self.lines = []
self.miniTerminal = Text(master, width=self.width, height=self.height)
ys = Scrollbar(master, orient='vertical', command=self.miniTerminal.yview)
self.miniTerminal['yscrollcommand'] = ys.set
self.miniTerminal.insert('1.0', startText)
+ if startText.find("\n") != -1:
+ self.lines = startText.split('\n')
+ else:
+ self.lines.append(startText)
self.miniTerminal['state'] = 'disabled'
+ # Sets the output of the console to something else.
def setOutput(self, replace):
self.miniTerminal['state'] = 'normal'
self.miniTerminal.delete('1.0', 'end')
self.miniTerminal.insert('1.0', replace)
self.miniTerminal['state'] = 'disabled'
+ if replace.find("\n") != -1:
+ self.lines = replace.split('\n')
+ else:
+ self.lines.append(replace)
+
+ # Appends a new line to the bottom of the console.
+ def append(self, e):
+ self.miniTerminal['state'] = 'normal'
+ self.miniTerminal.insert('end', e)
+ self.lines.append(e)
+ self.miniTerminal['state'] = 'disabled'
+
+ # Clears the output completely.
+ def clear(self):
+ self.lines = []
+ self.miniTerminal['state'] = 'normal'
+ self.miniTerminal.delete('1.0', 'end')
+ self.miniTerminal['state'] = 'disabled'
+
+ # Checks if the output is empty and returns true if it is.
+ def isEmpty(self):
+ if len(self.lines) == 0:
+ return True
+ return False
+ # Helper function that formats outputted text generated by the subprocess library to be usable for the class.
def subprocessHelper(self, query):
tOutputTmp = query.split('\n')
tOutputTmp.pop(0)
@@ -57,9 +91,11 @@ def subprocessHelper(self, query):
tOutput += tOutputTmp[count] + '\n'
return tOutput
+ # Show the console
def show(self):
self.miniTerminal.grid(column=self.column, row=self.row, sticky=(N, S, E, W), columnspan=69)
+ # Hide the console
def hide(self):
self.miniTerminal.grid_remove()
diff --git a/interp.py b/interp.py
index 251dea7..db35926 100644
--- a/interp.py
+++ b/interp.py
@@ -2,7 +2,10 @@
import jsonc
from tkinter.filedialog import askopenfilename, askdirectory
import os
+# Importing classes for decompiling and compiling tasks
from menus import CompMenu, DecompMenu
+import sys
+import subprocess
# Class that gets information from the script header (the lines of text sandwiched inbetween the dashes)
class SSTVer:
@@ -49,7 +52,7 @@ def __init__(self, dat:dict, opt:dict):
# Reader for SST (Snark ScripT) files
class SSTReader:
- def __init__(self, sst:str, opt:dict, logger):
+ def __init__(self, sst:str, opt:dict, logger, options:dict):
sstf = open(sst, 'r')
scr = sstf.readlines()
count = -1
@@ -73,15 +76,18 @@ def __init__(self, sst:str, opt:dict, logger):
if parsedSCR["globalOutput"].startswith("askFolder"):
suffix = "(generated path from askFolder)"
print(f"Global Output Folder: {scrG.globalOut} {suffix}")
+ intrp = SSTInterp(logger, parsedSCR["tasks"], scrG, header, options)
class SSTInterp:
- def __init__(self, logger, dat, globalVs, header):
+ def __init__(self, logger, dat, globalVs, header, options):
self.logger = logger
self.dat = dat
self.globalVs = globalVs
self.header = header
+ self.options = options
+ self.tskCnt = 0
# This variable stores all available tasks and tells the Interpreter how to handle them
self.cmds = {
# This command is for compiling models
@@ -99,6 +105,14 @@ def __init__(self, logger, dat, globalVs, header):
"args": [["file", "file+task", ".mdl"]]
}
}
+ logger.append(f"Starting Script \'{globalVs.name}\'")
+
+ def taskToValue(self, tsk:str, grab:str):
+ for t in self.dat:
+ if t["name"] == tsk:
+ return t[grab]
+ # If a value could not be found, return nothing.
+ return None
def cmpHnd(self):
# This is a stub for now.
@@ -108,6 +122,44 @@ def dCOMPHnd(self):
# This is a stub for now.
pass
- def hlmvHnd(self):
- # This is a stub for now.
- pass
\ No newline at end of file
+ def hlmvHnd(self, dat):
+ file = ""
+ genByTask = False
+ if dat["file"].endswith(".mdl"):
+ file = dat["file"]
+ else:
+ file = self.taskToValue(dat["file"], "output")
+ genByTask = True
+
+ if file != None:
+ if not genByTask:
+ self.hlmvTsk(file, False)
+ else:
+ self.hlmvTsk(file, True, dat["file"])
+ else:
+ self.logger.append(f"Error: Couldn't find model generated by compile task \'{dat["file"]}\'")
+ self.logger.append(f"From: view task \'{dat["name"]}\' (index {self.tskCnt})")
+
+ def hlmvTsk(self, f, genByTask:bool, task=""):
+ if genByTask:
+ self.logger.append(f"Viewing model generated by compile task: \'{task}\'")
+ else:
+ self.logger.append(f"Viewing model \'{os.path.basename(f)}\'")
+ # If "Half-Life Asset Manager" is selected
+ if self.options["gsMV"]["selectedMV"] == 1:
+ if sys.platform == "linux":
+ a = subprocess.getoutput(f"XDG_SESSION_TYPE=x11 hlam \"{self.name.get()}\"")
+ else:
+ a = subprocess.getoutput(f"\"C:/Program Files (x86)/Half-Life Asset Manager/hlam.exe\" \"{self.name.get()}\"")
+ # If "Other" option is selected
+ elif self.options["gsMV"]["selectedMV"] > 1:
+ if sys.platform == "linux":
+ path = self.options["gsMV"]["csPath"]
+ path = os.path.expanduser(path)
+ if path.endswith(".exe"):
+ a = subprocess.getoutput(f"wine \"{path}\" \"{self.name.get()}\"")
+ else:
+ a = subprocess.getoutput(f"\"{path}\" \"{self.name.get()}\"")
+ else:
+ path = self.options["gsMV"]["csPath"]
+ a = subprocess.getoutput(f"\"{path}\" \"{self.name.get()}\"")
\ No newline at end of file
diff --git a/menus.py b/menus.py
index fec951b..0f7dd64 100644
--- a/menus.py
+++ b/menus.py
@@ -1847,7 +1847,8 @@ def __init__(self, template, master, startHidden:bool=False):
EXE_LOCATION = os.path.dirname( os.path.realpath( __file__ ) )
self.scr_dir = os.path.join(EXE_LOCATION, "scripts")
for s in os.listdir(self.scr_dir):
- self.scripts.append(s)
+ if not s.startswith("template"):
+ self.scripts.append(s)
self.scr_list = Listbox(master, width=self.widthFix, selectmode=SINGLE)
count = -1
From 52573dd7c0effe1750641776e53d8f50dcbcf360 Mon Sep 17 00:00:00 2001
From: PostScriptReal <149461738+PostScriptReal@users.noreply.github.com>
Date: Thu, 22 May 2025 19:19:39 +1000
Subject: [PATCH 3/9] More script progress
---
GUI.py | 2 +-
interp.py | 12 +++++-------
menus.py | 2 +-
scripts/template.sst | 11 +++++++++--
4 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/GUI.py b/GUI.py
index d366fcd..cb1a34d 100644
--- a/GUI.py
+++ b/GUI.py
@@ -27,7 +27,7 @@ def __init__(self):
self.devMode = False
# Flag specifically for Snark, scripts are currently not implemented yet and is a copy of the scripting system from SMD Tools v1.1
# This will allow me to disable the functionality for it until I come up with a proper implementation
- self.allowScripts = False
+ self.allowScripts = True
# Another flag for Snark, it disables booting to the "games" menu and makes the menu show a "This menu will be completed soon" message
# instead of showing the menu
self.allowGames = True
diff --git a/interp.py b/interp.py
index db35926..483535a 100644
--- a/interp.py
+++ b/interp.py
@@ -2,8 +2,6 @@
import jsonc
from tkinter.filedialog import askopenfilename, askdirectory
import os
-# Importing classes for decompiling and compiling tasks
-from menus import CompMenu, DecompMenu
import sys
import subprocess
@@ -148,18 +146,18 @@ def hlmvTsk(self, f, genByTask:bool, task=""):
# If "Half-Life Asset Manager" is selected
if self.options["gsMV"]["selectedMV"] == 1:
if sys.platform == "linux":
- a = subprocess.getoutput(f"XDG_SESSION_TYPE=x11 hlam \"{self.name.get()}\"")
+ a = subprocess.getoutput(f"XDG_SESSION_TYPE=x11 hlam \"{f}\"")
else:
- a = subprocess.getoutput(f"\"C:/Program Files (x86)/Half-Life Asset Manager/hlam.exe\" \"{self.name.get()}\"")
+ a = subprocess.getoutput(f"\"C:/Program Files (x86)/Half-Life Asset Manager/hlam.exe\" \"{f}\"")
# If "Other" option is selected
elif self.options["gsMV"]["selectedMV"] > 1:
if sys.platform == "linux":
path = self.options["gsMV"]["csPath"]
path = os.path.expanduser(path)
if path.endswith(".exe"):
- a = subprocess.getoutput(f"wine \"{path}\" \"{self.name.get()}\"")
+ a = subprocess.getoutput(f"wine \"{path}\" \"{f}\"")
else:
- a = subprocess.getoutput(f"\"{path}\" \"{self.name.get()}\"")
+ a = subprocess.getoutput(f"\"{path}\" \"{f}\"")
else:
path = self.options["gsMV"]["csPath"]
- a = subprocess.getoutput(f"\"{path}\" \"{self.name.get()}\"")
\ No newline at end of file
+ a = subprocess.getoutput(f"\"{path}\" \"{f}\"")
\ No newline at end of file
diff --git a/menus.py b/menus.py
index 0f7dd64..0e20ea5 100644
--- a/menus.py
+++ b/menus.py
@@ -815,7 +815,7 @@ def __init__(self, template, master, startHidden:bool=False):
self.angleSBtt = ToolTip(self.angleChk, "Overrides the blend angle of vertex normals, Valve recommends keeping this value at 2 (the default) according to the HLSDK docs.", background=thme["tt"], foreground=thme["txt"])
self.angleChkTT = ToolTip(self.hitboxChk, "Dumps hitbox information to the console when enabled.", background=thme["tt"], foreground=thme["txt"])
self.keepBonesChkTT = ToolTip(self.keepBonesChk, "Tells the compiler to keep all bones, including unweighted bones.", background=thme["tt"], foreground=thme["txt"])
- self.ignoreChkTT = ToolTip(self.ignoreChk, "Tells the compiler to ignore all warnings, useful for if you want to quickly test a model that isn't complete yet.", background=thme["tt"], foreground=thme["txt"])
+ self.ignoreChkTT = ToolTip(self.ignoreChk, "Tells the compiler to ignore all warnings, useful for when you want to quickly test a model that isn't complete yet.", background=thme["tt"], foreground=thme["txt"])
self.bNormChkTT = ToolTip(self.bNormChk, "Tags bad normals in the console.", background=thme["tt"], foreground=thme["txt"])
self.flipChkTT = ToolTip(self.flipChk, "Tells the compiler to flip all triangles in the model.", background=thme["tt"], foreground=thme["txt"])
self.groupChkTT = ToolTip(self.groupChk, "Sets the maximum group size for sequences in KB", background=thme["tt"], foreground=thme["txt"])
diff --git a/scripts/template.sst b/scripts/template.sst
index 9cf6370..99dbde3 100644
--- a/scripts/template.sst
+++ b/scripts/template.sst
@@ -15,14 +15,21 @@ format jsonc
"task": "decompile",
"file": "absolute/path/to/mdl/file",
// You can use this key to specify an output folder for this specific task.
- "output": "path/to/output/folder"
+ "output": "path/to/output/folder",
+ // Specify arguments for the decompiler, write them how you would if you were interfacing with it through a terminal
+ // Supported options: -l, -m, -t, -u, -V
+ "args": "-m -t"
},
{
"name": "Compile MDL",
"task": "compile",
"file": "absolute/path/to/qc/file",
// Please note that with compile tasks, the output will not be put in a subfolder of the output folder.
- "output": "path/to/output/folder"
+ "output": "path/to/output/folder",
+ // Specify arguments for the compiler, write them how you would if you were interfacing with it through a terminal
+ // Supported options: -t, -r, -a, -h, -i, -n, -f, -g, -p, -k (only for Sven Co-op's StudioMDL)
+ "args": "-k",
+ "useProfile": "Svengine"
},
{
"name": "View Compiled Model",
From 09d6ac5099e63d2a659be9430950bd9544c53bdb Mon Sep 17 00:00:00 2001
From: PostScriptReal <149461738+PostScriptReal@users.noreply.github.com>
Date: Fri, 23 May 2025 15:51:49 +1000
Subject: [PATCH 4/9] Script Menu improvment + more
---
GUI.py | 2 ++
README.md | 2 +-
interp.py | 36 +++++++++++++++++++++++++-----------
scripts/batch-compile.sst | 3 ++-
scripts/batch-decompile.sst | 3 ++-
scripts/template.sst | 22 ++++++++++++++++------
6 files changed, 48 insertions(+), 20 deletions(-)
diff --git a/GUI.py b/GUI.py
index cb1a34d..959106d 100644
--- a/GUI.py
+++ b/GUI.py
@@ -577,11 +577,13 @@ def changeTheme(self, a):
self.decMenu.changeTheme(thCol)
self.optMenu.changeTheme(thCol)
self.compSetMenu.changeTheme(thCol)
+ self.scrMenu.changeTheme(thCol)
self.setupMenu.master.config(bg=thCol["bg"])
self.cmpMenu.master.config(bg=thCol["bg"])
self.abtMenu.master.config(bg=thCol["bg"])
self.optMenu.master.config(bg=thCol["bg"])
self.compSetMenu.master.config(bg=thCol["bg"])
+ self.scrMenu.master.config(bg=thCol["bg"])
self.frame.config(bg=thCol["bg"])
self.header.config(bg=thCol["bg"])
for w in self.header.winfo_children():
diff --git a/README.md b/README.md
index ca22067..d5cdf04 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,7 @@
In Crowbar, to decompile a model you would have to fiddle around with settings in order to get your model decompiled properly for GoldSRC. With Snark, you don't need to do any extra configuration, just select an MDL file, select the output folder, set the appropriate preset for the compiler used, hit the decompile button and you're set!
+In Crowbar, to decompile a model you would have to fiddle around with settings in order to get your model decompiled properly for GoldSRC. With Snark, you don't need to do any extra configuration, just select an MDL file, select the output folder, set the appropriate preset for the compiler you'd like to use, hit the decompile button and you're set!
On top of that, the compiling GUI includes all the command-line options as toggleable checks with tooltips to tell you what they do, so you don't need to check any sort of documentation, official or unofficial to use the advanced features StudioMDL offers its users.
diff --git a/interp.py b/interp.py
index 483535a..de2d06a 100644
--- a/interp.py
+++ b/interp.py
@@ -4,6 +4,7 @@
import os
import sys
import subprocess
+import yaml
# Class that gets information from the script header (the lines of text sandwiched inbetween the dashes)
class SSTVer:
@@ -35,7 +36,9 @@ class SSTGlobal:
def __init__(self, dat:dict, opt:dict):
self.name = dat["name"]
- self.globalOut = dat["globalOutput"]
+ self.defProf = dat.get("defComp", None)
+ self.defDec = dat.get("defDecPreset", None)
+ self.globalOut = dat.get("globalOutput", None)
if self.globalOut.startswith('askFolder'):
# Getting start directory
startDir = opt["startFolder"]
@@ -54,6 +57,7 @@ def __init__(self, sst:str, opt:dict, logger, options:dict):
sstf = open(sst, 'r')
scr = sstf.readlines()
count = -1
+ error = False
for l in scr:
count += 1
scr[count] = l.replace('\n', '')
@@ -65,16 +69,23 @@ def __init__(self, sst:str, opt:dict, logger, options:dict):
elif header.format == 'json':
print(header.script)
parsedSCR = json.loads(header.script)
- scrG = SSTGlobal(parsedSCR, opt)
- print("Data from SST file: ")
- print(f"Version: {header.version}")
- print(f"Format: {header.format}")
- print(f"Name: {scrG.name}")
- suffix = ""
- if parsedSCR["globalOutput"].startswith("askFolder"):
- suffix = "(generated path from askFolder)"
- print(f"Global Output Folder: {scrG.globalOut} {suffix}")
- intrp = SSTInterp(logger, parsedSCR["tasks"], scrG, header, options)
+ elif header.format == 'yaml' or header.format == 'yml':
+ print(header.script)
+ parsedSCR = yaml.safe_load(header.script)
+ else:
+ logger.append("Fatal error: Format specified in header is not json, jsonc, or yaml/yml.")
+ error = True
+ if not error:
+ scrG = SSTGlobal(parsedSCR, opt)
+ print("Data from SST file: ")
+ print(f"Version: {header.version}")
+ print(f"Format: {header.format}")
+ print(f"Name: {scrG.name}")
+ suffix = ""
+ if parsedSCR["globalOutput"].startswith("askFolder"):
+ suffix = "(generated path from askFolder)"
+ print(f"Global Output Folder: {scrG.globalOut} {suffix}")
+ intrp = SSTInterp(logger, parsedSCR["tasks"], scrG, header, options)
class SSTInterp:
@@ -91,6 +102,8 @@ def __init__(self, logger, dat, globalVs, header, options):
# This command is for compiling models
"compile": {
"func": self.cmpHnd,
+ # First array: Type?, Accepted inputs, Options
+ # Second array:
"args": [["file", "file", ".mdl"], ["output", "folder"]]
},
# This command is for decompiling models
@@ -112,6 +125,7 @@ def taskToValue(self, tsk:str, grab:str):
# If a value could not be found, return nothing.
return None
+ # Functions for each instruction defined in self.cmds
def cmpHnd(self):
# This is a stub for now.
pass
diff --git a/scripts/batch-compile.sst b/scripts/batch-compile.sst
index a78929a..5ff9d9e 100644
--- a/scripts/batch-compile.sst
+++ b/scripts/batch-compile.sst
@@ -4,7 +4,8 @@ format json
-
{
"name": "Batch Compile",
- "globalOutput": "askFolder",
+ "globalOutput": "askFolder,Select a folder full of compilable models",
+ "defComp": "ask",
"tasks": [
{
"name": "Compile MDL",
diff --git a/scripts/batch-decompile.sst b/scripts/batch-decompile.sst
index a7fec6f..4a06b9a 100644
--- a/scripts/batch-decompile.sst
+++ b/scripts/batch-decompile.sst
@@ -4,7 +4,8 @@ format json
-
{
"name": "Batch Decompile",
- "globalOutput": "askFolder,Select a folder full of models",
+ "globalOutput": "askFolder,Select a folder full of compiled models",
+ "defDecPreset": "ask",
"tasks": [
{
"name": "Decompile MDL",
diff --git a/scripts/template.sst b/scripts/template.sst
index 99dbde3..99dd2a7 100644
--- a/scripts/template.sst
+++ b/scripts/template.sst
@@ -4,8 +4,12 @@ format jsonc
-
{
"name": "Template Script",
- // You can specify a global output folder for every task
+ // You can specify a global output folder for every task.
"globalOutput": "path/to/output/folder",
+ // You can also specify a default compiler for the compile task to use,
+ "defComp": "Svengine",
+ // and a default preset for the decompiler to use.
+ "defDecPreset": "Svengine",
"tasks": [
{
// This specifies the name of the task, this will show up in the console when the task has been started.
@@ -16,9 +20,13 @@ format jsonc
"file": "absolute/path/to/mdl/file",
// You can use this key to specify an output folder for this specific task.
"output": "path/to/output/folder",
- // Specify arguments for the decompiler, write them how you would if you were interfacing with it through a terminal
+ // Specify arguments for the decompiler, write them how you would if you were interfacing with it through a terminal.
// Supported options: -l, -m, -t, -u, -V
- "args": "-m -t"
+ // More info for them available on the wiki's Scripting 101 page.
+ "args": "-m -t",
+ // Specify a decompiler preset just for this task, you can do this instead of specifying arguments directly.
+ // Available options are: GoldSRC, Svengine, DoomMusic and Xash3D
+ "usePreset": "Svengine"
},
{
"name": "Compile MDL",
@@ -26,10 +34,12 @@ format jsonc
"file": "absolute/path/to/qc/file",
// Please note that with compile tasks, the output will not be put in a subfolder of the output folder.
"output": "path/to/output/folder",
- // Specify arguments for the compiler, write them how you would if you were interfacing with it through a terminal
- // Supported options: -t, -r, -a, -h, -i, -n, -f, -g, -p, -k (only for Sven Co-op's StudioMDL)
+ // Specify arguments for the compiler, write them how you would if you were interfacing with it through a terminal.
+ // Supported options: -t, -r, -a, -h, -i, -n, -f, -g, -p, -k (only for Sven Co-op's StudioMDL).
+ // More info for them available on the wiki's Scripting 101 page.
"args": "-k",
- "useProfile": "Svengine"
+ // Specify a compiler to use just for this task.
+ "useComp": "Svengine"
},
{
"name": "View Compiled Model",
From 9e7ff4d412f8caf1161ff38090732f8ff9f5164b Mon Sep 17 00:00:00 2001
From: PostScriptReal <149461738+PostScriptReal@users.noreply.github.com>
Date: Thu, 26 Jun 2025 19:20:39 +1000
Subject: [PATCH 5/9] Fix issue with Decompiling on Windows
---
GUI.py | 2 +-
menus.py | 4 ++--
version.txt | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/GUI.py b/GUI.py
index 959106d..dc3773d 100644
--- a/GUI.py
+++ b/GUI.py
@@ -27,7 +27,7 @@ def __init__(self):
self.devMode = False
# Flag specifically for Snark, scripts are currently not implemented yet and is a copy of the scripting system from SMD Tools v1.1
# This will allow me to disable the functionality for it until I come up with a proper implementation
- self.allowScripts = True
+ self.allowScripts = False
# Another flag for Snark, it disables booting to the "games" menu and makes the menu show a "This menu will be completed soon" message
# instead of showing the menu
self.allowGames = True
diff --git a/menus.py b/menus.py
index 0e20ea5..f119ab5 100644
--- a/menus.py
+++ b/menus.py
@@ -647,9 +647,9 @@ def startDecomp(self):
tOutput = subprocess.getoutput(f'./third_party/mdldec -a \"{mdl}\"')
elif sys.platform == 'win32':
if gotArgs:
- tOutput = subprocess.getoutput(f'\"{os.getcwd()}/third_party/mdldec.exe -a {cmdArgs} \" \"{mdl}\"')
+ tOutput = subprocess.getoutput(f'\"{os.getcwd()}/third_party/mdldec.exe\" -a {cmdArgs} \" \"{mdl}\"')
else:
- tOutput = subprocess.getoutput(f'\"{os.getcwd()}/third_party/mdldec.exe -a \" \"{mdl}\"')
+ tOutput = subprocess.getoutput(f'\"{os.getcwd()}/third_party/mdldec.exe\" -a \" \"{mdl}\"')
# I don't have a Mac so I can't compile mdldec to Mac targets :(
# So instead I have to use wine for Mac systems
"""elif sys.platform == 'darwin':
diff --git a/version.txt b/version.txt
index 0b16ff8..824a641 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-v0.2.2-(OS)-alpha
+v0.2.3-(OS)-alpha
From 284aed8a8a3d9a175c09827399e5a3c7c715fb8a Mon Sep 17 00:00:00 2001
From: PostScriptReal <149461738+PostScriptReal@users.noreply.github.com>
Date: Thu, 26 Jun 2025 19:28:06 +1000
Subject: [PATCH 6/9] Github Actions fix
---
.github/workflows/pyinstaller-linux.yml | 1 +
.github/workflows/pyinstaller.yml | 1 +
2 files changed, 2 insertions(+)
diff --git a/.github/workflows/pyinstaller-linux.yml b/.github/workflows/pyinstaller-linux.yml
index 382fbc3..91c0dd1 100644
--- a/.github/workflows/pyinstaller-linux.yml
+++ b/.github/workflows/pyinstaller-linux.yml
@@ -21,6 +21,7 @@ jobs:
pip install pyinstaller
pip install jsoncparser
pip install certifi
+ pip install yaml
- name: Run PyInstaller
run: |
pyinstaller --noconfirm --onedir --console --name "Snark" --add-data "version.txt:." --add-data "activities.txt:." --add-data "logo128.png:." --add-data "icon-win32.ico:." --add-data "icon-linux.png:." --add-data "LICENSE:." --add-data "README.md:." --add-data "save:save/" --add-data "themes:themes/" --add-data "third_party:third_party/" --add-data "images:images/" --add-data "logs:logs/" "GUI.py"
diff --git a/.github/workflows/pyinstaller.yml b/.github/workflows/pyinstaller.yml
index 1b2637c..842af97 100644
--- a/.github/workflows/pyinstaller.yml
+++ b/.github/workflows/pyinstaller.yml
@@ -21,6 +21,7 @@ jobs:
pip install pyinstaller
pip install jsoncparser
pip install certifi
+ pip install yaml
- name: Run PyInstaller
run: |
pyinstaller --noconfirm --onedir --console --name "Snark" --add-data "version.txt:." --add-data "activities.txt:." --add-data "logo128.png:." --add-data "icon-win32.ico:." --add-data "icon-linux.png:." --add-data "LICENSE:." --add-data "README.md:." --add-data "save:save/" --add-data "themes:themes/" --add-data "third_party:third_party/" --add-data "images:images/" --add-data "logs:logs/" "GUI.py"
From 5f1e6dec29fb68a2a020cdd4997ebb2cbd98b43c Mon Sep 17 00:00:00 2001
From: PostScriptReal <149461738+PostScriptReal@users.noreply.github.com>
Date: Thu, 26 Jun 2025 19:30:19 +1000
Subject: [PATCH 7/9] I'm so stupid
---
.github/workflows/pyinstaller-linux.yml | 2 +-
.github/workflows/pyinstaller.yml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/pyinstaller-linux.yml b/.github/workflows/pyinstaller-linux.yml
index 91c0dd1..891933d 100644
--- a/.github/workflows/pyinstaller-linux.yml
+++ b/.github/workflows/pyinstaller-linux.yml
@@ -21,7 +21,7 @@ jobs:
pip install pyinstaller
pip install jsoncparser
pip install certifi
- pip install yaml
+ pip install pyyaml
- name: Run PyInstaller
run: |
pyinstaller --noconfirm --onedir --console --name "Snark" --add-data "version.txt:." --add-data "activities.txt:." --add-data "logo128.png:." --add-data "icon-win32.ico:." --add-data "icon-linux.png:." --add-data "LICENSE:." --add-data "README.md:." --add-data "save:save/" --add-data "themes:themes/" --add-data "third_party:third_party/" --add-data "images:images/" --add-data "logs:logs/" "GUI.py"
diff --git a/.github/workflows/pyinstaller.yml b/.github/workflows/pyinstaller.yml
index 842af97..5a2cc35 100644
--- a/.github/workflows/pyinstaller.yml
+++ b/.github/workflows/pyinstaller.yml
@@ -21,7 +21,7 @@ jobs:
pip install pyinstaller
pip install jsoncparser
pip install certifi
- pip install yaml
+ pip install pyyaml
- name: Run PyInstaller
run: |
pyinstaller --noconfirm --onedir --console --name "Snark" --add-data "version.txt:." --add-data "activities.txt:." --add-data "logo128.png:." --add-data "icon-win32.ico:." --add-data "icon-linux.png:." --add-data "LICENSE:." --add-data "README.md:." --add-data "save:save/" --add-data "themes:themes/" --add-data "third_party:third_party/" --add-data "images:images/" --add-data "logs:logs/" "GUI.py"
From 9cace1b8e8160b4d1ab1076712583d3308dd2a0d Mon Sep 17 00:00:00 2001
From: PostScriptReal <149461738+PostScriptReal@users.noreply.github.com>
Date: Thu, 26 Jun 2025 19:40:53 +1000
Subject: [PATCH 8/9] Windows fix test
---
menus.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/menus.py b/menus.py
index f119ab5..3d0a64c 100644
--- a/menus.py
+++ b/menus.py
@@ -647,9 +647,9 @@ def startDecomp(self):
tOutput = subprocess.getoutput(f'./third_party/mdldec -a \"{mdl}\"')
elif sys.platform == 'win32':
if gotArgs:
- tOutput = subprocess.getoutput(f'\"{os.getcwd()}/third_party/mdldec.exe\" -a {cmdArgs} \" \"{mdl}\"')
+ tOutput = subprocess.getoutput(f'{os.getcwd()}/third_party/mdldec.exe\" -a {cmdArgs} \" \"{mdl}\"')
else:
- tOutput = subprocess.getoutput(f'\"{os.getcwd()}/third_party/mdldec.exe\" -a \" \"{mdl}\"')
+ tOutput = subprocess.getoutput(f'{os.getcwd()}/third_party/mdldec.exe\" -a \" \"{mdl}\"')
# I don't have a Mac so I can't compile mdldec to Mac targets :(
# So instead I have to use wine for Mac systems
"""elif sys.platform == 'darwin':
From 1f698bde1a45c54f37aa7a1a317d93d248d4107f Mon Sep 17 00:00:00 2001
From: PostScriptReal <149461738+PostScriptReal@users.noreply.github.com>
Date: Thu, 26 Jun 2025 19:44:40 +1000
Subject: [PATCH 9/9] Windows fix (hopefully it works this time)
---
menus.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/menus.py b/menus.py
index 3d0a64c..9120ab9 100644
--- a/menus.py
+++ b/menus.py
@@ -647,9 +647,9 @@ def startDecomp(self):
tOutput = subprocess.getoutput(f'./third_party/mdldec -a \"{mdl}\"')
elif sys.platform == 'win32':
if gotArgs:
- tOutput = subprocess.getoutput(f'{os.getcwd()}/third_party/mdldec.exe\" -a {cmdArgs} \" \"{mdl}\"')
+ tOutput = subprocess.getoutput(f'\"{os.getcwd()}/third_party/mdldec.exe\" -a {cmdArgs} \"{mdl}\"')
else:
- tOutput = subprocess.getoutput(f'{os.getcwd()}/third_party/mdldec.exe\" -a \" \"{mdl}\"')
+ tOutput = subprocess.getoutput(f'\"{os.getcwd()}/third_party/mdldec.exe\" -a \"{mdl}\"')
# I don't have a Mac so I can't compile mdldec to Mac targets :(
# So instead I have to use wine for Mac systems
"""elif sys.platform == 'darwin':