summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
m---------Modernizr0
-rw-r--r--README.rst6
-rw-r--r--ast2json/decompiler.py500
-rwxr-xr-xconfigure77
m---------fastclick0
6 files changed, 54 insertions, 531 deletions
diff --git a/Makefile b/Makefile
index 5e45486..0b7e65d 100644
--- a/Makefile
+++ b/Makefile
@@ -68,12 +68,14 @@ $(IJSON): www/json/%.json: ast2json/imachine2json.py ast2json/%.json.i
$^ $@
%.json.gz: %.json
+ifdef GZIP
ifdef DEFLUFF
$(GZIP) -c $< | $(DEFLUFF) > $@
else
$(GZIP) -c $< > $@
endif
touch $< $@
+endif
# === VIDEO ===
diff --git a/Modernizr b/Modernizr
-Subproject 608d9069ef615aa35d6430e10bf938002074e41
+Subproject 3b56e7309de3a301ac69987ac3d5d7055d0fb04
diff --git a/README.rst b/README.rst
index f149277..bfd538b 100644
--- a/README.rst
+++ b/README.rst
@@ -55,11 +55,9 @@ Build steps
Disabling unused conversions
----------------------------
-To reduce programs and build time required, some conversions can be disabled.
-Passing --minimal to configure will disable the safe ones.
+To reduce programs and build time required, some conversions can be disabled by passing ``CONVERSION=`` on the command line, e.g. ``ZOPFLIPNG= ./configure``.
-Alternatively, specific conversions can be disabled by passing --disable-conversion on the command line.
-See ``./configure --help`` for more information.
+Alternatively, just don't install those programs. Conversions that are safe to disable are labeled as such in ``configure``. If a required conversion is disabled, configure will print a big error.
Reducing disk usage
===================
diff --git a/ast2json/decompiler.py b/ast2json/decompiler.py
deleted file mode 100644
index 0a0b916..0000000
--- a/ast2json/decompiler.py
+++ /dev/null
@@ -1,500 +0,0 @@
-# Copyright (c) 2012 Yuri K. Schlesner
-#
-# 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.
-
-import renpy.ast as ast
-import renpy.atl as atl
-import codegen
-import screendecompiler
-import code
-
-DECOMPILE_SCREENS = True
-
-def pretty_print_ast(out_file, ast):
- code.interact(local=locals())
- for stmt in ast:
- print_statement(out_file, stmt, 0)
-
-def indent(f, level):
- # Print indentation
- f.write(u' ' * level)
-
-def print_statement(f, statement, indent_level=0):
- indent(f, indent_level)
-
- func = statement_printer_dict.get(type(statement), print_Unknown)
- func(f, statement, indent_level)
-
-def escape_string(s):
- s = s.replace('"', '\\"')
- s = s.replace('\n', '\\n')
- s = s.replace('\t', '\\t')
- return s
-
-# TODO "choice" and "parallel" blocks are greedily combined
-# so we need a "pass" statement to separate them if
-# multiple of the same block are immediately after
-# each other.
-def print_atl(f, atl_block, indent_level):
- if not atl_block.statements:
- indent(f, indent_level)
- f.write(u'pass\n')
- for stmt in atl_block.statements:
- indent(f, indent_level)
-
- if type(stmt) is atl.RawMultipurpose:
- # warper
- if stmt.warp_function:
- f.write(u"warp %s" % (stmt.warp_function.strip(), ))
- f.write(u" %s " % (stmt.duration.strip(), ))
- elif stmt.warper:
- f.write(stmt.warper)
- f.write(u" %s " % (stmt.duration.strip(), ))
- elif stmt.duration.strip() != '0':
- f.write(u'pause')
- f.write(u" %s" % (stmt.duration.strip(), ))
-
- # revolution
- if stmt.revolution:
- f.write(u"%s " % (stmt.revolution, ))
-
- # circles
- if stmt.circles != "0":
- f.write(u"circles %s " % (stmt.circles.strip(), ))
-
- # splines
- for (name, exprs) in stmt.splines:
- f.write(u"%s " % (name, ))
- for expr in exprs:
- f.write(u"knot %s " % (expr.strip(), ))
-
- # properties
- for (k, v) in stmt.properties:
- f.write(u"%s %s " % (k, v.strip()))
-
- # with
- for (expr, with_expr) in stmt.expressions:
- f.write(u"%s " % (expr.strip(), ))
- if with_expr:
- f.write(u"with %s " % (with_expr, ))
-
- f.write(u"\n")
-
- elif type(stmt) is atl.RawBlock:
- # what does stmt.animation do?
- f.write(u"block:\n")
- print_atl(f, stmt, indent_level + 1)
-
- elif type(stmt) is atl.RawChoice:
- first = True
- for (chance, block) in stmt.choices:
- if first:
- first = False
- else:
- indent(f, indent_level)
-
- f.write(u"choice")
- if chance != "1.0":
- f.write(u" %s" % (chance, ))
- f.write(u":\n")
- print_atl(f, block, indent_level + 1)
-
- elif type(stmt) is atl.RawContainsExpr:
- f.write(u"contains %s\n" % (stmt.expression, ))
-
- elif type(stmt) is atl.RawEvent:
- f.write(u"event %s\n" % (stmt.name, ))
-
- elif type(stmt) is atl.RawFunction:
- f.write(u"function %s\n" % (stmt.expr, ))
-
- elif type(stmt) is atl.RawOn:
- first = True
- for name, block in stmt.handlers.iteritems():
- if first:
- first = False
- else:
- indent(f, indent_level)
-
- f.write(u"on %s:\n" % (name, ))
- print_atl(f, block, indent_level + 1)
-
- elif type(stmt) is atl.RawParallel:
- first = True
- for block in stmt.blocks:
- if first:
- first = False
- else:
- indent(f, indent_level)
-
- f.write(u"parallel:\n")
- print_atl(f, block, indent_level + 1)
-
- elif type(stmt) is atl.RawRepeat:
- f.write(u"repeat")
- if stmt.repeats:
- f.write(u" %s" % (stmt.repeats, )) # not sure if this is even a string
- f.write(u"\n")
-
- elif type(stmt) is atl.RawTime:
- f.write(u"time %s\n" % (stmt.time, ))
-
- else:
- f.write(u"TODO atl.%s\n" % type(stmt).__name__)
-
-def print_imspec(f, imspec):
- if imspec[1] is not None: # Expression
- f.write(u'expression ')
- f.write(imspec[1])
- else: # Image name
- f.write(' '.join(imspec[0]))
-
- # at
- if len(imspec[3]) > 0:
- f.write(u" at %s" % (', '.join(imspec[3])))
-
- # as
- if imspec[2] is not None:
- f.write(u" as %s" % (imspec[2], ))
-
- # behind
- if len(imspec[6]) > 0:
- f.write(u" behind %s" % (', '.join(imspec[6])))
-
- # onlayer
- if imspec[4] != 'master':
- f.write(u" onlayer %s" % (imspec[4], ))
-
- # zorder
- # This isn't in the docs, but it's in the parser
- if imspec[5] is not None:
- f.write(u" zorder %s" % (imspec[5], ))
-
-def print_Label(f, stmt, indent_level):
- f.write(u"label %s" % (stmt.name, ))
- if stmt.parameters is not None:
- print_params(f, stmt.parameters)
- f.write(u':\n')
-
- for sub_stmt in stmt.block:
- print_statement(f, sub_stmt, indent_level + 1)
-
-def print_Say(f, stmt, indent_level):
- if stmt.who is not None:
- f.write(u"%s " % (stmt.who, ))
- f.write(u"\"%s\"" % (escape_string(stmt.what), ))
- if stmt.with_ is not None:
- f.write(u" with %s" % (stmt.with_, ))
- f.write(u'\n')
-
-def print_Jump(f, stmt, indent_level):
- f.write(u"jump ")
- if stmt.expression:
- # TODO expression
- f.write(u"expression TODO")
- else:
- f.write(stmt.target)
- f.write(u'\n')
-
-def print_Scene(f, stmt, indent_level):
- f.write(u"scene")
- if stmt.imspec is None:
- if stmt.layer != 'master':
- f.write(u" onlayer %s" % (stmt.layer, ))
- else:
- f.write(u' ')
- print_imspec(f, stmt.imspec)
-
- # with isn't handled here, but split in several statements
-
- if stmt.atl is not None:
- f.write(u':\n')
- print_atl(f, stmt.atl, indent_level+1)
- else:
- f.write('\n')
-
-def print_With(f, stmt, indent_level):
- f.write(u"with %s\n" % (stmt.expr, ))
-
-def print_Show(f, stmt, indent_level):
- f.write(u"show ")
- print_imspec(f, stmt.imspec)
-
- # with isn't handled here, but split in several statements
-
- if stmt.atl is not None:
- f.write(u':\n')
- print_atl(f, stmt.atl, indent_level+1)
- else:
- f.write('\n')
-
-def print_Hide(f, stmt, indent_level):
- f.write(u"hide ")
- print_imspec(f, stmt.imspec)
-
- # with isn't handled here, but split in several statements
-
- f.write('\n')
-
-def print_Python(f, stmt, indent_level, early=False):
- code_src = stmt.code.source
-
- stripped_code = code_src.strip()
-
- if stripped_code.count('\n') == 0:
- f.write(u"$ %s\n" % (stripped_code, ))
- else:
- f.write(u"python")
- if early:
- f.write(u" early")
- if stmt.hide:
- f.write(u" hide")
- f.write(u":\n")
-
- for line in code_src.splitlines(True):
- indent(f, indent_level + 1)
- f.write(line)
-
-def print_Return(f, stmt, indent_level):
- f.write(u"return")
-
- if stmt.expression is not None:
- f.write(u" %s" % (stmt.expression, ))
-
- f.write(u'\n')
-
-def print_UserStatement(f, stmt, indent_level):
- f.write(u"%s\n" % (stmt.line, ))
-
-def print_Init(f, stmt, indent_level):
- if len(stmt.block) == 1 and (hasattr(ast, 'Screen') and isinstance(stmt.block[0], ast.Screen)) and stmt.priority == -500:
- print_screen(f, stmt.block[0], indent_level)
- else:
- f.write(u"init")
- if stmt.priority != 0:
- f.write(u" %d" % (stmt.priority, ))
- f.write(u":\n")
- for s in stmt.block:
- print_statement(f, s, indent_level + 1)
-
-def print_Image(f, stmt, indent_level):
- f.write(u"image %s" % (' '.join(stmt. imgname), ))
- if stmt.code is not None:
- f.write(u" = %s\n" % (stmt.code.source, ))
- else:
- f.write(u":\n")
- print_atl(f, stmt.atl, indent_level + 1)
-
-def print_Transform(f, stmt, indent_level):
- f.write(u"transform %s" % (stmt.varname, ))
- if stmt.parameters is not None:
- print_params(f, stmt.parameters)
-
- f.write(":\n")
- print_atl(f, stmt.atl, indent_level + 1)
-
-def print_Menu(f, stmt, indent_level):
- f.write(u"menu:\n")
-
- if stmt.with_ is not None:
- indent(f, indent_level + 1)
- f.write(u"with %s\n" % (stmt.with_, ))
-
- if stmt.set is not None:
- indent(f, indent_level + 1)
- f.write(u"set %s\n" % (stmt.with_, ))
-
- for item in stmt.items:
- indent(f, indent_level + 1)
-
- # caption
- f.write(u"\"%s\"" % (escape_string(item[0]), ))
-
- if item[2] is not None:
- # condition
- if item[1] != 'True':
- f.write(u" if %s" % (item[1], ))
-
- f.write(u':\n')
-
- for inner_stmt in item[2]:
- print_statement(f, inner_stmt, indent_level + 2)
- else:
- f.write(u'\n')
-
-def print_Pass(f, stmt, indent_level):
- f.write(u"pass\n")
-
-def print_Call(f, stmt, indent_level):
- f.write(u"call ")
- if stmt.expression:
- f.write(u"expression %s" % (stmt.label, ))
- else:
- f.write(stmt.label)
-
- if stmt.arguments is not None:
- if stmt.expression:
- f.write(u"pass ")
- print_args(f, stmt.arguments)
-
- f.write(u'\n')
-
-def print_If(f, stmt, indent_level):
- f.write(u"if %s:\n" % (stmt.entries[0][0], ))
- for inner_stmt in stmt.entries[0][1]:
- print_statement(f, inner_stmt, indent_level + 1)
-
- if len(stmt.entries) >= 2:
- if stmt.entries[-1][0].strip() == 'True':
- else_entry = stmt.entries[-1]
- elif_entries = stmt.entries[1:-1]
- else:
- else_entry = None
- elif_entries = stmt.entries
-
- for case in elif_entries:
- indent(f, indent_level)
- f.write(u"elif %s:\n" % (case[0], ))
- for inner_stmt in case[1]:
- print_statement(f, inner_stmt, indent_level + 1)
-
- if else_entry is not None:
- indent(f, indent_level)
- f.write(u"else:\n")
- for inner_stmt in else_entry[1]:
- print_statement(f, inner_stmt, indent_level + 1)
-
-def print_EarlyPython(f, stmt, indent_level):
- print_Python(f, stmt, indent_level, early=True)
-
-# TODO extrapos, extrakw?
-def print_args(f, arginfo):
- if arginfo is None:
- return
-
- f.write(u"(")
-
- first = True
- for (name, val) in arginfo.arguments:
- if first:
- first = False
- else:
- f.write(u", ")
-
- if name is not None:
- f.write(u"%s = " % (name, ))
- f.write(val)
-
- f.write(u")")
-
-# TODO positional?
-def print_params(f, paraminfo):
- f.write(u"(")
-
- first = True
- for param in paraminfo.parameters:
- if first:
- first = False
- else:
- f.write(u", ")
-
- f.write(param[0])
-
- if (param[1] is not None) and ('None' not in param[1]):
- f.write(u" = %s" % param[1])
- if paraminfo.extrapos:
- f.write(u", ")
- f.write(u"*%s" % paraminfo.extrapos)
- if paraminfo.extrakw:
- f.write(u", ")
- f.write(u"**%s" % paraminfo.extrakw)
-
- f.write(u")")
-
-# Print while command, from http://forum.cheatengine.org/viewtopic.php?p=5377683
-def print_While(f, stmt, indent_level):
- f.write(u"while %s:\n" % (stmt.condition, ))
- for inner_stmt in stmt.block:
- print_statement(f, inner_stmt, indent_level + 1)
-
-# Print define command, by iAmGhost
-def print_Define(f, stmt, indent_level):
- f.write(u"define %s = %s\n" % (stmt.varname, stmt.code.source,))
-
-# Print Screen code (or at least code which does exactly the same. can't be picky, don't have source)
-# We'll read the ast out here, but leave the decompilation of the resulting python code to screendecompiler.py
-# It'd just bloat up this file
-def print_screen(f, stmt, indent_level):
- screen = stmt.screen
- # The creator of the python ast module also created a script to revert it.
- sourcecode = codegen.to_source(screen.code.source, u" "*4)
- # why suddenly ast in the source code field
- f.write(u"screen %s" % screen.name)
- if hasattr(screen, 'parameters') and screen.parameters:
- print_params(f, screen.parameters)
- f.write(u":\n")
- if screen.tag:
- indent(f, indent_level+1)
- f.write(u"tag %s\n" % screen.tag)
- if screen.zorder and screen.zorder != '0':
- indent(f, indent_level+1)
- f.write(u"zorder %s\n" % screen.zorder)
- if screen.modal:
- indent(f, indent_level+1)
- f.write(u"modal %s\n" % screen.modal)
- if screen.variant != "None":
- indent(f, indent_level+1)
- f.write(u"variant %s\n" % screen.variant)
- # actual screen decompilation is HARD
- if DECOMPILE_SCREENS:
- screendecompiler.print_screen(f, sourcecode, indent_level+1)
- else:
- indent(f, indent_level+1)
- f.write('python:\n')
- f.write('\n'.join([" "*(indent_level+2)+line for line in sourcecode.splitlines()]))
- f.write(u"\n")
-
-statement_printer_dict = {
- ast.Label: print_Label,
- ast.Say: print_Say,
- ast.Jump: print_Jump,
- ast.Scene: print_Scene,
- ast.With: print_With,
- ast.Show: print_Show,
- ast.Hide: print_Hide,
- ast.Python: print_Python,
- ast.Return: print_Return,
- ast.UserStatement: print_UserStatement,
- ast.Init: print_Init,
- ast.Image: print_Image,
- ast.Transform: print_Transform,
- ast.Menu: print_Menu,
- ast.Pass: print_Pass,
- ast.Call: print_Call,
- ast.If: print_If,
- ast.While: print_While,
- ast.Define: print_Define,
- ast.EarlyPython: print_EarlyPython,
- }
-if hasattr(ast, 'Screen'): #backwards compatability
- statement_printer_dict.update({ast.Screen: print_screen})
-
-def print_Unknown(f, stmt, indent_level):
- print "Unknown AST node: %s" % (type(stmt).__name__, )
- f.write(u"<<<UNKNOWN NODE %s>>>\n" % (type(stmt).__name__, ))
diff --git a/configure b/configure
index 291ce68..a039e8c 100755
--- a/configure
+++ b/configure
@@ -5,9 +5,9 @@ import re
import shlex
import shutil
import subprocess
-from sys import stderr
cmds = {}
+warnings = []
class CheckError(Exception):
pass
@@ -16,15 +16,31 @@ def checking(thing):
stderr.write("checking %s... " % thing)
stderr.flush()
-def check(name, flags=[], optional=False, var=None, run=True):
+def warn(string):
+ warnings.append(string)
+ stderr.write("WARNING: %s\n" % string)
+
+def check(name, why, flags=[], optional=False, var=None, run=True):
+ global warn
checking("for %s" % name)
var = var or name.upper()
- split = shlex.split(os.getenv(var) or name)
+ varvalue = os.getenv(var)
+ if varvalue == '':
+ stderr.write("skipping\n")
+ if not optional:
+ warn("%s is required to %s, the code will not fall back gracefully without it!" % (name, why))
+ return
+ elif varvalue is None:
+ varvalue = name
+ split = shlex.split(varvalue)
exe = shutil.which(split[0])
if not exe:
stderr.write("not found\n")
if not optional:
raise CheckError()
+ else:
+ warn("%s is recommended to %s." % (name, why))
+ return
stderr.write("%s\n" % exe)
cmd = [exe] + split[1:] + flags + shlex.split(os.getenv(var + "FLAGS") or "")
if run:
@@ -51,27 +67,34 @@ def ffmpeg_check(name, regex, checks, output):
stderr.write("no\n")
raise CheckError()
-try:
- check("zopfli", var="GZIP")
-except CheckError:
- check("gzip", ["-9"])
-
-check("apngasm", run=False)
-check("convert")
-check("cwebp", ["-quiet", "-alpha_cleanup", "-m", "6"])
-ffmpeg = check("ffmpeg", ["-v", "warning", "-y"], run=False)
-ffmpeg_formats = run_ffmpeg("-formats")
-ffmpeg_check("demuxing", "D.", ["matroska,webm", "ogg", "wav", "yuv4mpegpipe"], ffmpeg_formats)
-ffmpeg_check("muxing", ".E", ["ipod", "mp4", "ogg", "wav", "webm", "yuv4mpegpipe"], ffmpeg_formats)
-ffmpeg_check("decoding", ".{6}", ["mpeg4", "rawvideo", "pcm_s16le", "vorbis"], run_ffmpeg("-decoders"))
-ffmpeg_check("encoding", ".{6}", ["libx264", "rawvideo", "libtheora", "libvpx", "libvpx-vp9", "libfdk_aac", "libopus", "pcm_s16le"], run_ffmpeg("-encoders"))
-check("npm", ["--quiet"])
-check("webpmux")
-check("defluff", optional=True, run=False)
-check("pngquant", optional=True)
-check("zopflipng", optional=True)
-
-stderr.write("creating Makefile.inc\n")
-
-with open("Makefile.inc", "w") as f:
- f.write(''.join('%s := %s\n' % (k, subprocess.list2cmdline(cmds[k])) for k in cmds))
+if __name__ == "__main__":
+ # no, this line isn't bugged. really. examine check() and Makefile
+ if not check("zopfli", "compress gzip files better than gzip -9", optional=True, var="GZIP"):
+ check("gzip", "pre-compress the JSON files", ["-9"])
+
+ check("apngasm", "assemble the click-to-continue image", run=False)
+ check("convert", "perform miscellaneous actions on the images")
+ check("cwebp", "convert all images to WebP for webkit browsers", ["-quiet", "-alpha_cleanup", "-m", "6"])
+ ffmpeg = check("ffmpeg", "convert audio and video to HTML5 formats", ["-v", "warning", "-y"], run=False)
+ if ffmpeg:
+ ffmpeg_formats = run_ffmpeg("-formats")
+ ffmpeg_check("demuxing", "D.", ["matroska,webm", "ogg", "wav", "yuv4mpegpipe"], ffmpeg_formats)
+ ffmpeg_check("muxing", ".E", ["ipod", "mp4", "ogg", "wav", "webm", "yuv4mpegpipe"], ffmpeg_formats)
+ ffmpeg_check("decoding", ".{6}", ["mpeg4", "rawvideo", "pcm_s16le", "vorbis"], run_ffmpeg("-decoders"))
+ ffmpeg_check("encoding", ".{6}", ["libx264", "rawvideo", "libtheora", "libvpx", "libvpx-vp9", "libfdk_aac", "libopus", "pcm_s16le"], run_ffmpeg("-encoders"))
+ check("npm", "install uglifyjs", ["--quiet"])
+ check("webpmux", "assemble the WebP click-to-continue image")
+ check("defluff", "decrease the size of DEFLATE files including gzip and PNG files", optional=True, run=False)
+ check("pngquant", "quantize PNG images, improving compatibility and dramatically decreasing size", optional=True)
+ check("zopflipng", "recompress DEFLATE files including gzip and PNG files", optional=True)
+
+ stderr.write("creating Makefile.inc\n")
+
+ with open("Makefile.inc", "w") as f:
+ f.write(''.join('%s := %s\n' % (k, subprocess.list2cmdline(cmds[k])) for k in cmds))
+
+ if len(warnings):
+ stderr.write("Warnings during configuration:\n")
+ stderr.write('\n'.join(warnings) + '\n')
+
+ stderr.write("Run `make' now to build HTML5KS.\n")
diff --git a/fastclick b/fastclick
-Subproject d7727a10e538da46ce7a7ed86dc6f4be466dc06
+Subproject 3497d2e92ccc8a959c7efb326c0fc437302d5bc