Skip to content

Commit

Permalink
Use construct for parsing.
Browse files Browse the repository at this point in the history
cpac stuff is still done without construct because I can't figure out
how to make it into a struct and it's NOT IMPORTANT RIGHT NOW.
  • Loading branch information
CatTrinket committed Mar 19, 2012
1 parent 4ca1984 commit ab76646
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 29 deletions.
54 changes: 32 additions & 22 deletions formats.py
Original file line number Diff line number Diff line change
@@ -1,38 +1,49 @@
from collections import namedtuple
from struct import unpack

from construct import *

### sprite things

class NTFP():
class NTFPAdapter(Adapter):
"""A DS palette entry.
RGBA, five bits per colour channel and one bit for transparency.
"""

def __init__(self, color):
color, = unpack('<H', color)
def _encode(self, rgba, context):
return rgba.r | rgba.g << 5 | rgba.b << 10 | rgba.a << 15

def _decode(self, color, context):
return Container(
r=color & 0x1f,
g=color >> 5 & 0x1f,
b=color >> 10 & 0x1f,
a=bool(color >> 15)
)

self.r = color & 0x1f
self.g = color >> 5 & 0x1f
self.b = color >> 10 & 0x1f
self.a = color >> 15
ntfp = NTFPAdapter(ULInt16('color'))
palette = GreedyRepeater(ntfp)

class NTFS():

class NTFSAdapter(Adapter):
"""A single tile in a screen.
No relation to the filesystem of the same name.
"""

def __init__(self, tile):
tile, = unpack('<H', tile)
def _encode(self, obj, context):
return obj.tile | obj.transformation << 10 | obj.palette << 12

self.palette = tile >> 12
self.transformation = tile >> 10 & 0x3
self.tile = tile & 0x3ff
def _decode(self, obj, context):
return Container(
palette=obj >> 12,
transformation=obj >> 10 & 0x3,
tile=obj & 0x3ff
)

if self.transformation == 3:
# XXX Is this actually invalid or does it just do both flips?
raise ValueError('invalid NTFS transformation')
ntfs = NTFSAdapter(ULInt16('tile'))
ntfs_repeater = GreedyRepeater(ntfs)

class Screen():
"""Data to put together a sprite that takes up the entire screen.
Expand All @@ -41,11 +52,7 @@ class Screen():
"""

def __init__(self, source):
self.ntfs = []

while source:
self.ntfs.append(NTFS(source[:2]))
source = source[2:]
self.ntfs = ntfs_repeater.parse(source)

def image(self, palettes, tiles):
"""Actually put together the sprite."""
Expand All @@ -70,14 +77,17 @@ def image(self, palettes, tiles):
# Flip along the y axis
x = 7 - pixel_num % 8 + tile_x * 8
y = pixel_num // 8 + tile_y * 8
else:
# XXX Is this actually invalid or does it just do both flips?
raise ValueError('invalid NTFS transformation')

pixels[y][x] = palettes[tile.palette][pixel]

return pixels


### cpac stuff
# XXX Turn these into pretty classes, too
# XXX Turn these into pretty structs, too

CPACSection = namedtuple('CPACSection', ['offset', 'length'])

Expand Down
10 changes: 3 additions & 7 deletions sprites.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from io import BytesIO
from struct import unpack

from formats import NTFP, NTFS, Screen, parse_cpac
from formats import palette, Screen, parse_cpac
from lzss3 import decompress

def split_into_tiles(data):
Expand All @@ -25,11 +25,7 @@ def split_into_tiles(data):
# Rip a palette that goes with the Capcom logo
data = BytesIO(data_sections[0])
data.seek(0x2d80)
palette = []

for color in range(0x100):
palette.append(NTFP(data.read(2)))

capcom_palette = palette.parse(data.read(0x200))

# Rip the Capcom logo
data = BytesIO(data_sections[2])
Expand All @@ -41,7 +37,7 @@ def split_into_tiles(data):
data.seek(0xa00 + 0xde8)
screen = Screen(decompress(data))

image = screen.image([palette], tiles)
image = screen.image([capcom_palette], tiles)

with open('/tmp/logo.ppm', 'w') as output:
# PPM header
Expand Down

0 comments on commit ab76646

Please sign in to comment.