#!/usr/bin/env python """ Generate HTML from a subset of rpy """ import fileinput import sys quick_help_text = """ This is a 'kinetic visual novel'. To advance in the
story, just click the screen. There are no decisions
to make, items to collect, or minigames to play. """ container_text = """ {title}
""" header = """
""" character_names = ['pirogoeth'] images_used = [ "assets/character/pirogoeth/pirogoeth_pfront_crouching_m0.png", "assets/character/pirogoeth/pirogoeth_pfront_crouching_m1.png", "assets/character/pirogoeth/pirogoeth_pfront_lungingclose_m1.png", "assets/character/pirogoeth/pirogoeth_pfront_lunging_m1.png", "assets/character/pirogoeth/pirogoeth_pfront_nonplussed_m0.png", "assets/character/pirogoeth/pirogoeth_pfront_nonplussed_m1.png", "assets/character/pirogoeth/pirogoeth_pleft_headdown_lookingaside_m0.png", "assets/character/pirogoeth/pirogoeth_pleft_headdown_lookingaside_m1.png", "assets/character/pirogoeth/pirogoeth_pleft_headdown_lookingfront_m0.png", "assets/character/pirogoeth/pirogoeth_pleft_headdown_lookingfront_m1.png", "assets/character/pirogoeth/pirogoeth_pleft_headstraight_lookingaside_m0.png", "assets/character/pirogoeth/pirogoeth_pleft_headstraight_lookingaside_m1.png", "assets/character/pirogoeth/pirogoeth_pleft_headstraight_lookingfront_m0.png", "assets/character/pirogoeth/pirogoeth_pleft_headstraight_lookingfront_m1.png", "assets/character/pirogoeth/pirogoeth_pleft_headstraight_lookingstraightangry_m1.png", "assets/character/pirogoeth/pirogoeth_pleft_headstraight_lookingstraight_m0.png", "assets/character/pirogoeth/pirogoeth_pleft_headstraight_lookingstraight_m1.png", "assets/character/pirogoeth/pirogoeth_pleft_headstraight_lookingstraightsadface_m1.png", "assets/character/pirogoeth/pirogoeth_pleft_headstraight_lookingstraightwideeyed_m0.png", "assets/character/pirogoeth/pirogoeth_pleft_headstraight_lookingstraightwideeyed_m1.png", "assets/character/pirogoeth/pirogoeth_pright_lookingoff_m1.png", "assets/character/pirogoeth/pirogoeth_pright_lookingup_m0.png", "assets/character/pirogoeth/pirogoeth_pright_lookingup_m1.png", "assets/character/pirogoeth/pirogoeth_pright_turning_m0.png", "assets/character/pirogoeth/pirogoeth_pright_turning_m1.png", "assets/background/market_empty.jpg", "assets/background/market_busy.jpg", "assets/background/flashback/flashbackCamping.jpg", "assets/background/flashback/flashbackDancing.jpg", "assets/background/flashback/flashbackDarkBG.png", "assets/background/flashback/flashbackDomina.jpg", "assets/background/flashback/flashbackEscaping.jpg", "assets/background/flashback/flashbackFalling.jpg", "assets/background/flashback/flashbackHunting.jpg", ] next_classes = None scene = "black" frame_count = 0 characters = {} expressions = [] last_content = "" last_scene = "" last_expression = "" audio_background = None output_buffer = '' current_file_num = 0 def format_filename(file_num): t = fileinput.filename().replace('.webvn','') if file_num != -1: t += '_' + str(file_num) t += '.htm' return t def output_append(string): global output_buffer output_buffer += string def output_buffer_write(name): global output_buffer output_buffer = output_buffer.replace('_XXX_','') with open(name, 'w') as out: out.write(output_buffer) output_buffer = '' def output_replace_last_link(new_target): global output_buffer parts = output_buffer.split('_XXX_') x = parts[:-1] output_buffer = "_XXX_".join(x) + new_target + parts[-1] def next_file(): global current_file_num print_preload() print_footer() output_buffer_write(format_filename(current_file_num)) current_file_num += 1 output_append(header) def wordbox(text): return """
{0}
""".format(text) def wordbubble(text): return """
{0}
""".format(text) def whitetext(text): global scene if scene != "black": return wordbox(text) line_map = { 1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five' } line_count = len(text.splitlines()) return """
{1}
""".format(line_map[line_count] if line_count in line_map else "one", text) def switch_mouth(character, newmouth): if '_m1' in characters[character]['pose']: characters[character]['pose'] = characters[character]['pose'].replace('_m1','_'+newmouth) elif '_m0' in characters[character]['pose']: characters[character]['pose'] = characters[character]['pose'].replace('_m0','_'+newmouth) def switch_pose(character, newpose): if '_m1' in characters[character]['pose']: characters[character]['pose'] = newpose + '_m1' elif '_m0' in characters[character]['pose']: characters[character]['pose'] = newpose + '_m0' def characterbubble(character, text): if text.startswith('"'): text = "m0 " + text mouth, _, text = text.partition(" ") if not (mouth == 'm1' or mouth == 'm0'): switch_pose(character, mouth) mouth, _, text = text.partition(" ") text = eval(text) switch_mouth(character, mouth) return """
{0}
""".format(text) def character(name, extra=None): attributes = characters[name] return """
""".format(name, attributes['pose'], attributes['position']) def make_expression(expression): return """
""".format(expression) def stage(contents): global scene, next_classes, characters, expressions, last_content, last_scene, last_expression chars = "" for k,v in characters.iteritems(): chars += character(k) extra_classes = "scene-{0}".format(scene if scene else "black") my_expressions = "\n".join([make_expression(x) for x in expressions]) out = """
{4} {7}
{1} {6} {2}
""".format(extra_classes, chars, "\n".join(contents), last_scene, last_content, next_classes if next_classes else "fade-in", my_expressions, last_expression) last_content = chars + "\n".join(contents) last_scene = extra_classes last_expression = my_expressions return out def print_frame(content): global frame_count frame_count += 1 output_append("""
{0}
""".format(content.strip(), frame_count - 1, frame_count)) def process(line): global scene, next_classes, characters, expressions, audio_background c, _, rest = line.strip().partition(" ") if c == "#WEB:": c, _, rest = rest.strip().partition(" ") if line.strip().startswith('"'): print_frame(stage([whitetext(eval(line.strip()))])) elif c == "class": next_classes = rest elif c == "expression": expressions = rest.split(" ") elif c == "moh": print_frame(stage([wordbubble(eval(rest))])) elif c == "pirogoeth": print_frame(stage([characterbubble("pirogoeth", rest)])) elif c == "scene": scene = rest.split()[-1] characters.clear() del expressions[:] elif c == "pause": # Can't pause, can insert an interstitial print_frame(stage([""])) elif c == "show": character = rest.split()[0].replace(":","") if character not in character_names: print >>sys.stderr, "Unknown character:", character return if character not in characters: characters[character] = {'pose': None, 'position': 'center'} attributes = rest.split()[1:] if len(attributes) == 1 and attributes[0] == 'm1': switch_mouth(character, 'm1') return if len(attributes) == 1 and attributes[0] == 'm0': switch_mouth(character, 'm0') return if len(attributes) == 1 and not (attributes[0].endswith('_m1') or attributes[0].endswith('_m0')): switch_pose(character, attributes[0]) return if len(attributes) > 0: characters[character]['pose'] = attributes[0] if len(attributes) > 1: characters[character]['position'] = attributes[1] elif c == "hide": character = rest.split()[0] if character in characters: del charactersc[character] elif c == "music": output_replace_last_link(format_filename(current_file_num + 1)) next_file() if rest.split()[0] == 'stop': audio_background = None else: audio_background = eval(rest) def print_footer(): output_append("\n
\n") if audio_background: output_append("""