mirror of
https://github.com/lalbornoz/roar.git
synced 2024-11-22 15:26:37 +00:00
Initial commit.
This commit is contained in:
commit
74bdd88766
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
__pycache__/
|
||||||
|
*.sw[op]
|
BIN
DejaVuSansMono.ttf
Normal file
BIN
DejaVuSansMono.ttf
Normal file
Binary file not shown.
143
ENNTool.py
Executable file
143
ENNTool.py
Executable file
@ -0,0 +1,143 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# ENNTool -- mIRC art animation tool (for EFnet #MiRCART) (WIP)
|
||||||
|
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
|
||||||
|
# This project is licensed under the terms of the MIT license.
|
||||||
|
#
|
||||||
|
# TODO:
|
||||||
|
# 1) -A: render frame #1, render frame #2, ...
|
||||||
|
# 2) -o: support at least {GIF,MP4,WEBM}
|
||||||
|
# 3) -s: effects: rotate, smash into bricks, swirl, wave, ...
|
||||||
|
# 4) XXX autodetect video width from widest mircart
|
||||||
|
# 5) XXX convert TTF to texture PNG & coords TXT, render accordingly
|
||||||
|
# 6) XXX dont stall GPU w/ glReadPixels(), switch to asynchronous model w/ PBOs
|
||||||
|
# 7) XXX render mircart as 3D blocks vs flat surface
|
||||||
|
#
|
||||||
|
|
||||||
|
from getopt import getopt, GetoptError
|
||||||
|
from glob import glob
|
||||||
|
from OpenGL.GL import *
|
||||||
|
import os, sys, time
|
||||||
|
import wx
|
||||||
|
|
||||||
|
from ENNToolGLCanvasPanel import ENNToolGLCanvasPanel
|
||||||
|
from ENNToolMiRCARTImporter import ENNToolMiRCARTImporter
|
||||||
|
|
||||||
|
class ENNToolApp(object):
|
||||||
|
"""XXX"""
|
||||||
|
|
||||||
|
# {{{ parseArgv(self, argv): XXX
|
||||||
|
def parseArgv(self, argv):
|
||||||
|
def usage(argv0):
|
||||||
|
print("usage: {}".format(os.path.basename(argv0)), file=sys.stderr)
|
||||||
|
print(" [-A] [-f fps] [-h] [-o pname]".format(os.path.basename(argv0)), file=sys.stderr)
|
||||||
|
print(" [-p] [-r WxH] [-R WxH] [-s pname]", file=sys.stderr)
|
||||||
|
print(" [-S] [-t pname] [-v] [--] pname..", file=sys.stderr)
|
||||||
|
print("", file=sys.stderr)
|
||||||
|
print(" -a........: select animation mode", file=sys.stderr)
|
||||||
|
print(" -f fps....: set video FPS; defaults to 25", file=sys.stderr)
|
||||||
|
print(" -h........: show this screen", file=sys.stderr)
|
||||||
|
print(" -o pname..: output video pathname", file=sys.stderr)
|
||||||
|
print(" -p........: play video after rendering", file=sys.stderr)
|
||||||
|
print(" -r WxH....: set video resolution; defaults to 1152x864", file=sys.stderr)
|
||||||
|
print(" -R WxH....: set MiRCART cube resolution; defaults to 0.1x0.2", file=sys.stderr)
|
||||||
|
print(" -s pname..: input script pathname", file=sys.stderr)
|
||||||
|
print(" -S........: select scrolling mode", file=sys.stderr)
|
||||||
|
print(" -t pname..: set MiRCART texture pathname; defaults to texture.png", file=sys.stderr)
|
||||||
|
print(" -v........: be verbose", file=sys.stderr)
|
||||||
|
try:
|
||||||
|
optlist, argv = getopt(argv[1:], "Af:ho:pr:R:s:St:v")
|
||||||
|
optdict = dict(optlist)
|
||||||
|
|
||||||
|
if "-h" in optdict:
|
||||||
|
usage(sys.argv[0]); exit(0);
|
||||||
|
elif not "-o" in optdict:
|
||||||
|
raise GetoptError("-o pname must be specified")
|
||||||
|
elif not len(argv):
|
||||||
|
raise GetoptError("at least one MiRCART input pname must be specified")
|
||||||
|
|
||||||
|
if not "-f" in optdict:
|
||||||
|
optdict["-f"] = "25"
|
||||||
|
if not "-r" in optdict:
|
||||||
|
optdict["-r"] = "1152x864"
|
||||||
|
if not "-R" in optdict:
|
||||||
|
optdict["-R"] = "0.1x0.2"
|
||||||
|
if not "-t" in optdict:
|
||||||
|
optdict["-t"] = "texture.png"
|
||||||
|
|
||||||
|
if "-r" in optdict:
|
||||||
|
optdict["-r"] = [int(r) for r in optdict["-r"].split("x")][0:2]
|
||||||
|
if "-R" in optdict:
|
||||||
|
optdict["-R"] = [float(r) for r in optdict["-R"].split("x")][0:2]
|
||||||
|
except GetoptError as e:
|
||||||
|
print(e.msg); usage(sys.argv[0]); exit(1);
|
||||||
|
return argv, optdict
|
||||||
|
# }}}
|
||||||
|
# {{{ printProgress(self, progressCur, progressMax): XXX
|
||||||
|
def printProgress(self, progressCur, progressMax):
|
||||||
|
progressDiv = float(progressCur / progressMax)
|
||||||
|
if progressDiv >= 1:
|
||||||
|
progressDiv = 1; endChar = "\n";
|
||||||
|
else:
|
||||||
|
endChar = ""
|
||||||
|
print("\r[{:<50}] {}%".format(
|
||||||
|
("=" * int(progressDiv * 50)), int(progressDiv * 100)), end=endChar)
|
||||||
|
# }}}
|
||||||
|
# {{{ modeScroll(self, argv, optdict, panelGLCanvas, texturePathName, fps=25, scrollRate=0.25): XXX
|
||||||
|
def modeScroll(self, argv, optdict, panelGLCanvas, texturePathName, fps=25, scrollRate=0.25):
|
||||||
|
MiRCART = []
|
||||||
|
for inFileArg in argv:
|
||||||
|
for inFile in sorted(glob(inFileArg)):
|
||||||
|
MiRCART += ENNToolMiRCARTImporter(inFile).outMap
|
||||||
|
|
||||||
|
curY, rotateX, rotateY, translateY = 0, 0, 0, scrollRate
|
||||||
|
artTextureId = panelGLCanvas.initTexture(texturePathName)
|
||||||
|
artVbo, artVboLen, lastY, numVertices = panelGLCanvas.renderMiRCART(MiRCART, cubeSize=optdict["-R"])
|
||||||
|
if "-v" in optdict:
|
||||||
|
print("{} vertices".format(numVertices))
|
||||||
|
w, h = panelGLCanvas.GetClientSize(); w, h = max(w, 1.0), max(h, 1.0);
|
||||||
|
|
||||||
|
while True:
|
||||||
|
self.printProgress(curY, lastY)
|
||||||
|
for numFrame in range(fps):
|
||||||
|
panelGLCanvas.renderFrame(artTextureId, artVbo, artVboLen)
|
||||||
|
if translateY:
|
||||||
|
glTranslatef(0, translateY, 0); curY += translateY
|
||||||
|
if rotateX:
|
||||||
|
glRotatef(rotateX * (180.0/w), 0.0, 1.0, 0.0)
|
||||||
|
if rotateY:
|
||||||
|
glRotatef(rotateY * (180.0/h), 1.0, 0.0, 0.0)
|
||||||
|
panelGLCanvas.saveFrame()
|
||||||
|
if curY >= lastY:
|
||||||
|
self.printProgress(curY, lastY); break;
|
||||||
|
# }}}
|
||||||
|
# {{{ __init__(self, argv): XXX
|
||||||
|
def __init__(self, argv):
|
||||||
|
argv, optdict = self.parseArgv(argv)
|
||||||
|
wxApp = wx.App(False)
|
||||||
|
appFrameSize = optdict["-r"]
|
||||||
|
appFrame = wx.Frame(None, size=appFrameSize); appFrame.Hide();
|
||||||
|
appPanelSkin = wx.Panel(appFrame, wx.ID_ANY)
|
||||||
|
|
||||||
|
videoFps, videoPath = int(optdict["-f"]), optdict["-o"]
|
||||||
|
panelGLCanvas = ENNToolGLCanvasPanel(appPanelSkin, size=appFrameSize, videoPath=videoPath)
|
||||||
|
panelGLCanvas.initOpenGL(); panelGLCanvas.initVideoWriter(fps=videoFps)
|
||||||
|
|
||||||
|
if "-v" in optdict:
|
||||||
|
time0 = time.time()
|
||||||
|
self.modeScroll(argv, optdict, panelGLCanvas, fps=videoFps, texturePathName=optdict["-t"])
|
||||||
|
if "-v" in optdict:
|
||||||
|
print("delta {}s".format(time.time() - time0))
|
||||||
|
if "-p" in optdict:
|
||||||
|
os.startfile(videoPath)
|
||||||
|
# }}}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Entry point
|
||||||
|
def main(*argv):
|
||||||
|
ENNToolApp(argv)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main(*sys.argv)
|
||||||
|
|
||||||
|
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
156
ENNToolGLCanvasPanel.py
Normal file
156
ENNToolGLCanvasPanel.py
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# ENNTool -- mIRC art animation tool (for EFnet #MiRCART) (WIP)
|
||||||
|
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
|
||||||
|
# This project is licensed under the terms of the MIT license.
|
||||||
|
#
|
||||||
|
# References:
|
||||||
|
# Wed, 27 Jun 2018 16:02:10 +0200 [1] <https://www.opengl.org/discussion_boards/showthread.php/125843-default-camera?p=954801&viewfull=1#post954801>
|
||||||
|
# Wed, 27 Jun 2018 16:02:11 +0200 [2] <https://www.opengl.org/discussion_boards/showthread.php/167808-2D-texture-problem-lines-between-textures>
|
||||||
|
# Wed, 27 Jun 2018 16:02:12 +0200 [3] <https://www.khronos.org/opengl/wiki/How_lighting_works#Good_Settings.>
|
||||||
|
# Wed, 27 Jun 2018 16:02:13 +0200 [4] <https://www.khronos.org/opengl/wiki/Common_Mistakes>
|
||||||
|
# Wed, 27 Jun 2018 16:02:14 +0200 [5] <https://www.khronos.org/opengl/wiki/Pixel_Transfer#Pixel_layout>
|
||||||
|
#
|
||||||
|
|
||||||
|
from OpenGL.GL import *
|
||||||
|
from PIL import Image
|
||||||
|
import cv2, numpy
|
||||||
|
import ctypes, sys
|
||||||
|
import wx, wx.glcanvas
|
||||||
|
|
||||||
|
class ENNToolGLCanvasPanel(wx.glcanvas.GLCanvas, wx.Panel):
|
||||||
|
"""XXX"""
|
||||||
|
|
||||||
|
# {{{ initOpenGL(self): XXX
|
||||||
|
def initOpenGL(self):
|
||||||
|
self.glContext = wx.glcanvas.GLContext(self)
|
||||||
|
self.SetCurrent(self.glContext)
|
||||||
|
|
||||||
|
# [1]
|
||||||
|
glViewport(0, 0, *self.curSize)
|
||||||
|
glMatrixMode(GL_PROJECTION)
|
||||||
|
glLoadIdentity(); glFrustum(-1, 1, -1, 1, 1, 100);
|
||||||
|
glMatrixMode(GL_MODELVIEW)
|
||||||
|
glEnable(GL_DEPTH_TEST)
|
||||||
|
glClearColor(0, 0, 0, 1); glClearDepth(1);
|
||||||
|
glTranslatef(-5.0, 3.0, -5)
|
||||||
|
|
||||||
|
# [3]
|
||||||
|
glLight(GL_LIGHT0, GL_AMBIENT, (0, 0, 0, 1))
|
||||||
|
glLight(GL_LIGHT0, GL_DIFFUSE, (1, 1, 1, 1))
|
||||||
|
glLight(GL_LIGHT0, GL_POSITION, (1, 1, 0+2, 0))
|
||||||
|
glLight(GL_LIGHT0, GL_SPECULAR, (1, 1, 1, 1))
|
||||||
|
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (0.2, 0.2, 0.2, 1))
|
||||||
|
glEnable(GL_LIGHTING); glEnable(GL_LIGHT0);
|
||||||
|
glEnable(GL_COLOR_MATERIAL)
|
||||||
|
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)
|
||||||
|
# }}}
|
||||||
|
# {{{ initTexture(self, pathName): XXX
|
||||||
|
def initTexture(self, pathName):
|
||||||
|
artTextureId = glGenTextures(1)
|
||||||
|
artTextureImage = Image.open(pathName)
|
||||||
|
artTextureImageData = numpy.array(list(artTextureImage.getdata()), numpy.uint8)
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, artTextureId)
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
|
||||||
|
|
||||||
|
# [2]
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
|
||||||
|
|
||||||
|
# [4][5]
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
|
||||||
|
artTextureImage.size[0], artTextureImage.size[1],
|
||||||
|
0, GL_RGBA, GL_UNSIGNED_BYTE, artTextureImageData)
|
||||||
|
glBindTexture(GL_TEXTURE_2D, artTextureId)
|
||||||
|
return artTextureId
|
||||||
|
# }}}
|
||||||
|
# {{{ initVideoWriter(self): XXX
|
||||||
|
def initVideoWriter(self, fourcc="XVID", fps=25):
|
||||||
|
fourcc = cv2.VideoWriter_fourcc(*list(fourcc))
|
||||||
|
self.videoWriter = cv2.VideoWriter(self.videoPath, fourcc, fps, (self.width, self.height), True)
|
||||||
|
# }}}
|
||||||
|
# {{{ renderFrame(self, artTextureId, artVbo, artVboLen): XXX
|
||||||
|
def renderFrame(self, artTextureId, artVbo, artVboLen):
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY)
|
||||||
|
glEnableClientState(GL_NORMAL_ARRAY)
|
||||||
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY)
|
||||||
|
glEnable(GL_TEXTURE_2D)
|
||||||
|
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, artTextureId)
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, artVbo)
|
||||||
|
glVertexPointer(3, GL_FLOAT, 32, ctypes.c_void_p(0))
|
||||||
|
glNormalPointer(GL_FLOAT, 32, ctypes.c_void_p(12))
|
||||||
|
glTexCoordPointer(2, GL_FLOAT, 32, ctypes.c_void_p(24))
|
||||||
|
glDrawArrays(GL_QUADS, 0, artVboLen)
|
||||||
|
|
||||||
|
glDisable(GL_TEXTURE_2D)
|
||||||
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY)
|
||||||
|
glDisableClientState(GL_NORMAL_ARRAY)
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY)
|
||||||
|
# }}}
|
||||||
|
# {{{ renderMiRCART(self, artMap, centre=True, canvasCols=100, cubeSize=(0.1, 0.2), texelHeight=0.0625, texelWidth=0.0625): XXX
|
||||||
|
def renderMiRCART(self, artMap, centre=True, canvasCols=100, cubeSize=(0.1, 0.2), texelHeight=0.0625, texelWidth=0.0625):
|
||||||
|
curPos = [0, 0, 0]; vertices = []; numVertices = 0;
|
||||||
|
for numRow in range(len(artMap)):
|
||||||
|
if centre and (len(artMap[numRow]) < canvasCols):
|
||||||
|
curPos[0] += (((canvasCols - len(artMap[numRow])) * cubeSize[0]) / 2)
|
||||||
|
for numCol in range(len(artMap[numRow])):
|
||||||
|
cubeColour = artMap[numRow][numCol][1] * texelWidth
|
||||||
|
|
||||||
|
# Top Right
|
||||||
|
vertices += curPos
|
||||||
|
vertices += [0.0, 0.0, 1.0]
|
||||||
|
vertices += [cubeColour+texelWidth, texelHeight]
|
||||||
|
numVertices += 1
|
||||||
|
|
||||||
|
# Top Left
|
||||||
|
vertices += [curPos[0]-cubeSize[0], curPos[1], curPos[2]]
|
||||||
|
vertices += [0.0, 0.0, 1.0]
|
||||||
|
vertices += [cubeColour, texelHeight]
|
||||||
|
numVertices += 1
|
||||||
|
|
||||||
|
# Bottom Left
|
||||||
|
vertices += [curPos[0]-cubeSize[0], curPos[1]-cubeSize[1], curPos[2]]
|
||||||
|
vertices += [0.0, 0.0, 1.0]
|
||||||
|
vertices += [cubeColour, 0.0]
|
||||||
|
numVertices += 1
|
||||||
|
|
||||||
|
# Bottom Right
|
||||||
|
vertices += [curPos[0], curPos[1]-cubeSize[1], curPos[2]]
|
||||||
|
vertices += [0.0, 0.0, 1.0]
|
||||||
|
vertices += [cubeColour+texelWidth, 0.0]
|
||||||
|
numVertices += 1
|
||||||
|
|
||||||
|
curPos[0] += cubeSize[0]
|
||||||
|
curPos[0], curPos[1] = 0, curPos[1] - cubeSize[1]
|
||||||
|
|
||||||
|
artVbo = glGenBuffers(1)
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, artVbo)
|
||||||
|
glBufferData(GL_ARRAY_BUFFER,
|
||||||
|
(ctypes.c_float*len(vertices))(*vertices),
|
||||||
|
GL_STATIC_DRAW)
|
||||||
|
return artVbo, len(vertices), -curPos[1], numVertices
|
||||||
|
# }}}
|
||||||
|
# {{{ saveFrame(self): XXX
|
||||||
|
def saveFrame(self):
|
||||||
|
if sys.byteorder == "little":
|
||||||
|
screenshot = glReadPixels(0, 0, self.width, self.height, GL_BGR, GL_UNSIGNED_BYTE)
|
||||||
|
else:
|
||||||
|
screenshot = glReadPixels(0, 0, self.width, self.height, GL_RGB, GL_UNSIGNED_BYTE)
|
||||||
|
screenshot = numpy.flipud(numpy.frombuffer(screenshot, numpy.uint8).reshape((self.height, self.width, 3)))
|
||||||
|
self.videoWriter.write(screenshot)
|
||||||
|
# }}}
|
||||||
|
# {{{ __init__(self, parent, size, defaultPos=(24,24), videoPath=None): initialisation method
|
||||||
|
def __init__(self, parent, size, defaultPos=(24,24), videoPath=None):
|
||||||
|
super().__init__(parent, pos=defaultPos, size=size)
|
||||||
|
self.curPos = list(defaultPos); self.curSize = list(size);
|
||||||
|
self.width, self.height = self.GetClientSize()
|
||||||
|
self.videoPath = videoPath
|
||||||
|
# }}}
|
||||||
|
|
||||||
|
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
27
ENNToolMiRCARTColours.py
Normal file
27
ENNToolMiRCARTColours.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# ENNTool -- mIRC art animation tool (for EFnet #MiRCART) (WIP)
|
||||||
|
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
|
||||||
|
# This project is licensed under the terms of the MIT license.
|
||||||
|
#
|
||||||
|
|
||||||
|
ENNToolMiRCARTColours = [
|
||||||
|
[1.00, 1.00, 1.00], # White
|
||||||
|
[0.00, 0.00, 0.00], # Black
|
||||||
|
[0.00, 0.00, 0.73], # Blue
|
||||||
|
[0.00, 0.73, 0.00], # Green
|
||||||
|
[1.00, 0.33, 0.33], # Light Red
|
||||||
|
[0.73, 0.00, 0.00], # Red
|
||||||
|
[0.73, 0.00, 0.73], # Purple
|
||||||
|
[0.73, 0.73, 0.00], # Yellow
|
||||||
|
[1.00, 1.00, 0.33], # Light Yellow
|
||||||
|
[0.33, 1.00, 0.33], # Light Green
|
||||||
|
[0.00, 0.73, 0.73], # Cyan
|
||||||
|
[0.33, 1.00, 1.00], # Light Cyan
|
||||||
|
[0.33, 0.33, 1.00], # Light Blue
|
||||||
|
[1.00, 0.33, 1.00], # Pink
|
||||||
|
[0.33, 0.33, 0.33], # Grey
|
||||||
|
[0.73, 0.73, 0.73], # Light Grey
|
||||||
|
]
|
||||||
|
|
||||||
|
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
135
ENNToolMiRCARTImporter.py
Normal file
135
ENNToolMiRCARTImporter.py
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# ENNTool -- mIRC art animation tool (for EFnet #MiRCART) (WIP)
|
||||||
|
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
|
||||||
|
# This project is licensed under the terms of the MIT license.
|
||||||
|
#
|
||||||
|
# TODO:
|
||||||
|
# 1) un-Quick'n'Dirty-ify
|
||||||
|
#
|
||||||
|
|
||||||
|
import chardet
|
||||||
|
|
||||||
|
class ENNToolMiRCARTImporter(object):
|
||||||
|
"""XXX"""
|
||||||
|
|
||||||
|
# {{{ _CellState(): Cell state
|
||||||
|
class _CellState():
|
||||||
|
CS_NONE = 0x00
|
||||||
|
CS_BOLD = 0x01
|
||||||
|
CS_ITALIC = 0x02
|
||||||
|
CS_UNDERLINE = 0x04
|
||||||
|
# }}}
|
||||||
|
# {{{ _ParseState(): Parsing loop state
|
||||||
|
class _ParseState():
|
||||||
|
PS_CHAR = 1
|
||||||
|
PS_COLOUR_DIGIT0 = 2
|
||||||
|
PS_COLOUR_DIGIT1 = 3
|
||||||
|
# }}}
|
||||||
|
|
||||||
|
# {{{ _flipCellStateBit(self, cellState, bit): XXX
|
||||||
|
def _flipCellStateBit(self, cellState, bit):
|
||||||
|
if cellState & bit:
|
||||||
|
return cellState & ~bit
|
||||||
|
else:
|
||||||
|
return cellState | bit
|
||||||
|
# }}}
|
||||||
|
# {{{ _parseCharAsColourSpec(self, colourSpec, curColours): XXX
|
||||||
|
def _parseCharAsColourSpec(self, colourSpec, curColours):
|
||||||
|
if len(colourSpec) > 0:
|
||||||
|
colourSpec = colourSpec.split(",")
|
||||||
|
if len(colourSpec) == 2 \
|
||||||
|
and len(colourSpec[1]) > 0:
|
||||||
|
return [int(colourSpec[0] or curColours[0]), \
|
||||||
|
int(colourSpec[1])]
|
||||||
|
elif len(colourSpec) == 1 \
|
||||||
|
or len(colourSpec[1]) == 0:
|
||||||
|
return [int(colourSpec[0]), curColours[1]]
|
||||||
|
else:
|
||||||
|
return [15, 1]
|
||||||
|
# }}}
|
||||||
|
# {{{ fromTextFile(self, pathName): XXX
|
||||||
|
def fromTextFile(self, pathName):
|
||||||
|
with open(pathName, "rb") as fileObject:
|
||||||
|
inFileEncoding = chardet.detect(fileObject.read())["encoding"]
|
||||||
|
self.inFile = open(pathName, "r", encoding=inFileEncoding)
|
||||||
|
self.inSize = self.outMap = None;
|
||||||
|
inCurColourSpec = ""; inCurRow = -1;
|
||||||
|
inLine = self.inFile.readline()
|
||||||
|
inSize = [0, 0]; outMap = []; inMaxCols = 0;
|
||||||
|
while inLine:
|
||||||
|
inCellState = self._CellState.CS_NONE
|
||||||
|
inParseState = self._ParseState.PS_CHAR
|
||||||
|
inCurCol = 0; inMaxCol = len(inLine);
|
||||||
|
inCurColourDigits = 0; inCurColours = [15, 1]; inCurColourSpec = "";
|
||||||
|
inCurRow += 1; outMap.append([]); inRowCols = 0; inSize[1] += 1;
|
||||||
|
while inCurCol < inMaxCol:
|
||||||
|
inChar = inLine[inCurCol]
|
||||||
|
if inChar in set("\r\n"): \
|
||||||
|
inCurCol += 1
|
||||||
|
elif inParseState == self._ParseState.PS_CHAR:
|
||||||
|
inCurCol += 1
|
||||||
|
if inChar == "":
|
||||||
|
inCellState = self._flipCellStateBit( \
|
||||||
|
inCellState, self._CellState.CS_BOLD)
|
||||||
|
elif inChar == "":
|
||||||
|
inParseState = self._ParseState.PS_COLOUR_DIGIT0
|
||||||
|
elif inChar == "":
|
||||||
|
inCellState = self._flipCellStateBit( \
|
||||||
|
inCellState, self._CellState.CS_ITALIC)
|
||||||
|
elif inChar == "":
|
||||||
|
inCellState |= self._CellState.CS_NONE
|
||||||
|
inCurColours = [15, 1]
|
||||||
|
elif inChar == "":
|
||||||
|
inCurColours = [inCurColours[1], inCurColours[0]]
|
||||||
|
elif inChar == "":
|
||||||
|
inCellState = self._flipCellStateBit( \
|
||||||
|
inCellState, self._CellState.CS_UNDERLINE)
|
||||||
|
else:
|
||||||
|
inRowCols += 1
|
||||||
|
outMap[inCurRow].append([*inCurColours, inCellState, inChar])
|
||||||
|
elif inParseState == self._ParseState.PS_COLOUR_DIGIT0 \
|
||||||
|
or inParseState == self._ParseState.PS_COLOUR_DIGIT1:
|
||||||
|
if inChar == "," \
|
||||||
|
and inParseState == self._ParseState.PS_COLOUR_DIGIT0:
|
||||||
|
if (inCurCol + 1) < inMaxCol \
|
||||||
|
and not inLine[inCurCol + 1] in set("0123456789"):
|
||||||
|
inCurColours = self._parseCharAsColourSpec( \
|
||||||
|
inCurColourSpec, inCurColours)
|
||||||
|
inCurColourDigits = 0; inCurColourSpec = "";
|
||||||
|
inParseState = self._ParseState.PS_CHAR
|
||||||
|
else:
|
||||||
|
inCurCol += 1
|
||||||
|
inCurColourDigits = 0; inCurColourSpec += inChar;
|
||||||
|
inParseState = self._ParseState.PS_COLOUR_DIGIT1
|
||||||
|
elif inChar in set("0123456789") \
|
||||||
|
and inCurColourDigits == 0:
|
||||||
|
inCurCol += 1
|
||||||
|
inCurColourDigits += 1; inCurColourSpec += inChar;
|
||||||
|
elif inChar in set("0123456789") \
|
||||||
|
and inCurColourDigits == 1 \
|
||||||
|
and inCurColourSpec[-1] == "0":
|
||||||
|
inCurCol += 1
|
||||||
|
inCurColourDigits += 1; inCurColourSpec += inChar;
|
||||||
|
elif inChar in set("012345") \
|
||||||
|
and inCurColourDigits == 1 \
|
||||||
|
and inCurColourSpec[-1] == "1":
|
||||||
|
inCurCol += 1
|
||||||
|
inCurColourDigits += 1; inCurColourSpec += inChar;
|
||||||
|
else:
|
||||||
|
inCurColours = self._parseCharAsColourSpec( \
|
||||||
|
inCurColourSpec, inCurColours)
|
||||||
|
inCurColourDigits = 0; inCurColourSpec = "";
|
||||||
|
inParseState = self._ParseState.PS_CHAR
|
||||||
|
inMaxCols = max(inMaxCols, inRowCols)
|
||||||
|
inLine = self.inFile.readline()
|
||||||
|
inSize[0] = inMaxCols; self.inSize = inSize; self.outMap = outMap;
|
||||||
|
self.inFile.close()
|
||||||
|
# }}}
|
||||||
|
# {{{ __init__(self, inFile): initialisation method
|
||||||
|
def __init__(self, inFile):
|
||||||
|
self.inFile = inFile; self.inSize = self.outMap = None;
|
||||||
|
self.fromTextFile(inFile)
|
||||||
|
# }}}
|
||||||
|
|
||||||
|
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
19
LICENCE
Normal file
19
LICENCE
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
5
README.md
Normal file
5
README.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# ENNTool -- mIRC art animation tool (for EFnet #MiRCART) (WIP)
|
||||||
|
Copyright (c) 2018 Lucio Andrés Illanes Albornoz <<lucio@lucioillanes.de>>
|
||||||
|
This project is licensed under the terms of the MIT licence.
|
||||||
|
* Prerequisites on Windows: install Python v3.5.x and script dependencies w/ the following elevated command prompt command line:
|
||||||
|
`pip install chardet numpy opencv-python Pillow PyOpenGL wxPython`
|
36
puke.txt
Normal file
36
puke.txt
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
0,1 3,3 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 3,3 0,1 0,0 1,1 0,1 0,0 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 1,1 9,9 1,1 9,9 1,1 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1
|
||||||
|
3,3 0,1 3,3 0,1 9,9 0,1 9,9 1,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 0,0 0,1 0,0 0,1 0,0 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 1,1 9,9 0,1 9,9 1,1 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1
|
||||||
|
0,1 3,3 0,1 9,9 0,1 11,11 10,10 11,11 0,1 9,9 0,1 9,9 0,1 3,3 0,1 3,3 0,1 0,0 0,1 0,0 0,1 0,0 0,1 9,9 0,1 9,9 0,1 9,9 0,1 1,1 9,9 0,1 1,1 0,1 9,9 0,1 9,9 0,1
|
||||||
|
0,1 3,3 0,1 3,3 0,1 10,10 11,11 10,10 11,11 10,10 0,1 3,3 0,1 3,3 0,1 0,0 0,1 3,3 0,1 3,3 0,1 1,1 3,3 1,1 3,3 1,1 9,9 1,1 9,9 1,1 3,3 1,1 3,3 1,1 0,1 3,3 0,1 3,3 0,1
|
||||||
|
9,9 1,1 3,3 1,1 10,10 11,11 10,10 11,11 10,10 1,1 0,0 1,1 11,11 1,10 1,1 11,11 1,1 3,3 1,1 9,9 1,1 3,3 1,1 11,11 1,1 1,10 11,11 0,1 9,9
|
||||||
|
9,9 1,1 10,10 11,11 10,10 11,11 10,10 11,11 1,1 3,3 1,1 11,11 1,10 1,1 11,11 1,1 3,3 1,1 3,3 1,1 11,11 1,1 1,10 11,11 0,1 9,9
|
||||||
|
9,9 1,1 10,10 11,11 10,10 11,11 10,10 1,1 8,8 1,1 11,11 1,10 1,1 11,11 1,1 3,3 1,1 11,11 1,1 1,10 11,11 1,1 0,1 9,9
|
||||||
|
9,9 1,1 11,11 10,10 11,11 10,10 11,11 10,10 11,11 10,10 1,1 8,8 1,1 8,8 1,1 11,11 1,10 1,1 11,11 1,1 1,10 11,11 1,1 0,1 9,9
|
||||||
|
9,9 1,1 11,11 10,10 11,11 10,10 11,10 10,10 11,11 10,10 1,1 8,8 1,1 8,8 1,1 11,11 1,10 1,1 1,10 11,11 1,1 0,1 9,9
|
||||||
|
9,9 1,1 11,11 10,10 11,11 10,10 11,11 10,10 1,1 8,8 1,1 8,8 1,1 8,8 1,1 0,0 1,1 8,8 1,1 8,8 1,1 8,8 1,1 11,11 1,10 11,11 1,10 11,11 1,1 0,1 9,9
|
||||||
|
1,3 9,9 1,1 11,11 10,10 11,11 10,10 11,11 1,1 8,8 1,1 8,8 1,1 8,8 1,1 0,0 1,1 0,0 1,1 8,8 1,1 8,8 1,1 8,8 1,1 11,11 10,10 11,11 1,1 0,1 9,9 1,3
|
||||||
|
3,3 9,9 1,1 3,3 1,1 3,3 1,1 11,11 10,10 1,1 8,8 1,1 8,8 1,1 8,8 1,1 0,0 1,1 8,8 1,1 8,8 1,1 8,8 1,1 3,3 9,9 3,3 1,1 0,1 9,9 1,3
|
||||||
|
3,3 9,9 1,1 3,3 1,1 3,3 1,1 3,3 1,1 3,3 1,1 8,8 1,1 8,8 1,1 8,8 1,1 0,0 1,1 8,8 1,1 8,8 1,1 0,0 1,1 8,8 1,1 8,8 1,1 8,8 1,1 3,3 9,9 1,1 0,1 9,9 1,3
|
||||||
|
3,3 9,9 1,1 3,3 1,1 3,3 1,1 3,3 1,1 3,3 1,1 8,8 1,1 8,8 1,1 8,8 1,1 0,0 1,1 0,0 1,1 8,8 1,1 8,8 1,1 0,0 1,1 0,0 1,1 8,8 1,1 8,8 1,1 8,8 1,1 3,3 9,9 3,3 1,1 0,1 9,9 1,3
|
||||||
|
3,3 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 7,7 8,8 1,1 8,8 1,1 8,8 1,1 0,0 1,1 8,8 1,1 0,0 1,1 8,8 1,1 8,8 1,1 8,8 1,1 9,9 3,3 1,1 0,1 9,9 1,3
|
||||||
|
1,3 3,3 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 7,7 8,8 1,1 8,8 1,1 8,8 1,1 3,3 9,9 3,3 1,1 0,1 9,9 1,3
|
||||||
|
11,11 3,3 9,9 1,1 7,7 8,8 1,1 8,8 1,1 8,8 1,1 8,8 1,1 3,3 9,9 1,1 0,1 9,9 1,3 11,11
|
||||||
|
11,11 3,3 9,9 1,1 3,3 1,1 3,3 1,1 3,3 1,1 3,3 1,1 3,3 1,1 3,3 1,1 7,7 8,8 1,1 0,0 1,1 8,8 1,1 3,3 9,9 3,3 1,1 0,1 9,9 1,3 11,11
|
||||||
|
11,11 1,3 3,3 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 7,7 8,8 1,1 8,8 1,1 9,9 3,3 1,1 0,1 9,9 1,3 11,11
|
||||||
|
10,10 3,11 1,3 3,3 9,9 1,1 3,3 1,1 3,3 1,1 7,7 8,8 1,1 0,0 1,1 0,0 1,1 0,0 1,1 8,8 1,1 3,3 1,1 9,9 1,3 3,11 10,10
|
||||||
|
10,10 3,11 1,3 3,3 9,9 1,1 3,3 1,1 3,3 1,1 3,3 1,1 3,3 1,1 3,3 1,1 7,7 8,8 8,1 1,1 8,1 8,8 1,1 9,9 3,3 1,1 9,9 1,3 3,11 10,10
|
||||||
|
10,10 3,11 1,3 3,3 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 7,7 8,8 8,1 0,0 1,1 0,0 1,1 0,0 8,1 8,8 1,1 3,3 9,9 1,3 3,11 10,10
|
||||||
|
10,10 3,11 3,3 9,9 7,7 8,8 8,1 1,1 8,1 8,8 7,7 9,9 3,3 1,3 3,11 10,10
|
||||||
|
10,10 11,11 3,3 7,7 8,8 8,1 0,0 8,1 8,8 7,7 3,3 11,11 10,10
|
||||||
|
10,10 11,11 3,3 9,9 7,7 8,8 8,1 8,8 7,7 9,9 3,3 11,11 10,10
|
||||||
|
10,10 11,11 3,3 9,9 3,3 7,7 3,3 9,9 3,3 11,11 10,10
|
||||||
|
10,10 11,11 3,3 9,9 3,3 11,11 3,3 9,9 3,3 11,11 10,10
|
||||||
|
11,11 3,3 9,9 3,3 11,11 10,10 11,11 3,3 9,9 3,3 11,11
|
||||||
|
11,11 3,3 9,9 3,3 11,11 10,10 11,11 10,10 11,11 3,3 9,9 3,3 11,11
|
||||||
|
11,11 3,3 9,9 3,3 11,11 10,10 11,11 10,10 11,11 10,10 11,11 3,3 9,9 3,3 11,11
|
||||||
|
11,11 3,3 9,9 3,3 11,11 10,10 11,11 10,10 11,11 3,3 9,9 3,3 11,11
|
||||||
|
10,10 11,11 3,3 9,9 3,3 11,11 10,10 11,11 3,3 9,9 3,3 11,11 10,10
|
||||||
|
10,10 11,11 3,3 9,9 3,3 11,11 3,3 9,9 3,3 11,11 10,10
|
||||||
|
10,10 11,11 3,3 9,9 3,3 9,9 3,3 11,11 10,10
|
||||||
|
10,10 11,11 3,3 9,9 3,3 11,11 10,10
|
||||||
|
10,10 11,11 3,3 11,11 10,10
|
BIN
texture.png
Normal file
BIN
texture.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 270 B |
Loading…
Reference in New Issue
Block a user