summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoremilybrooks <emilybrooksemilybrooks@gmail.com>2024-09-25 11:50:06 -0700
committerGitHub <noreply@github.com>2024-09-25 11:50:06 -0700
commit5fb92a5079f8e2ccf67d5593236a62dff6cd3638 (patch)
tree19a401e3fbf9dda42147198eb97c8990c2d44a22
parent35eba20abdd3f810a2f878edea37890858ffccc2 (diff)
properly handle swapped textures (#215)
* set up extension * extension works * make file stuff * everything works! * renamed script
-rw-r--r--Makefile3
-rw-r--r--src/objects/furniture/int_sum_clchest03/int_sum_clchest03.c14
-rw-r--r--src/objects/furniture/int_sum_hal_chest02/int_sum_hal_chest02.c12
-rw-r--r--tools/ci4swap_handler.py34
-rw-r--r--tools/splat_ext/ci4swap.py52
-rw-r--r--yamls/jp/assets.yaml26
6 files changed, 115 insertions, 26 deletions
diff --git a/Makefile b/Makefile
index df90e5e..5e58a57 100644
--- a/Makefile
+++ b/Makefile
@@ -368,6 +368,9 @@ $(BUILD_DIR)/%.o: %.c
$(RM_MDEBUG)
# Build C files from assets
+$(BUILD_DIR)/%.ci4swap.inc.c: %.ci4swap.png
+ $(PYTHON) tools/ci4swap_handler.py $< $@
+
$(BUILD_DIR)/%.inc.c: %.png
# File names are formatted as <file name>.<image format>.png
# The <image format> part is passed into pigment's format argument
diff --git a/src/objects/furniture/int_sum_clchest03/int_sum_clchest03.c b/src/objects/furniture/int_sum_clchest03/int_sum_clchest03.c
index af0c5ce..9a58576 100644
--- a/src/objects/furniture/int_sum_clchest03/int_sum_clchest03.c
+++ b/src/objects/furniture/int_sum_clchest03/int_sum_clchest03.c
@@ -2,25 +2,25 @@
#include "assets/jp/objects/furniture/int_sum_clchest03/int_sum_clchest03_pal01_pal.palette.inc.c"
u8 int_sum_clchest03_hiki_txt[] = {
-#include "assets/jp/objects/furniture/int_sum_clchest03/int_sum_clchest03_hiki_txt.ci4.inc.c"
+#include "assets/jp/objects/furniture/int_sum_clchest03/int_sum_clchest03_hiki_txt.ci4swap.inc.c"
};
u8 int_sum_clchest03_hikiura_txt[] = {
-#include "assets/jp/objects/furniture/int_sum_clchest03/int_sum_clchest03_hikiura_txt.ci4.inc.c"
+#include "assets/jp/objects/furniture/int_sum_clchest03/int_sum_clchest03_hikiura_txt.ci4swap.inc.c"
};
u8 int_sum_clchest03_top_txt[] = {
-#include "assets/jp/objects/furniture/int_sum_clchest03/int_sum_clchest03_top_txt.ci4.inc.c"
+#include "assets/jp/objects/furniture/int_sum_clchest03/int_sum_clchest03_top_txt.ci4swap.inc.c"
};
u8 int_sum_clchest03_stand_txt[] = {
-#include "assets/jp/objects/furniture/int_sum_clchest03/int_sum_clchest03_stand_txt.ci4.inc.c"
+#include "assets/jp/objects/furniture/int_sum_clchest03/int_sum_clchest03_stand_txt.ci4swap.inc.c"
};
u8 int_sum_clchest03_front_txt[] = {
-#include "assets/jp/objects/furniture/int_sum_clchest03/int_sum_clchest03_front_txt.ci4.inc.c"
+#include "assets/jp/objects/furniture/int_sum_clchest03/int_sum_clchest03_front_txt.ci4swap.inc.c"
};
u8 int_sum_clchest03_side_txt[] = {
-#include "assets/jp/objects/furniture/int_sum_clchest03/int_sum_clchest03_side_txt.ci4.inc.c"
+#include "assets/jp/objects/furniture/int_sum_clchest03/int_sum_clchest03_side_txt.ci4swap.inc.c"
};
u8 int_sum_clchest03_hisasi_txt[] = {
-#include "assets/jp/objects/furniture/int_sum_clchest03/int_sum_clchest03_hisasi_txt.ci4.inc.c"
+#include "assets/jp/objects/furniture/int_sum_clchest03/int_sum_clchest03_hisasi_txt.ci4swap.inc.c"
};
s32 pad15D0720[] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
diff --git a/src/objects/furniture/int_sum_hal_chest02/int_sum_hal_chest02.c b/src/objects/furniture/int_sum_hal_chest02/int_sum_hal_chest02.c
index f8340c8..a03e553 100644
--- a/src/objects/furniture/int_sum_hal_chest02/int_sum_hal_chest02.c
+++ b/src/objects/furniture/int_sum_hal_chest02/int_sum_hal_chest02.c
@@ -2,22 +2,22 @@
#include "assets/jp/objects/furniture/int_sum_hal_chest02/int_sum_hal_chest02_pal.palette.inc.c"
u8 int_sum_hal_chest02_hiki_tex_txt[] = {
-#include "assets/jp/objects/furniture/int_sum_hal_chest02/int_sum_hal_chest02_hiki_tex_txt.ci4.inc.c"
+#include "assets/jp/objects/furniture/int_sum_hal_chest02/int_sum_hal_chest02_hiki_tex_txt.ci4swap.inc.c"
};
u8 int_sum_hal_chest02_hiite_tex_txt[] = {
-#include "assets/jp/objects/furniture/int_sum_hal_chest02/int_sum_hal_chest02_hiite_tex_txt.ci4.inc.c"
+#include "assets/jp/objects/furniture/int_sum_hal_chest02/int_sum_hal_chest02_hiite_tex_txt.ci4swap.inc.c"
};
u8 int_sum_hal_chest02_top_tex_txt[] = {
-#include "assets/jp/objects/furniture/int_sum_hal_chest02/int_sum_hal_chest02_top_tex_txt.ci4.inc.c"
+#include "assets/jp/objects/furniture/int_sum_hal_chest02/int_sum_hal_chest02_top_tex_txt.ci4swap.inc.c"
};
u8 int_sum_hal_chest02_front_tex_txt[] = {
-#include "assets/jp/objects/furniture/int_sum_hal_chest02/int_sum_hal_chest02_front_tex_txt.ci4.inc.c"
+#include "assets/jp/objects/furniture/int_sum_hal_chest02/int_sum_hal_chest02_front_tex_txt.ci4swap.inc.c"
};
u8 int_sum_hal_chest02_back_tex_txt[] = {
-#include "assets/jp/objects/furniture/int_sum_hal_chest02/int_sum_hal_chest02_back_tex_txt.ci4.inc.c"
+#include "assets/jp/objects/furniture/int_sum_hal_chest02/int_sum_hal_chest02_back_tex_txt.ci4swap.inc.c"
};
u8 int_sum_hal_chest02_kuki_tex_txt[] = {
-#include "assets/jp/objects/furniture/int_sum_hal_chest02/int_sum_hal_chest02_kuki_tex_txt.ci4.inc.c"
+#include "assets/jp/objects/furniture/int_sum_hal_chest02/int_sum_hal_chest02_kuki_tex_txt.ci4swap.inc.c"
};
#include "assets/jp/objects/furniture/int_sum_hal_chest02/cKF_ckcb_r_int_sum_hal_chest02_tbl.inc.c"
#include "assets/jp/objects/furniture/int_sum_hal_chest02/cKF_kn_int_sum_hal_chest02_tbl.inc.c"
diff --git a/tools/ci4swap_handler.py b/tools/ci4swap_handler.py
new file mode 100644
index 0000000..7875a86
--- /dev/null
+++ b/tools/ci4swap_handler.py
@@ -0,0 +1,34 @@
+import argparse
+import subprocess
+import png
+import struct
+
+parser=argparse.ArgumentParser(description="Converts extracted texture png files to the swapped data that Animal Forest expects.")
+parser.add_argument("input")
+parser.add_argument("output")
+args=parser.parse_args()
+
+reader = png.Reader(filename=args.input)
+width, height, rows, info = reader.read()
+rowIndex: int = 0
+outputData: bytearray = bytearray()
+
+for row in rows:
+ if rowIndex % 2 == 0:
+ # odd row, just copy as is
+ outputData.extend(row)
+ else:
+ # even row, swap groups of 8 pixels, or 64 bits
+ for swapBlock in struct.iter_unpack(">QQ", row):
+ outputData.extend(struct.pack(">QQ", swapBlock[1], swapBlock[0]))
+
+ rowIndex += 1
+
+newPngPath = args.output[:-14] + "_swapped.png"
+output = open(newPngPath, 'wb')
+writer = png.Writer(width, height, **info)
+writer.write_array(output, outputData)
+output.close()
+
+# use pigment64 to convert it to .inc.c
+subprocess.run(["tools/pigment64/pigment64", "to-bin", "-f", "ci4", "--c-array", "-o", args.output, newPngPath])
diff --git a/tools/splat_ext/ci4swap.py b/tools/splat_ext/ci4swap.py
new file mode 100644
index 0000000..0e9171b
--- /dev/null
+++ b/tools/splat_ext/ci4swap.py
@@ -0,0 +1,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}") \ No newline at end of file
diff --git a/yamls/jp/assets.yaml b/yamls/jp/assets.yaml
index b018373..9543da6 100644
--- a/yamls/jp/assets.yaml
+++ b/yamls/jp/assets.yaml
@@ -12282,12 +12282,12 @@
name: int_sum_hal_chest02
subsegments:
- [0x15C8000, af_palette, int_sum_hal_chest02_pal]
- - [0x15C8020, ci4, int_sum_hal_chest02_hiki_tex_txt, 32, 32, int_sum_hal_chest02_pal]
- - [0x15C8220, ci4, int_sum_hal_chest02_hiite_tex_txt, 16, 16, int_sum_hal_chest02_pal]
- - [0x15C82A0, ci4, int_sum_hal_chest02_top_tex_txt, 16, 16, int_sum_hal_chest02_pal]
- - [0x15C8320, ci4, int_sum_hal_chest02_front_tex_txt, 32, 48, int_sum_hal_chest02_pal]
- - [0x15C8620, ci4, int_sum_hal_chest02_back_tex_txt, 16, 48, int_sum_hal_chest02_pal]
- - [0x15C87A0, ci4, int_sum_hal_chest02_kuki_tex_txt, 16, 16, int_sum_hal_chest02_pal]
+ - [0x15C8020, ci4swap, int_sum_hal_chest02_hiki_tex_txt, 32, 32, int_sum_hal_chest02_pal]
+ - [0x15C8220, ci4swap, int_sum_hal_chest02_hiite_tex_txt, 16, 16, int_sum_hal_chest02_pal]
+ - [0x15C82A0, ci4swap, int_sum_hal_chest02_top_tex_txt, 16, 16, int_sum_hal_chest02_pal]
+ - [0x15C8320, ci4swap, int_sum_hal_chest02_front_tex_txt, 32, 48, int_sum_hal_chest02_pal]
+ - [0x15C8620, ci4swap, int_sum_hal_chest02_back_tex_txt, 16, 48, int_sum_hal_chest02_pal]
+ - [0x15C87A0, ci4swap, int_sum_hal_chest02_kuki_tex_txt, 16, 16, int_sum_hal_chest02_pal]
- [0x15C8820, ckf_ckcb, cKF_ckcb_r_int_sum_hal_chest02_tbl]
- [0x15C8824, ckf_kn, cKF_kn_int_sum_hal_chest02_tbl]
- [0x15C8830, ckf_c, cKF_c_int_sum_hal_chest02_tbl]
@@ -12359,13 +12359,13 @@
name: int_sum_clchest03
subsegments:
- [0x15D0000, af_palette, int_sum_clchest03_pal01_pal]
- - [0x15D0020, ci4, int_sum_clchest03_hiki_txt, 16, 32, int_sum_clchest03_pal01_pal]
- - [0x15D0120, ci4, int_sum_clchest03_hikiura_txt, 16, 32, int_sum_clchest03_pal01_pal]
- - [0x15D0220, ci4, int_sum_clchest03_top_txt, 16, 32, int_sum_clchest03_pal01_pal]
- - [0x15D0320, ci4, int_sum_clchest03_stand_txt, 16, 16, int_sum_clchest03_pal01_pal]
- - [0x15D03A0, ci4, int_sum_clchest03_front_txt, 16, 48, int_sum_clchest03_pal01_pal]
- - [0x15D0520, ci4, int_sum_clchest03_side_txt, 16, 48, int_sum_clchest03_pal01_pal]
- - [0x15D06A0, ci4, int_sum_clchest03_hisasi_txt, 16, 16, int_sum_clchest03_pal01_pal]
+ - [0x15D0020, ci4swap, int_sum_clchest03_hiki_txt, 16, 32, int_sum_clchest03_pal01_pal]
+ - [0x15D0120, ci4swap, int_sum_clchest03_hikiura_txt, 16, 32, int_sum_clchest03_pal01_pal]
+ - [0x15D0220, ci4swap, int_sum_clchest03_top_txt, 16, 32, int_sum_clchest03_pal01_pal]
+ - [0x15D0320, ci4swap, int_sum_clchest03_stand_txt, 16, 16, int_sum_clchest03_pal01_pal]
+ - [0x15D03A0, ci4swap, int_sum_clchest03_front_txt, 16, 48, int_sum_clchest03_pal01_pal]
+ - [0x15D0520, ci4swap, int_sum_clchest03_side_txt, 16, 48, int_sum_clchest03_pal01_pal]
+ - [0x15D06A0, ci4swap, int_sum_clchest03_hisasi_txt, 16, 16, int_sum_clchest03_pal01_pal]
- [0x15D0720, pad]
- [0x15D0820, ckf_ckcb, cKF_ckcb_r_int_sum_clchest03_tbl]
- [0x15D0824, ckf_kn, cKF_kn_int_sum_clchest03_tbl]