1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
from typing import TYPE_CHECKING
from splat.util import log, options
from n64img.image import CI4
from splat.segtypes.n64.ci import N64SegCi
import struct
if TYPE_CHECKING:
from splat.segtypes.n64.palette import N64SegPalette
# CI4 texture but on even rows every 32 bits of data are swapped
class N64SegCi4swap(N64SegCi):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs, img_cls=CI4)
def split(self, rom_bytes):
assert self.palettes is not None
if len(self.palettes) == 0:
# TODO: output with blank palette
log.error(
f"no palettes have been mapped to ci segment `{self.name}`\n(hint: add a palette segment with the same name or use the `palettes:` field of this segment to specify palettes by name')"
)
assert isinstance(self.rom_start, int)
assert isinstance(self.rom_end, int)
data: bytes = rom_bytes[self.rom_start : self.rom_end]
rowLength: int = self.width // 2 # in bytes
outputData:bytearray = bytearray()
for rowIndex in range(self.height):
rowStart: int = rowIndex * rowLength
rowEnd: int = (rowIndex + 1) * rowLength
rowData: bytes = data[rowStart:rowEnd]
if rowIndex % 2 == 0:
# odd row, just copy as is
outputData.extend(rowData)
else:
# even row, swap groups of 32 bits
for swapBlock in struct.iter_unpack(">II", rowData):
outputData.extend(struct.pack(">II", swapBlock[1], swapBlock[0]))
self.n64img.data = outputData
for palette in self.palettes:
path = self.out_path_pal(palette.name)
path.parent.mkdir(parents=True, exist_ok=True)
self.n64img.palette = palette.parse_palette(rom_bytes)
self.n64img.write(path)
self.log(f"Wrote {path.name} to {path}")
|