Loading

Paste #pkerltwnq

  1. diff --git a/nml/actions/real_sprite.py b/nml/actions/real_sprite.py
  2. --- a/nml/actions/real_sprite.py
  3. +++ b/nml/actions/real_sprite.py
  4. @@ -160,6 +160,9 @@ class RealSprite(object):
  5.  
  6.      @ivar flags: Cropping/warning flags.
  7.      @type flags: L{expression.ConstantNumeric}
  8. +
  9. +    @ivar pos: Position of creation of the sprite, if available.
  10. +    @type pos: L{Position}
  11.      """
  12.  
  13.      def __init__(self, param_list = None, label = None):
  14. @@ -170,6 +173,7 @@ class RealSprite(object):
  15.          self.ypos = None
  16.          self.xsize = None
  17.          self.ysize = None
  18. +        self.pos = None
  19.  
  20.      def debug_print(self, indentation):
  21.          generic.print_dbg(indentation, 'Real sprite, parameters:')
  22. @@ -249,6 +253,13 @@ class RealSprite(object):
  23.          return (rgb_file, rgb_rect, mask_file, mask_rect, do_crop)
  24.  
  25.  class SpriteAction(base_action.BaseAction):
  26. +    """
  27. +    @ivar sprite_num: Number of the sprite, or C{None} if not decided yet.
  28. +    @type sprite_num: C{int} or C{None}
  29. +
  30. +    @ivar last: Whether this sprite action is the last of a series.
  31. +    @type last: C{bool}
  32. +    """
  33.      def __init__(self):
  34.          self.sprite_num = None
  35.          self.last = False
  36. @@ -493,7 +504,7 @@ def parse_sprite_data(sprite_container):
  37.      first = True
  38.  
  39.      for sprite_data in all_sprite_data:
  40. -        sprite_list, default_file, default_mask_file, zoom_level, bit_depth = sprite_data
  41. +        sprite_list, default_file, default_mask_file, pos, zoom_level, bit_depth = sprite_data
  42.          new_sprite_list = parse_sprite_list(sprite_list, default_file, default_mask_file)
  43.          if not first and len(new_sprite_list) != len(action_list):
  44.              msg = "Expected {:d} alternative sprites for {} '{}', got {:d}."
  45. @@ -507,6 +518,7 @@ def parse_sprite_data(sprite_container):
  46.                  raise generic.ScriptError("Mask file may only be specified for 32bpp sprites.", sprite.mask_file.pos)
  47.              if first:
  48.                  if isinstance(sprite, RealSprite):
  49. +                    sprite.pos = pos
  50.                      action_list.append(RealSpriteAction())
  51.                  else:
  52.                      assert isinstance(sprite, RecolourSprite)
  53. diff --git a/nml/ast/sprite_container.py b/nml/ast/sprite_container.py
  54. --- a/nml/ast/sprite_container.py
  55. +++ b/nml/ast/sprite_container.py
  56. @@ -28,7 +28,7 @@ class SpriteContainer(object):
  57.      @type block_name: L{Identifier}, or C{None} if N/A
  58.  
  59.      @ivar sprite_data: Mapping of (zoom level, bit-depth) to (sprite list, default file)
  60. -    @type sprite_data: C{dict} that maps (C{tuple} of (C{int}, C{int})) to (C{tuple} of (C{list} of (L{RealSprite}, L{RecolourSprite} or L{TemplateUsage}), L{StringLiteral} or C{None}))
  61. +    @type sprite_data: C{dict} that maps (C{tuple} of (C{int}, C{int})) to (C{tuple} of (C{list} of (L{RealSprite}, L{RecolourSprite} or L{TemplateUsage}), L{StringLiteral} or C{None}, L{Position}))
  62.      """
  63.      sprite_blocks = {}
  64.  
  65. @@ -50,14 +50,17 @@ class SpriteContainer(object):
  66.                     "level / bit depth combination. This data will be overridden.")
  67.              msg = msg.format(self.block_type, self.block_name.value)
  68.              generic.print_warning(msg, pos)
  69. -        self.sprite_data[key] = (sprite_list, default_file, default_mask_file)
  70. +        self.sprite_data[key] = (sprite_list, default_file, default_mask_file, pos)
  71.  
  72.      def get_all_sprite_data(self):
  73.          """
  74. -        Get all sprite data as a list of 5-tuples (sprite_list, default_file, default_mask_file, zoom_level, bit_depth)
  75. -        Sorting makes sure that the order is consistent, and that the normal zoom, 8bpp sprites appear first
  76. +        Get all sprite data.
  77. +        Sorting makes sure that the order is consistent, and that the normal zoom, 8bpp sprites appear first.
  78. +
  79. +        @return: List of 6-tuples (sprite_list, default_file, default_mask_file, position, zoom_level, bit_depth).
  80. +        @rtype:  C{list} of C{tuple} of (C{list} of (L{RealSprite}, L{RecolourSprite} or L{TemplateUsage}), L{StringLiteral} or C{None}, L{Position}, C{int}, C{int})
  81.          """
  82. -        return [(self.sprite_data[key][0], self.sprite_data[key][1], self.sprite_data[key][2], key[0], key[1]) for key in sorted(self.sprite_data)]
  83. +        return [val + key for key, val in sorted(self.sprite_data.items())]
  84.  
  85.      @classmethod
  86.      def resolve_sprite_block(cls, block_name):
  87. diff --git a/nml/generic.py b/nml/generic.py
  88. --- a/nml/generic.py
  89. +++ b/nml/generic.py
  90. @@ -139,8 +139,10 @@ class ImageFilePosition(Position):
  91.      """
  92.      Generic (not position-dependant) error with an image file
  93.      """
  94. -    def __init__(self, filename):
  95. -        Position.__init__(self, filename, [])
  96. +    def __init__(self, filename, pos = None):
  97. +        poslist = []
  98. +        if pos is not None: poslist.append(pos)
  99. +        Position.__init__(self, filename, poslist)
  100.  
  101.      def __str__(self):
  102.          return 'Image file "{}"'.format(self.filename)
  103. @@ -181,8 +183,8 @@ class RangeError(ScriptError):
  104.          ScriptError.__init__(self, name + " out of range " + str(min_value) + ".." + str(max_value) + ", encountered " + str(value), pos)
  105.  
  106.  class ImageError(ScriptError):
  107. -    def __init__(self, value, filename):
  108. -        ScriptError.__init__(self, value, ImageFilePosition(filename))
  109. +    def __init__(self, value, filename, pos = None):
  110. +        ScriptError.__init__(self, value, ImageFilePosition(filename, pos))
  111.  
  112.  class OnlyOnceError(ScriptError):
  113.      """
  114. diff --git a/nml/spriteencoder.py b/nml/spriteencoder.py
  115. --- a/nml/spriteencoder.py
  116. +++ b/nml/spriteencoder.py
  117. @@ -237,6 +237,9 @@ class SpriteEncoder(object):
  118.              filename_32bpp = sprite_info.file
  119.              filename_8bpp = sprite_info.mask_file
  120.  
  121. +        pos = sprite_info.pos
  122. +        if pos is None: pos = sprite_info.file.pos
  123. +
  124.          # Get initial info_byte and dimensions from sprite_info.
  125.          # These values will be changed depending on cropping and compression.
  126.          info_byte = INFO_NOCROP if (sprite_info.flags.value & real_sprite.FLAG_NOCROP) != 0 else 0
  127. @@ -263,14 +266,14 @@ class SpriteEncoder(object):
  128.          if filename_32bpp is not None:
  129.              im = self.open_image_file(filename_32bpp.value)
  130.              if im.mode not in ("RGB", "RGBA"):
  131. -                raise generic.ImageError("32bpp image is not a full colour RGB(A) image.", filename_32bpp.value)
  132. +                raise generic.ImageError("32bpp image is not a full colour RGB(A) image.", filename_32bpp.value, pos)
  133.              info_byte |= INFO_RGB
  134.              if im.mode == "RGBA":
  135.                  info_byte |= INFO_ALPHA
  136.  
  137.              (im_width, im_height) = im.size
  138.              if x < 0 or y < 0 or x + size_x > im_width or y + size_y > im_height:
  139. -                raise generic.ScriptError("Read beyond bounds of image file '{}'".format(filename_32bpp.value), filename_32bpp.pos)
  140. +                raise generic.ScriptError("Read beyond bounds of image file '{}'".format(filename_32bpp.value), pos)
  141.              sprite = im.crop((x, y, x + size_x, y + size_y))
  142.              rgb_sprite_data = sprite.tostring()
  143.  
  144. @@ -281,13 +284,13 @@ class SpriteEncoder(object):
  145.          if filename_8bpp is not None:
  146.              mask_im = self.open_image_file(filename_8bpp.value)
  147.              if mask_im.mode != "P":
  148. -                raise generic.ImageError("8bpp image does not have a palette", filename_8bpp.value)
  149. +                raise generic.ImageError("8bpp image does not have a palette", filename_8bpp.value, pos)
  150.              im_mask_pal = palette.validate_palette(mask_im, filename_8bpp.value)
  151.              info_byte |= INFO_PAL
  152.  
  153.              (im_width, im_height) = mask_im.size
  154.              if mask_x < 0 or mask_y < 0 or mask_x + size_x > im_width or mask_y + size_y > im_height:
  155. -                raise generic.ScriptError("Read beyond bounds of image file '{}'".format(filename_8bpp.value), filename_8bpp.pos)
  156. +                raise generic.ScriptError("Read beyond bounds of image file '{}'".format(filename_8bpp.value), pos)
  157.              mask_sprite = mask_im.crop((mask_x, mask_y, mask_x + size_x, mask_y + size_y))
  158.  
  159.              mask_sprite_data = self.palconvert(mask_sprite.tostring(), im_mask_pal)

Comments