import sys sys.dont_write_bytecode = True import mtTkinter as tk from tkinter import ttk as tkk from tkinter import messagebox from tkinter import filedialog import copy import hashengine global LH if __name__ == "__main__": import PCPL import langsys PCPL.interpreter.ENG = hashengine LH = langsys.langhandler() lang = open("clang", 'r') lang = lang.read() LH.setlang(lang) # LH.string("") else: class rLH: def __init__(self): pass def string(self, target): return target LH = rLH() import ast import subprocess import sys import time import shutil import os import random import string import easygui import base64 import simpleaudio as sa import multiprocessing global gamedata global cooldown cooldown = False gamedata = {} def prepgamedata(): out = [] tempwin = tk.Tk() bar = tkk.Progressbar(tempwin) bar.place(width=200) ptext = tk.Label(tempwin, text="NONE") ptext.place() count = 1 for i in gamedata: i = gamedata[i] ptext.config(text=i["name"]) bar.step(count/len(gamedata)) count += 1 tempwin.update() temp = {"id": i["id"], "name": i["name"]} tempargs = {} tosearch = {} for arg in i["args"]: if not arg in extypes and not arg in ignoreat and arg != "sdata": tosearch[arg] = i["args"][arg] continue if arg in ignoreat and arg != "sdata": continue if arg != "sdata": tempargs[arg] = i["args"][arg] else: tempargs[arg] = str(base64.b64encode(i["args"][arg]), "ascii", "ignore") for argname in tosearch: arg = tosearch[argname] temp2 = getattributes(arg) temp2.update({"ARGID": arg._type}) tempargs[argname] = temp2 temp["args"] = tempargs out.append(temp) tempwin.destroy() return out class script: def __init__(self): self.code = "" def execute(self, API): #old code for PCPL code execution, replaced with python code execution """ PCPL.resetvar() PCPL.LIS("HASHBASE") PCPL.run(self.code)""" exec(self.code, API) class previewrend: def __init__(self, size, cam, container, offset): self._size = size self._grid = {} self._win = container self._frame = tk.Frame(container) self._posframe = tk.Frame(self._frame) self._cam = cam self._xcam = tk.Label(self._posframe, text="-") self._ycam = tk.Label(self._posframe, text="-") self._xcam.grid(row=size[1], column=0) self._ycam.grid(row=size[1]+1, column=0) tkeys = list(string.ascii_letters) self._keys = {} for i in tkeys: self._keys[i] = False self._win.bind("", self.keypupd) self._win.bind("", self.keydupd) for y in range(size[1]): for x in range(size[0]): temp = tk.Label(self._frame, text=" ", borderwidth=1, relief=tk.GROOVE, width=3) temp.grid(row=y+offset[1], column=x+offset[0]+1) self._win.update() self._grid[f"{x}:{y}"] = temp self._posframe.grid() self._frame.grid() def keypupd(self, event): event = event.char if event in self._keys: self._keys[event] = True def keydupd(self, event): event = event.char if event in self._keys: self._keys[event] = False def getkeys(self): return self._keys def coltohex(self, target): colors = [] target = [target.r, target.g, target.b] for i in target: colors.append(("0"*(2-len(hex(int(i))[2:])))+hex(i)[2:]) out = "" for i in colors: out = out + i return "#"+out def update(self): self._win.update() def pix(self, x, y, text, bcolor, fcolor): self._xcam.config(text=LH.string("xcam")+str(self._cam.position.x)) self._ycam.config(text=LH.string("ycam")+str(self._cam.position.y)) if f"{x}:{y}" in self._grid: self._grid[f"{x}:{y}"].config(text=text, bg=self.coltohex(bcolor), fg=self.coltohex(fcolor)) class render: def __init__(self, size, cam, container, offset): self._size = size self._grid = {} self._win = container self._frame = tk.Frame(container) self._posframe = tk.Frame(self._frame) self._cam = cam self._xcam = tk.Label(self._posframe, text="-") self._ycam = tk.Label(self._posframe, text="-") #self._xcam.grid(row=size[1], column=0) #self._ycam.grid(row=size[1]+1, column=0) tkeys = list(string.ascii_letters) self._keys = {} for i in tkeys: self._keys[i] = False self._win.bind("", self.keypupd) self._win.bind("", self.keydupd) for y in range(size[1]): for x in range(size[0]): temp = tk.Label(self._frame, text=" ", width=3) temp.grid(row=y+offset[1], column=x+offset[0]+1) self._win.update() self._grid[f"{x}:{y}"] = temp self._posframe.grid() self._frame.grid() def keypupd(self, event): event = event.char if event in self._keys: self._keys[event] = True def keydupd(self, event): event = event.char if event in self._keys: self._keys[event] = False def getkeys(self): return self._keys def coltohex(self, target): colors = [] target = [target.r, target.g, target.b] for i in target: colors.append(("0"*(2-len(hex(int(i))[2:])))+hex(i)[2:]) out = "" for i in colors: out = out + i return "#"+out def update(self): self._win.update() def pix(self, x, y, text, bcolor, fcolor): self._xcam.config(text=LH.string("xcam")+str(self._cam.position.x)) self._ycam.config(text=LH.string("ycam")+str(self._cam.position.y)) if f"{x}:{y}" in self._grid: self._grid[f"{x}:{y}"].config(text=text, bg=self.coltohex(bcolor), fg=self.coltohex(fcolor)) class nullrend: def __init__(self, size, cam): pass def getkeys(self): pass def update(self): pass def pix(self, x, y, text, bcolor, fcolor): pass def selectlang(new): lang = open("clang", 'w') lang.write(new) lang.close() container.quit() subprocess.Popen([sys.executable, __file__]) def add(objtype): global objtree obj = getattr(types, objtype)() args = {} for i in dir(obj): if i.startswith("_"): continue args[i] = getattr(obj, i) temp = {"id": objtype, "args": args, "name": LH.string(objtype)} id = "" chars = list(string.ascii_letters) for i in range(255): id = id + random.choice(chars) if GUIe == True: objtree.insert("", tk.END, text=LH.string(objtype), image=icons[objtype], iid=id, tags=("objsel")) gamedata[id] = temp if objtype in crucial: preview.addobj(obj) gamedata[id]["args"]["ID"] = obj.ID if GUIe == True: preview.render() return id def renameobj(): target = objtree.focus() if target == "": return new = easygui.enterbox(LH.string("NN"), LH.string("rename")) if new: objtree.item(target, text=new) gamedata[target]["name"] = new def delobj(): target = objtree.focus() if target == "": return atritree.delete(*atritree.get_children()) objtree.delete(target) temp = gamedata.pop(target) if temp["id"] in crucial: preview.removeobjbyid(temp["args"]["ID"]) preview.render() def rpopup(event): try: rmenu.tk_popup(event.x_root, event.y_root) finally: rmenu.grab_release() def getattributes(target): out = {} for i in dir(target): if i.startswith("_"): continue out[i] = getattr(target, i) return out def updatribute(event): global currentat target = objtree.focus() currentat = target atritree.delete(*atritree.get_children()) for i in gamedata[target]["args"]: if i in ignoreat: continue if i in valtypes: val = gamedata[target]["args"][i] atritree.insert("", tk.END, text=i, values=(val)) else: root = atritree.insert("", tk.END, text=i) temp = getattributes(gamedata[target]["args"][i]) for f in temp: atritree.insert(root, tk.END, text=f, values=(temp[f])) def halatribute(event): target = atritree.focus() name = atritree.item(target, "text") parent = atritree.parent(target) if name in valtypes: if parent == "": new = valtypes[name](gamedata[currentat]["args"][name]) gamedata[currentat]["args"][name] = new if "ID" in gamedata[currentat]["args"]: temp = preview.getobjbyid(gamedata[currentat]["args"]["ID"]) setattr(temp, name, new) atritree.item(target, values=(new)) else: parent = atritree.item(parent, "text") new = valtypes[name](getattr(gamedata[currentat]["args"][parent], name)) setattr(gamedata[currentat]["args"][parent], name, new) atritree.item(target, values=(new)) preview.render() def updatepreviewcam(char): global cooldown if cooldown == True: return cooldown = True char = char.char if char == "w": preview.camera.position += hashengine.vector2(y=1) if char == "a": preview.camera.position += hashengine.vector2(x=1) if char == "s": preview.camera.position -= hashengine.vector2(y=1) if char == "d": preview.camera.position -= hashengine.vector2(x=1) preview.render() time.sleep(0) cooldown = False def save(): target = filedialog.asksaveasfile() target.write(str(prepgamedata())) target.close() messagebox.showinfo(LH.string("suc"), LH.string("save-suc")) def clear(): global gamedata objtree.delete(*objtree.get_children()) atritree.delete(*atritree.get_children()) gamedata = {} preview._objects = {} preview.camera.position = hashengine.vector2() preview.render() def importsound(target): oid = add("rawsound") gamedata[oid]["name"] = target["name"] gamedata[oid]["args"]["sdata"] = base64.b64decode(target["args"]["sdata"]) gamedata[oid]["args"]["spath"] = target["args"]["spath"] if GUIe == True: objtree.item(oid, text=target["name"]) def importobj(target): if target["id"] == "sound" or target["id"] == "rawsound": importsound(target) return oid = add(target["id"]) id = gamedata[oid] id["name"] = target["name"] if GUIe == True: objtree.item(oid, text=target["name"]) #create arguments outargs = {} for argname in target["args"]: arg = target["args"][argname] if isinstance(arg, dict): ID = arg.pop("ARGID") obj = attypes[ID]() for i in arg: setattr(obj, i, arg[i]) arg = obj outargs[argname] = arg #apply arguments to obj if target["id"] in crucial: for i in outargs: setattr(preview.getobjbyid(gamedata[oid]["args"]["ID"]), i, outargs[i]) id["args"].update(outargs) def load(): file = filedialog.askopenfile() tempwin = tk.Tk() ptext = tk.Label(tempwin, text="NONE") ptext.place(y=30) stat = tk.Label(tempwin, text="NONE") stat.place(y=50) target = file.read() file.close() target = ast.literal_eval(target) clear() count = 1 bar = tkk.Progressbar(tempwin, maximum=len(target)) bar.place(width=200) for i in target: ptext.config(text="Current: "+i["name"]) bar.step() stat.config(text=f"Object {count}/{len(target)}") tempwin.update() importobj(i) count += 1 tempwin.destroy() preview.render() def log(text, end="\n", flush=False): global logfile if not os.path.exists("logs"): os.mkdir("logs") file = open("logs/"+logfile+".txt", 'a') file.write(str(text)+end) file.close() def NULL(): pass class gsound: def __init__(self, data, game): self._playing = False self._data = data game.currentsounds.append(self) def play(self): if self._playing == True: return self._sound = sa.play_buffer(self._data, 2, 2, 44100) self._playing = True def stop(self): if self._playing == False: return self._sound.stop() self._playing = False def wait(self): if self._playing == False: return self._sound.wait_done() def testing(): global testproc testproc = multiprocessing.Process(target=execgame, args=(prepgamedata(),)) testproc.start() def run(): print("preparing log file...") global logfile global maingame global window temp = time.gmtime(time.time()) logfile = "" for i in temp: logfile = logfile + "S" + str(i) print("done") log("Log file start!") log("Preparing API...") API = {"print": log, "HASHBASE": hashengine} log("Done!") window = tk.Tk() window.protocol("WM_DELETE_WINDOW", NULL) maingame = hashengine.game(renderer=lambda size, cam: render(size, cam, window, [0, 0]), sounddir="/") API["HASHGAME"] = maingame API["SOUND"] = lambda data: gsound(data, maingame) log("main game initalised!") log("copying sounds...") for i in gamedata: i = gamedata[i] if i["id"] != "sound" and i["id"] != "rawsound": continue maingame.sounds[i["args"]["spath"]] = i["args"]["sdata"] print(i["args"]["spath"]) objects = copy.deepcopy(preview._objects) maingame._objects = objects scripts = [] for i in gamedata: i = gamedata[i] if i["id"] != "script": continue i = i["args"]["code"] obj = script() obj.code = i scripts.append(obj) log("objects transferred!") gamescript = """ global HASHGAME import time while True: for i in HASHGAME._objects: i = HASHGAME._objects[i] HASHGAME.calcphysobj(i) HASHGAME.render() """ gameloopsc = script() gameloopsc.code = gamescript maingame.startscript(lambda: gameloopsc.execute(API)) log("game test started!!!") log("---------------------") for i in scripts: maingame.startscript(lambda: i.execute(API)) window.mainloop() def muladd(target): for i in range(10): add(target) def stoptest(): global testproc testproc.terminate() def build(): print("asking user for output directory...") target = filedialog.askdirectory() os.mkdir(target+"/out") target = target+"/out" print("building started") print("generating HEGF file...") hegf = str(prepgamedata()) file = open(target+"/game.HEGF", 'w') file.write(hegf) file.close() print("done.") print("copying files...") tocopy = ["mtTkinter.py", "hashengine.py"] for i in tocopy: print(f"copying {i}...") shutil.copyfile(i, target+"/"+i) shutil.copyfile(__file__, target+"/"+"player.py") file = open(target+"/main.py", 'w') file.write(""" import player import ast file = open("game.HEGF", 'r') file = file.read() file = ast.literal_eval(file) player.execgame(file) """) print("done.") print("building finished!") def GUIinit(): global container global objtree global rmenu global atritree global currentat global preview global GUIe GUIe = True container = tk.Tk() container.bind("", updatepreviewcam) global icons icons = {} for i in os.listdir("icons"): icons[i.split(".")[0]] = tk.PhotoImage(file=f"icons/{i}") #preview init preview = hashengine.game(renderer=lambda size, cam: previewrend(size, cam, container=container, offset=[0, 0]), sounddir="/") #tree init objtree = tkk.Treeview(container, selectmode="browse", columns=("-")) objtree.heading("#0", text=LH.string("objs")) objtree.tag_bind("objsel", "<>", updatribute) objtree.grid(row=1, column=0) #attribute tree init currentat = "temp" atritree = tkk.Treeview(container, columns=("#1"), selectmode="browse") atritree.heading("#0", text=LH.string("attribute")) atritree.heading("#1", text=LH.string("attribute-val")) atritree.bind("", halatribute) atritree.grid(row=2, column=0) #right click menu rmenu = tk.Menu(container, tearoff=0) rmenu.add_command(label=LH.string("rename"), command=renameobj) rmenu.add_command(label=LH.string("delete"), command=delobj) objtree.bind("", rpopup) #menu init menu = tk.Menu(container) container.config(menu=menu) filemenu = tk.Menu(menu) menu.add_cascade(label=LH.string("file"), menu=filemenu) filemenu.add_command(label=LH.string("new"), command=clear) filemenu.add_command(label=LH.string("open"), command=load) filemenu.add_command(label=LH.string("save"), command=save) filemenu.add_separator() filemenu.add_command(label=LH.string("exit"), command=container.quit) addmenu = tk.Menu(menu) menu.add_cascade(label=LH.string("add"), menu=addmenu) addmenu.add_command(label=LH.string("obj"), command=lambda: add("obj")) addmenu.add_command(label=LH.string("script"), command=lambda: add("script")) addmenu.add_command(label=LH.string("sound"), command=lambda: add("sound")) #addmenu.add_command(label=LH.string("obj"), command=lambda: muladd("obj")) testmenu = tk.Menu(menu) menu.add_cascade(label=LH.string("testing"), menu=testmenu) testmenu.add_command(label=LH.string("test"), command=testing, image=icons["test"], compound="left") testmenu.add_command(label=LH.string("stest"), command=stoptest, image=icons["stop-test"], compound="left") buildmenu = tk.Menu(menu) menu.add_cascade(label=LH.string("building"), menu=buildmenu) buildmenu.add_command(label=LH.string("build"), command=build, image=icons["build"], compound="left") langmenu = tk.Menu(menu) menu.add_cascade(label=LH.string("langs"), menu=langmenu) for i in LH.getlangs(): langmenu.add_command(label=i, command=lambda i=i: selectlang(i)) container.mainloop() # attribute changers def ats(mode, old): #mode 0 = string #mode 1 = single character out = easygui.enterbox(LH.string("newval"), LH.string("newval")) if out: if mode == 1 and len(out) != 1: messagebox.showerror(LH.string("error"), LH.string("SCE")) return "N" return out else: return old def anum(old): out = easygui.enterbox(LH.string("newval"), LH.string("newval")) if out: if "." in out: try: out = float(out) return out except ValueError: return old else: return int(out) else: return old def abool(old): out = easygui.boolbox(LH.string("newval"), LH.string("newval"), (LH.string("true"), LH.string("false"))) if out: return out else: return old def acode(old): out = easygui.textbox(LH.string("newval"), LH.string("newval"), old) if out: return out else: return old def apath(old, ext): new = filedialog.askopenfilename(defaultextension=ext, filetypes=(ext)) if new: return new else: return old def aNULL(old): return old def execgame(gametree): global GUIe global preview preview = hashengine.game(renderer=nullrend, sounddir="/") GUIe = False for i in gametree: importobj(i) run() class rsound: def __init__(self): self.spath = "" self.sdata = b"" class sound(): def __init__(self, new): self.spath = os.path.basename(new).split(".")[0] self.sdata = hashengine.loadsound(new) global types global ignoreat global valtypes global extypes global attypes global crucial crucial = ["obj"] types = hashengine.enum({"obj": hashengine.obj, "script": script, "rawsound": rsound, "sound": lambda: sound(apath("", [("Wave files", ".wave .wav")]))}) ignoreat = ["ID", "execute", "sdata"] """self.position = vector2() self.char = " " self.ID = 0 self.gravity = 0 self.acceleration = vector2() self.velocity = vector2() self.friction = 0 self.collide = True self.touch = True self.anchored = False self.bcolor = color3(255, 255, 255) self.fcolor = color3()""" valtypes = { "char": lambda old: ats(1, old), "gravity": anum, "x": anum, "y": anum, "z": anum, "r": anum, "g": anum, "b": anum, "friction": anum, "collide": abool, "touch": abool, "anchored": abool, "code": acode, "spath": aNULL, } #lambda old: apath(old, [("Wave files", ".wave .wav")]) extypes = list(valtypes.keys()) attypes = { "vector2": hashengine.vector2, "color3": hashengine.color3, } if __name__ == "__main__": GUIinit()