# HG changeset patch # User Thibaut Girka # Date 1320151563 -3600 # Node ID 88361534c77e848f936e2b8a08952d83378dc579 # Parent df8b2ab5463926f88b086777b8dd13ff281cd56a Add some documentation (argh, so much left to document!) diff --git a/README b/README --- a/README +++ b/README @@ -28,3 +28,10 @@ Documentation: The code should be sufficiently documented for anyone interested to learn how the EoSD engine work, but additional documentation is available at: http://linkmauve.fr/doc/touhou/ + + + +Contact: +-------- + +You are welcome to join us at on jabber! diff --git a/pytouhou/__init__.py b/pytouhou/__init__.py --- a/pytouhou/__init__.py +++ b/pytouhou/__init__.py @@ -0,0 +1,13 @@ +"""Reimplementation of the Touhou engines. + +This package provides various classes to handle parts or the whole of Touhou +file formats and gameplay. + +Sub-packages: +formats -- file formats handling +game -- game logic +games -- game-specific classes +resource -- resource loading +utils -- various helpers and non Touhou-specific functions +vm -- virtual machines for enemies, etc. +""" diff --git a/pytouhou/formats/__init__.py b/pytouhou/formats/__init__.py --- a/pytouhou/formats/__init__.py +++ b/pytouhou/formats/__init__.py @@ -0,0 +1,5 @@ +"""Touhou games file formats handling. + +This package provides modules to handle the various proprietary file formats +used by Touhou games. +""" diff --git a/pytouhou/formats/anm0.py b/pytouhou/formats/anm0.py --- a/pytouhou/formats/anm0.py +++ b/pytouhou/formats/anm0.py @@ -12,6 +12,14 @@ ## GNU General Public License for more details. ## +"""ANM0 files handling. + +This module provides classes for handling the ANM0 file format. +The ANM0 format is a format used in Touhou 6: EoSD to describe sprites +and animations. +Almost everything rendered in the game is described by an ANM0 file. +""" + from struct import pack, unpack from pytouhou.utils.helpers import read_string, get_logger diff --git a/pytouhou/formats/ecl.py b/pytouhou/formats/ecl.py --- a/pytouhou/formats/ecl.py +++ b/pytouhou/formats/ecl.py @@ -12,6 +12,13 @@ ## GNU General Public License for more details. ## +"""ECL files handling. + +This module provides classes for handling the ECL file format. +The ECL format is a format used in Touhou 6: EoSD to script most of the gameplay +aspects of the game, such as enemy movements, attacks, and so on. +""" + import struct from struct import pack, unpack, calcsize @@ -20,6 +27,20 @@ from pytouhou.utils.helpers import get_l logger = get_logger(__name__) class ECL(object): + """Handle Touhou 6 ECL files. + + ECL files are binary script files used to describe the behavior of enemies. + They are basically composed of a header and two additional sections. + The first section is a list of subroutines, each composed of a list of timed + instructions. + The second section is a list of a different set of instructions describing + enemy waves, triggering dialogs and level completion. + + Instance variables: + main -- list of instructions describing waves and triggering dialogs + subs -- list of subroutines + """ + _instructions = {0: ('', 'noop?'), 1: ('I', 'delete?'), 2: ('Ii', 'relative_jump'), @@ -40,7 +61,7 @@ class ECL(object): 21: ('iff', 'substract_float'), 23: ('iff', 'divide_float'), 25: ('iffff', 'get_direction'), - 26: ('i', None), + 26: ('i', 'float_to_unit_circle'), #TODO: find a better name 27: ('ii', 'compare_ints'), 28: ('ff', 'compare_floats'), 29: ('ii', 'relative_jump_if_lower_than'), @@ -50,7 +71,7 @@ class ECL(object): 33: ('ii', 'relative_jump_if_greater_or_equal'), 34: ('ii', 'relative_jump_if_not_equal'), 35: ('iif', 'call'), - 36: ('', 'return?'), + 36: ('', 'return'), 39: ('iifii', 'call_if_equal'), 43: ('fff', 'set_position'), 45: ('ff', 'set_angle_and_speed'), @@ -81,18 +102,18 @@ class ECL(object): 79: ('', 'no_delay_attack'), 81: ('fff', 'set_bullet_launch_offset'), 82: ('iiiiffff', 'set_extended_bullet_attributes'), - 83: ('', None), + 83: ('', 'change_bullets_in_star_bonus'), 84: ('i', None), 85: ('hhffffffiiiiii', 'laser'), 86: ('hhffffffiiiiii', 'laser2'), 87: ('i', 'set_upcoming_id'), 88: ('if','alter_laser_angle'), - 90: ('iiii', None), - 92: ('i', None), + 90: ('iiii', 'translate_laser'), + 92: ('i', 'cancel_laser'), 93: ('hhs', 'set_spellcard'), 94: ('', 'end_spellcard'), - 95: ('ifffhhi', None), - 96: ('', None), + 95: ('ifffhhi', 'spawn_enemy'), + 96: ('', 'kill_all_enemies'), 97: ('i', 'set_anim'), 98: ('hhhhhxx', 'set_multiple_anims'), 99: ('ii', None), @@ -123,14 +144,14 @@ class ECL(object): 125: ('', None), 126: ('i', 'set_remaining_lives'), 127: ('i', None), - 128: ('i', None), + 128: ('i', 'set_smooth_disappear'), 129: ('ii', None), 130: ('i', None), - 131: ('ffiiii', None), - 132: ('i', None), + 131: ('ffiiii', 'set_difficulty_coeffs'), + 132: ('i', 'set_invisible'), 133: ('', None), 134: ('', None), - 135: ('i', None)} #TODO + 135: ('i', 'enable_spellcard_bonus')} #TODO _main_instructions = {0: ('fffhhI', 'spawn_enemy'), 2: ('fffhhI', 'spawn_enemy_mirrored'), @@ -149,6 +170,12 @@ class ECL(object): @classmethod def read(cls, file): + """Read an ECL file. + + Raise an exception if the file is invalid. + Return a ECL instance otherwise. + """ + sub_count, main_offset = unpack('