This commit is contained in:
Willy-JL
2023-02-02 21:38:45 +00:00
parent 651548913e
commit e33023463a
50 changed files with 336 additions and 256 deletions
+6 -3
View File
@@ -1,12 +1,14 @@
# Flipper Zero SUB-GHZ Playlist Generator
import os
import pip
try:
from easygui import diropenbox
except ImportError:
pip.main(['Install'], "easygui")
pip.main(["Install"], "easygui")
from easygui import diropenbox
def main():
folder_path = diropenbox("Select the folder with Subghz files", "Subghz selector")
output_path = diropenbox("Select your output location", "Output location")
@@ -23,5 +25,6 @@ def main():
playlist_file.close()
print("Done!")
if __name__ == '__main__':
main()
if __name__ == "__main__":
main()
+54 -38
View File
@@ -6,69 +6,85 @@ import os
import sys
def padded_hex(i, l):
given_int = i
given_len = l
hex_result = hex(given_int)[2:] # remove '0x' from beginning of str
hex_result = hex(given_int)[2:] # remove '0x' from beginning of str
num_hex_chars = len(hex_result)
extra_zeros = '0' * (given_len - num_hex_chars) # may not get used..
extra_zeros = "0" * (given_len - num_hex_chars) # may not get used..
return ('0x' + hex_result if num_hex_chars == given_len else
'?' * given_len if num_hex_chars > given_len else
'0x' + extra_zeros + hex_result if num_hex_chars < given_len else
None)
return (
"0x" + hex_result
if num_hex_chars == given_len
else "?" * given_len
if num_hex_chars > given_len
else "0x" + extra_zeros + hex_result
if num_hex_chars < given_len
else None
)
parser = argparse.ArgumentParser(description='Turn cooked Flipper .bm files back into .xbm')
parser.add_argument('infile', metavar='i',
help='Input file')
parser.add_argument('outfile', metavar='o',
help='File to write to')
parser.add_argument('Width', metavar='W', type=int, nargs="?", default="128",
help='Width of the image. Find from meta.txt or directory name')
parser.add_argument('Height', metavar='H', type=int, nargs="?", default="64",
help='Height of the image. Find from meta.txt or directory name')
parser = argparse.ArgumentParser(
description="Turn cooked Flipper .bm files back into .xbm"
)
parser.add_argument("infile", metavar="i", help="Input file")
parser.add_argument("outfile", metavar="o", help="File to write to")
parser.add_argument(
"Width",
metavar="W",
type=int,
nargs="?",
default="128",
help="Width of the image. Find from meta.txt or directory name",
)
parser.add_argument(
"Height",
metavar="H",
type=int,
nargs="?",
default="64",
help="Height of the image. Find from meta.txt or directory name",
)
args = vars(parser.parse_args())
r = open(args["infile"],"rb")
w = open(args["outfile"],"w")
r = open(args["infile"], "rb")
w = open(args["outfile"], "w")
fileStream=r.read()
filename=os.path.splitext(os.path.basename(args["outfile"]))[0]
fileStream = r.read()
filename = os.path.splitext(os.path.basename(args["outfile"]))[0]
imageWidth=args["Width"]
imageHeight=args["Height"]
imageWidth = args["Width"]
imageHeight = args["Height"]
#remove headers and padding
if(fileStream[0:2] == bytes([0x01,0x00])):
unpad=fileStream[4:]
# remove headers and padding
if fileStream[0:2] == bytes([0x01, 0x00]):
unpad = fileStream[4:]
else:
if(fileStream[0:1] == bytes([0x00])):
unpad=fileStream[2:]
if fileStream[0:1] == bytes([0x00]):
unpad = fileStream[2:]
#lzss decompress
# lzss decompress
data_decoded_str = subprocess.check_output(
["heatshrink", "-d","-w8","-l4"], input=unpad
["heatshrink", "-d", "-w8", "-l4"], input=unpad
)
#turn it back into xbm
# turn it back into xbm
b=list(data_decoded_str)
c=', '.join(padded_hex(my_int,2) for my_int in b)
b = list(data_decoded_str)
c = ", ".join(padded_hex(my_int, 2) for my_int in b)
width_out = "#define "+ filename+ "_width "+ str(imageWidth) + "\n"
height_out = "#define "+ filename+ "_height "+ str(imageHeight) + "\n"
bytes_out = "static unsigned char "+ filename+ "_bits[] = {"+ str(c) + "};"
width_out = "#define " + filename + "_width " + str(imageWidth) + "\n"
height_out = "#define " + filename + "_height " + str(imageHeight) + "\n"
bytes_out = "static unsigned char " + filename + "_bits[] = {" + str(c) + "};"
data=width_out+height_out+bytes_out
data = width_out + height_out + bytes_out
w.write(data)
r.close()
w.close()
w.close()
+7 -7
View File
@@ -6,17 +6,17 @@ import os
import sys
parser = argparse.ArgumentParser(description='Turn .xbm files into cooked .bm files for flipper FS')
parser = argparse.ArgumentParser(
description="Turn .xbm files into cooked .bm files for flipper FS"
)
parser.add_argument('infile', metavar='i',
help='Input file')
parser.add_argument('outfile', metavar='o',
help='File to write to')
parser.add_argument("infile", metavar="i", help="Input file")
parser.add_argument("outfile", metavar="o", help="File to write to")
args = vars(parser.parse_args())
r = open(args["infile"],"r")
w = open(args["outfile"],"wb")
r = open(args["infile"], "r")
w = open(args["outfile"], "wb")
output = subprocess.check_output(["cat", args["infile"]])
+53 -31
View File
@@ -5,60 +5,82 @@ import io
import os
import sys
def padded_hex(i, l):
given_int = i
given_len = l
hex_result = hex(given_int)[2:] # remove '0x' from beginning of str
hex_result = hex(given_int)[2:] # remove '0x' from beginning of str
num_hex_chars = len(hex_result)
extra_zeros = '0' * (given_len - num_hex_chars) # may not get used..
extra_zeros = "0" * (given_len - num_hex_chars) # may not get used..
return ('0x' + hex_result if num_hex_chars == given_len else
'?' * given_len if num_hex_chars > given_len else
'0x' + extra_zeros + hex_result if num_hex_chars < given_len else
None)
return (
"0x" + hex_result
if num_hex_chars == given_len
else "?" * given_len
if num_hex_chars > given_len
else "0x" + extra_zeros + hex_result
if num_hex_chars < given_len
else None
)
parser = argparse.ArgumentParser(description='Turn icon char arrays back into .xbm')
parser = argparse.ArgumentParser(description="Turn icon char arrays back into .xbm")
parser.add_argument('infile', metavar='i',
help='Input file')
parser.add_argument('outfile', metavar='o',
help='File to write to')
parser.add_argument('Width', metavar='W', type=int, nargs="?", default="128",
help='Width of the image. Find from meta.txt or directory name')
parser.add_argument('Height', metavar='H', type=int, nargs="?", default="64",
help='Height of the image. Find from meta.txt or directory name')
parser.add_argument('Trim', metavar='T', type=int, nargs="?", default="8",
help='Number of bytes off the start/header to trim. Multiples of 2 required.')
parser.add_argument("infile", metavar="i", help="Input file")
parser.add_argument("outfile", metavar="o", help="File to write to")
parser.add_argument(
"Width",
metavar="W",
type=int,
nargs="?",
default="128",
help="Width of the image. Find from meta.txt or directory name",
)
parser.add_argument(
"Height",
metavar="H",
type=int,
nargs="?",
default="64",
help="Height of the image. Find from meta.txt or directory name",
)
parser.add_argument(
"Trim",
metavar="T",
type=int,
nargs="?",
default="8",
help="Number of bytes off the start/header to trim. Multiples of 2 required.",
)
args = vars(parser.parse_args())
r = open(args["infile"],"r")
w = open(args["outfile"],"w")
imageWidth=args["Width"]
imageHeight=args["Height"]
trimStart=args["Trim"]
r = open(args["infile"], "r")
w = open(args["outfile"], "w")
imageWidth = args["Width"]
imageHeight = args["Height"]
trimStart = args["Trim"]
output = subprocess.check_output(["cat", args["infile"]]) #yes this is terrible.
output = subprocess.check_output(["cat", args["infile"]]) # yes this is terrible.
f = io.StringIO(output.decode().strip())
data = f.read().strip().replace(";","").replace("{","").replace("}","")
data = f.read().strip().replace(";", "").replace("{", "").replace("}", "")
data_str = data.replace(",", "").replace("0x", "")
data_bin = bytearray.fromhex(data_str[trimStart:])
data_decoded_str = subprocess.check_output(
["heatshrink", "-d","-w8","-l4"], input=data_bin
["heatshrink", "-d", "-w8", "-l4"], input=data_bin
)
b=list(data_decoded_str)
b = list(data_decoded_str)
c=', '.join(padded_hex(my_int,2) for my_int in b)
c = ", ".join(padded_hex(my_int, 2) for my_int in b)
width_out = "#define icon_width "+ str(imageWidth) + "\n"
height_out = "#define icon_height "+ str(imageHeight) + "\n"
bytes_out = "static unsigned char icon_bits[] = {"+ str(c) + "};"
width_out = "#define icon_width " + str(imageWidth) + "\n"
height_out = "#define icon_height " + str(imageHeight) + "\n"
bytes_out = "static unsigned char icon_bits[] = {" + str(c) + "};"
data=width_out+height_out+bytes_out
data = width_out + height_out + bytes_out
w.write(data)
r.close()
+48 -31
View File
@@ -5,64 +5,81 @@ import io
import os
import sys
def padded_hex(i, l):
given_int = i
given_len = l
hex_result = hex(given_int)[2:] # remove '0x' from beginning of str
hex_result = hex(given_int)[2:] # remove '0x' from beginning of str
num_hex_chars = len(hex_result)
extra_zeros = '0' * (given_len - num_hex_chars) # may not get used..
extra_zeros = "0" * (given_len - num_hex_chars) # may not get used..
return ('0x' + hex_result if num_hex_chars == given_len else
'?' * given_len if num_hex_chars > given_len else
'0x' + extra_zeros + hex_result if num_hex_chars < given_len else
None)
return (
"0x" + hex_result
if num_hex_chars == given_len
else "?" * given_len
if num_hex_chars > given_len
else "0x" + extra_zeros + hex_result
if num_hex_chars < given_len
else None
)
parser = argparse.ArgumentParser(description='Turn icon char arrays back into .xbm')
parser = argparse.ArgumentParser(description="Turn icon char arrays back into .xbm")
parser.add_argument('infile', metavar='i',
help='Input file')
parser.add_argument('Width', metavar='W', type=int, nargs="?", default="128",
help='Width of the image. Find from meta.txt or directory name')
parser.add_argument('Height', metavar='H', type=int, nargs="?", default="64",
help='Height of the image. Find from meta.txt or directory name')
parser.add_argument("infile", metavar="i", help="Input file")
parser.add_argument(
"Width",
metavar="W",
type=int,
nargs="?",
default="128",
help="Width of the image. Find from meta.txt or directory name",
)
parser.add_argument(
"Height",
metavar="H",
type=int,
nargs="?",
default="64",
help="Height of the image. Find from meta.txt or directory name",
)
args = vars(parser.parse_args())
r = open(args["infile"],"r")
infile=args["infile"].split(".")[0]
r = open(args["infile"], "r")
infile = args["infile"].split(".")[0]
imageWidth=args["Width"]
imageHeight=args["Height"]
dims=str(imageWidth)+"x"+str(imageHeight)
imageWidth = args["Width"]
imageHeight = args["Height"]
dims = str(imageWidth) + "x" + str(imageHeight)
output = subprocess.check_output(["cat", args["infile"]]) #yes this is terrible.
output = subprocess.check_output(["cat", args["infile"]]) # yes this is terrible.
f = io.StringIO(output.decode().strip())
data = f.read().strip().replace(";","").replace("{","").replace("}","")
data = f.read().strip().replace(";", "").replace("{", "").replace("}", "")
data_str = data.replace(",", "").replace("0x", "")
data_bin = bytearray.fromhex(data_str)
data_encoded_str = subprocess.check_output(
["heatshrink", "-e","-w8","-l4"], input=data_bin
["heatshrink", "-e", "-w8", "-l4"], input=data_bin
)
b=list(data_encoded_str)
b = list(data_encoded_str)
c=','.join(padded_hex(my_int,2) for my_int in b)
c = ",".join(padded_hex(my_int, 2) for my_int in b)
# a bit ugly.
framename="_I_"+infile+"_"+dims
framename = "_I_" + infile + "_" + dims
print(len(b))
#d=len(b)
# d=len(b)
# if b > 255 split 0x1234 into 0x34,0x12
#d=hex(len(b))
# d=hex(len(b))
char_out = "const uint8_t "+framename+"_0[] = {"+ str(c) + ",};"
char_out2 = "const uint8_t "+framename+"[] = {"+framename+"_0};"
#data=bytes_out
char_out = "const uint8_t " + framename + "_0[] = {" + str(c) + ",};"
char_out2 = "const uint8_t " + framename + "[] = {" + framename + "_0};"
# data=bytes_out
print(char_out)
print(char_out2)
#w.write(data)
#w.close()
# w.write(data)
# w.close()
+16 -9
View File
@@ -43,7 +43,9 @@ def convert_bmx(img: "Image.Image | pathlib.Path") -> bytes:
return data
def pack(input: "str | pathlib.Path", output: "str | pathlib.Path", logger: typing.Callable):
def pack(
input: "str | pathlib.Path", output: "str | pathlib.Path", logger: typing.Callable
):
input = pathlib.Path(input)
output = pathlib.Path(output)
output.mkdir(parents=True, exist_ok=True)
@@ -68,7 +70,9 @@ def pack(input: "str | pathlib.Path", output: "str | pathlib.Path", logger: typi
if (source / "Anims/manifest.txt").exists():
(packed / "Anims").mkdir(parents=True, exist_ok=True)
shutil.copyfile(source / "Anims/manifest.txt", packed / "Anims/manifest.txt")
shutil.copyfile(
source / "Anims/manifest.txt", packed / "Anims/manifest.txt"
)
for anim in (source / "Anims").iterdir():
if not anim.is_dir():
continue
@@ -77,9 +81,13 @@ def pack(input: "str | pathlib.Path", output: "str | pathlib.Path", logger: typi
if not frame.is_file():
continue
if frame.name == "meta.txt":
shutil.copyfile(frame, packed / "Anims" / anim.name / "meta.txt")
shutil.copyfile(
frame, packed / "Anims" / anim.name / "meta.txt"
)
elif frame.name.startswith("frame_"):
(packed / "Anims" / anim.name / frame.with_suffix(".bm").name).write_bytes(convert_bm(frame))
(
packed / "Anims" / anim.name / frame.with_suffix(".bm").name
).write_bytes(convert_bm(frame))
if (source / "Icons").is_dir():
for icons in (source / "Icons").iterdir():
@@ -89,7 +97,9 @@ def pack(input: "str | pathlib.Path", output: "str | pathlib.Path", logger: typi
for icon in icons.iterdir():
if not icon.is_file():
continue
(packed / "Icons" / icons.name / icon.with_suffix(".bmx").name).write_bytes(convert_bmx(icon))
(
packed / "Icons" / icons.name / icon.with_suffix(".bmx").name
).write_bytes(convert_bmx(icon))
if __name__ == "__main__":
@@ -105,7 +115,4 @@ if __name__ == "__main__":
pack(here, here / "dolphin_custom", logger=print)
end = time.perf_counter()
input(
f"\nFinished in {round(end - start, 2)}s\n"
"Press [Enter] to exit"
)
input(f"\nFinished in {round(end - start, 2)}s\n" "Press [Enter] to exit")
+28 -10
View File
@@ -30,11 +30,16 @@ valid_dirs = list()
# This will not stay, dont worry! This is temp code until we got time to rewrite this all
root_dir = pathlib.Path(__file__).absolute().parent.parent
dolphin_external = root_dir / "assets/dolphin/external/"
potential_directories = [item for item in dolphin_external.iterdir() if item.is_dir()] # Get all animation directories
potential_directories = [
item for item in dolphin_external.iterdir() if item.is_dir()
] # Get all animation directories
for directory in potential_directories: # loop through all of them
if (
directory / "manifest.txt"
).exists(): # check if they contain a manifest.txt TODO: This code should be moved to wherever manifest.txt files are validated!
valid_dirs.append(directory) # append valid directory to list
for directory in potential_directories: # loop through all of them
if (directory / "manifest.txt").exists(): # check if they contain a manifest.txt TODO: This code should be moved to wherever manifest.txt files are validated!
valid_dirs.append(directory) # append valid directory to list
class Main(App):
def init(self):
@@ -259,13 +264,24 @@ class Main(App):
self.logger.info("Manifest is up-to-date!")
# This will not stay, dont worry! This is temp code until we got time to rewrite this all
global valid_dirs # access our global variable
for valid_dir in valid_dirs: # We can copy the manifest for all of the valid dirs!
(root_dir / f"assets/resources/dolphin/{valid_dir.name}").mkdir(parents=True, exist_ok=True)
shutil.copyfile(valid_dir / "manifest.txt", root_dir / f"assets/resources/dolphin/{valid_dir.name}/manifest.txt")
global valid_dirs # access our global variable
for (
valid_dir
) in valid_dirs: # We can copy the manifest for all of the valid dirs!
(root_dir / f"assets/resources/dolphin/{valid_dir.name}").mkdir(
parents=True, exist_ok=True
)
shutil.copyfile(
valid_dir / "manifest.txt",
root_dir / f"assets/resources/dolphin/{valid_dir.name}/manifest.txt",
)
(root_dir / "assets/resources/dolphin/manifest.txt").unlink()
self.logger.info("Packing custom asset packs")
asset_packer.pack(root_dir / "assets/dolphin/custom", root_dir / f"assets/resources/dolphin_custom", self.logger.info)
asset_packer.pack(
root_dir / "assets/dolphin/custom",
root_dir / f"assets/resources/dolphin_custom",
self.logger.info,
)
self.logger.info(f"Complete")
@@ -295,7 +311,9 @@ class Main(App):
self.logger.info(f"Processing Dolphin sources")
dolphin = Dolphin()
self.logger.info(f"Loading data")
if f"dolphin{os.sep}external" in str(self.args.input_directory): # AHEM... oopsie. This script apparently just loads all assets, not only external assets, lol.
if f"dolphin{os.sep}external" in str(
self.args.input_directory
): # AHEM... oopsie. This script apparently just loads all assets, not only external assets, lol.
dolphin.load(self.args.input_directory, valid_dirs)
else:
dolphin.load(self.args.input_directory)
+11 -3
View File
@@ -35,7 +35,7 @@ class DolphinBubbleAnimation:
min_level: int,
max_level: int,
weight: int,
subpath: str = None
subpath: str = None,
):
# Manifest
self.name = name
@@ -188,7 +188,9 @@ class DolphinBubbleAnimation:
def save(self, output_directory: str):
if self.subpath:
animation_directory = os.path.join(output_directory, self.subpath, self.name)
animation_directory = os.path.join(
output_directory, self.subpath, self.name
)
else:
animation_directory = os.path.join(output_directory, self.name)
os.makedirs(animation_directory, exist_ok=True)
@@ -294,7 +296,13 @@ class DolphinManifest:
# Initialize animation
animation = DolphinBubbleAnimation(
name, min_butthurt, max_butthurt, min_level, max_level, weight, subpath
name,
min_butthurt,
max_butthurt,
min_level,
max_level,
weight,
subpath,
)
# Load Animation meta and frames
+1 -1
View File
@@ -103,4 +103,4 @@ class Main(App):
if __name__ == "__main__":
Main()()
Main()()
+7 -5
View File
@@ -166,11 +166,13 @@ class Main(App):
)
)
bundle_args.extend(self.other_args)
log_custom_fz_name = (
environ.get("CUSTOM_FLIPPER_NAME", None)
or ""
)
if (log_custom_fz_name != "") and (len(log_custom_fz_name) <= 8) and (log_custom_fz_name.isalnum()) and (log_custom_fz_name.isascii()):
log_custom_fz_name = environ.get("CUSTOM_FLIPPER_NAME", None) or ""
if (
(log_custom_fz_name != "")
and (len(log_custom_fz_name) <= 8)
and (log_custom_fz_name.isalnum())
and (log_custom_fz_name.isascii())
):
self.logger.info(
f"Flipper Custom Name is set:\n\tName: {log_custom_fz_name} : length - {len(log_custom_fz_name)} chars"
)
+14 -11
View File
@@ -11,7 +11,11 @@ from datetime import date, datetime
class GitVersion:
def __init__(self, source_dir):
self.source_dir = source_dir
self.gitlist = [("commit", "rev-parse --short HEAD"), ("branch", "rev-parse --abbrev-ref") , ("branch_num", "rev-list -count HEAD")]
self.gitlist = [
("commit", "rev-parse --short HEAD"),
("branch", "rev-parse --abbrev-ref"),
("branch_num", "rev-list -count HEAD"),
]
def get_version_info(self):
commit = branch = branch_num = "XFW-0040"
@@ -36,20 +40,19 @@ class GitVersion:
# If WORKFLOW_BRANCH_OR_TAG is set in environment, is has precedence
# (set by CI)
custom_fz_name = (
os.environ.get("CUSTOM_FLIPPER_NAME", None)
or ""
)
custom_fz_name = os.environ.get("CUSTOM_FLIPPER_NAME", None) or ""
force_no_dirty = (
os.environ.get("FORCE_NO_DIRTY", None)
or ""
)
force_no_dirty = os.environ.get("FORCE_NO_DIRTY", None) or ""
if (force_no_dirty != ""):
if force_no_dirty != "":
dirty = False
if (custom_fz_name != "") and (len(custom_fz_name) <= 8) and (custom_fz_name.isalnum()) and (custom_fz_name.isascii()):
if (
(custom_fz_name != "")
and (len(custom_fz_name) <= 8)
and (custom_fz_name.isalnum())
and (custom_fz_name.isascii())
):
return {
"GIT_COMMIT": commit,
"GIT_BRANCH": "dev",