mirror of
https://github.com/pmret/papermario.git
synced 2024-11-08 12:02:30 +01:00
More image splits (#272)
* A number of new image splits * Address comments. * git subrepo pull --force --branch=imgflip tools/splat subrepo: subdir: "tools/splat" merged: "9caaa45df9" upstream: origin: "https://github.com/ethteck/splat.git" branch: "imgflip" commit: "9caaa45df9" git-subrepo: version: "0.4.3" origin: "???" commit: "???" * use flip_y over flip * git subrepo pull --force --branch=imgflip tools/splat subrepo: subdir: "tools/splat" merged: "ef663ec0d5" upstream: origin: "https://github.com/ethteck/splat.git" branch: "imgflip" commit: "ef663ec0d5" git-subrepo: version: "0.4.3" origin: "???" commit: "???" * use flip_y * git subrepo pull --force --branch=imgflip tools/splat subrepo: subdir: "tools/splat" merged: "3144dc17f6" upstream: origin: "https://github.com/ethteck/splat.git" branch: "imgflip" commit: "3144dc17f6" git-subrepo: version: "0.4.3" origin: "???" commit: "???" Co-authored-by: JoshDuMan <Joshua.Shoup.1996@gmail.com>
This commit is contained in:
parent
a3e4140101
commit
9900e9a2b8
@ -50,8 +50,14 @@ class Converter():
|
||||
self.mode = mode
|
||||
self.infile = infile
|
||||
self.outfile = outfile
|
||||
self.flip_x = "--flip-x" in argv
|
||||
self.flip_y = "--flip-y" in argv
|
||||
|
||||
if self.flip_y:
|
||||
print(self.infile)
|
||||
|
||||
assert self.flip_x == False, "flip_x is not supported"
|
||||
|
||||
self.warned = False
|
||||
|
||||
def warn(self, msg):
|
||||
@ -250,7 +256,7 @@ class Converter():
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(argv) < 4:
|
||||
print("usage: build.py MODE INFILE OUTFILE [--flip-y]")
|
||||
print("usage: build.py MODE INFILE OUTFILE [--flip-x] [--flip-y]")
|
||||
exit(1)
|
||||
|
||||
Converter(*argv[1:]).convert()
|
||||
|
@ -5,8 +5,8 @@
|
||||
;
|
||||
[subrepo]
|
||||
remote = https://github.com/ethteck/splat.git
|
||||
branch = master
|
||||
commit = 5e36c4555865e8192653217ca75afe0da661651a
|
||||
parent = e7de26b831ba89b66285a4847c8c28e562f19ca2
|
||||
branch = imgflip
|
||||
commit = 3144dc17f6fd77211e016cfbbc6a705f59b838e0
|
||||
parent = 70e14bea15b1374095da723425d9b59a2ffb5915
|
||||
method = merge
|
||||
cmdver = 0.4.3
|
||||
|
@ -1,6 +1,14 @@
|
||||
# splat Release Notes
|
||||
|
||||
## 0.7: The Path Update
|
||||
## 0.7.1
|
||||
|
||||
* Image segment changes:
|
||||
* Added `flip_x` and `flip_y` boolean parameters to replace `flip`.
|
||||
* `flip` is deprecated and will produce a warning when used.
|
||||
* Fixed flipping of `ci4` and `ci8` images.
|
||||
* Fixed `extract: false` (and `start: auto`) behaviour.
|
||||
|
||||
## 0.7.0: The Path Update
|
||||
|
||||
* Significantly better performance, especially when using the cache feature (`--use-cache` CLI arg).
|
||||
* BREAKING: Some cli args for splat have been renamed. Please consult the usage output (-h or no args) for more information.
|
||||
|
@ -35,11 +35,8 @@ class LinkerEntry:
|
||||
def __init__(self, segment: Segment, src_paths: List[Path], object_path: Path, section: str):
|
||||
self.segment = segment
|
||||
self.src_paths = [clean_up_path(p) for p in src_paths]
|
||||
self.object_path = path_to_object_path(object_path)
|
||||
self.section = section
|
||||
if self.section == "linker":
|
||||
self.object_path = None
|
||||
else:
|
||||
self.object_path = path_to_object_path(object_path)
|
||||
|
||||
class LinkerWriter():
|
||||
def __init__(self):
|
||||
@ -65,7 +62,6 @@ class LinkerWriter():
|
||||
if entry.section == "linker": # TODO: isinstance is preferable
|
||||
self._end_block()
|
||||
self._begin_segment(entry.segment)
|
||||
continue
|
||||
|
||||
start = entry.segment.rom_start
|
||||
if isinstance(start, int):
|
||||
|
@ -27,7 +27,7 @@ class N64SegAsm(N64SegCodeSubsegment):
|
||||
|
||||
def scan(self, rom_bytes: bytes):
|
||||
if self.rom_start != "auto" and self.rom_end != "auto" and self.rom_start != self.rom_end:
|
||||
self.funcs_text = self.disassemble_code(rom_bytes, options.get("asm_endlabels", False))
|
||||
self.funcs_text = self.disassemble_code(rom_bytes)
|
||||
|
||||
def split(self, rom_bytes: bytes):
|
||||
if not self.rom_start == self.rom_end:
|
||||
|
@ -10,7 +10,7 @@ from util import options
|
||||
|
||||
class N64SegC(N64SegCodeSubsegment):
|
||||
defined_funcs: Set[str] = set()
|
||||
|
||||
|
||||
STRIP_C_COMMENTS_RE = re.compile(
|
||||
r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
|
||||
re.DOTALL | re.MULTILINE
|
||||
@ -135,7 +135,7 @@ class N64SegC(N64SegCodeSubsegment):
|
||||
c_lines = self.get_c_preamble()
|
||||
|
||||
for func in funcs_text:
|
||||
func_name = self.parent.get_symbol(func, type="func", local_only=True).name
|
||||
func_name = self.get_symbol(func, type="func", local_only=True).name
|
||||
if options.get_compiler() == "GCC":
|
||||
c_lines.append("INCLUDE_ASM(s32, \"{}\", {});".format(self.name, func_name))
|
||||
else:
|
||||
|
@ -1,11 +1,12 @@
|
||||
from segtypes.n64.ci8 import N64SegCi8
|
||||
from util import iter
|
||||
|
||||
class N64SegCi4(N64SegCi8):
|
||||
@staticmethod
|
||||
def parse_image(data, width, height, flip_h=False, flip_v=False):
|
||||
img_data = bytearray()
|
||||
|
||||
for i in range(width * height // 2):
|
||||
for x, y, i in iter.iter_image_indexes(width, height, 0.5, 1, flip_h, flip_v):
|
||||
img_data.append(data[i] >> 4)
|
||||
img_data.append(data[i] & 0xF)
|
||||
|
||||
|
@ -3,6 +3,7 @@ from segtypes.n64.rgba16 import N64SegRgba16
|
||||
import png
|
||||
from util import log
|
||||
from util import options
|
||||
from util import iter
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from segtypes.n64.palette import N64SegPalette as Palette
|
||||
@ -35,7 +36,19 @@ class N64SegCi8(N64SegRgba16):
|
||||
|
||||
@staticmethod
|
||||
def parse_image(data, width, height, flip_h=False, flip_v=False):
|
||||
return data
|
||||
# hot path
|
||||
if not flip_h and not flip_v:
|
||||
return data
|
||||
|
||||
flipped_data = bytearray()
|
||||
|
||||
for x, y, i in iter.iter_image_indexes(width, height, 1, 1, flip_h, flip_v):
|
||||
flipped_data.append(data[i])
|
||||
|
||||
return flipped_data
|
||||
|
||||
def max_length(self):
|
||||
return self.width * self.height
|
||||
|
||||
def cache(self):
|
||||
return (self.config, self.rom_end, 1)
|
||||
|
@ -39,7 +39,7 @@ class N64SegCodeSubsegment(Segment):
|
||||
def is_branch_insn(mnemonic):
|
||||
return (mnemonic.startswith("b") and not mnemonic.startswith("binsl") and not mnemonic == "break") or mnemonic == "j"
|
||||
|
||||
def disassemble_code(self, rom_bytes, addsuffix=False):
|
||||
def disassemble_code(self, rom_bytes):
|
||||
insns = [insn for insn in N64SegCodeSubsegment.md.disasm(rom_bytes[self.rom_start : self.rom_end], self.vram_start)]
|
||||
|
||||
funcs = self.process_insns(insns, self.rom_start)
|
||||
@ -50,7 +50,7 @@ class N64SegCodeSubsegment(Segment):
|
||||
|
||||
funcs = self.determine_symbols(funcs)
|
||||
self.gather_jumptable_labels(rom_bytes)
|
||||
return self.add_labels(funcs, addsuffix)
|
||||
return self.add_labels(funcs)
|
||||
|
||||
def process_insns(self, insns, rom_addr):
|
||||
assert(isinstance(self.parent, N64SegCode))
|
||||
@ -243,6 +243,7 @@ class N64SegCodeSubsegment(Segment):
|
||||
if offset != 0:
|
||||
offset_str = f"+0x{offset:X}"
|
||||
|
||||
|
||||
if self.parent:
|
||||
self.parent.check_rodata_sym(func_addr, sym)
|
||||
|
||||
@ -256,7 +257,7 @@ class N64SegCodeSubsegment(Segment):
|
||||
ret[func_addr] = func
|
||||
return ret
|
||||
|
||||
def add_labels(self, funcs, addsuffix):
|
||||
def add_labels(self, funcs):
|
||||
ret = {}
|
||||
|
||||
for func in funcs:
|
||||
@ -310,9 +311,6 @@ class N64SegCodeSubsegment(Segment):
|
||||
|
||||
if insn[0].mnemonic != "branch" and insn[0].mnemonic.startswith("b") or insn[0].mnemonic.startswith("j"):
|
||||
indent_next = True
|
||||
|
||||
if addsuffix:
|
||||
func_text.append(f"endlabel {sym.name}")
|
||||
|
||||
ret[func] = (func_text, rom_addr)
|
||||
|
||||
@ -360,7 +358,7 @@ class N64SegCodeSubsegment(Segment):
|
||||
rom_offset += 4
|
||||
|
||||
def should_scan(self) -> bool:
|
||||
return options.mode_active("code")
|
||||
return self.should_split()
|
||||
|
||||
def should_split(self) -> bool:
|
||||
return self.extract and options.mode_active("code")
|
||||
|
@ -33,6 +33,13 @@ class N64SegData(N64SegCodeSubsegment):
|
||||
def get_linker_section(self) -> str:
|
||||
return ".data"
|
||||
|
||||
def get_linker_entries(self):
|
||||
from segtypes.linker_entry import LinkerEntry
|
||||
|
||||
path = self.out_path()
|
||||
|
||||
return [LinkerEntry(self, [path], path, self.get_linker_section())]
|
||||
|
||||
def get_symbols(self):
|
||||
ret = []
|
||||
|
||||
@ -141,7 +148,7 @@ class N64SegData(N64SegCodeSubsegment):
|
||||
return sym_str
|
||||
|
||||
def disassemble_data(self, rom_bytes):
|
||||
rodata_encountered = "rodata" in self.type
|
||||
rodata_encountered = self.type == "rodata"
|
||||
ret = ".include \"macro.inc\"\n\n"
|
||||
ret += f'.section {self.get_linker_section()}'
|
||||
|
||||
@ -154,6 +161,9 @@ class N64SegData(N64SegCodeSubsegment):
|
||||
mnemonic = syms[i].access_mnemonic
|
||||
sym = self.parent.get_symbol(syms[i].vram_start, create=True, define=True, local_only=True)
|
||||
|
||||
if sym.vram_start == 0x80097D90:
|
||||
dog = 5
|
||||
|
||||
sym_str = f"\n\nglabel {sym.name}\n"
|
||||
dis_start = self.parent.ram_to_rom(syms[i].vram_start)
|
||||
dis_end = self.parent.ram_to_rom(syms[i + 1].vram_start)
|
||||
|
@ -57,6 +57,7 @@ class N64SegGroup(N64Segment):
|
||||
segment.parent = self
|
||||
|
||||
if segment.rom_start != "auto":
|
||||
assert isinstance(segment.rom_start, int)
|
||||
segment.vram_start = self.rom_to_ram(segment.rom_start)
|
||||
|
||||
# TODO: assumes section order - generalize and stuff
|
||||
|
@ -2,10 +2,47 @@ from pathlib import Path
|
||||
from typing import Optional
|
||||
from segtypes.n64.segment import N64Segment
|
||||
from util import options
|
||||
from util import log
|
||||
|
||||
class N64SegImg(N64Segment):
|
||||
def __init__(self, segment, rom_start, rom_end):
|
||||
super().__init__(segment, rom_start, rom_end)
|
||||
|
||||
if type(segment) is dict:
|
||||
if self.extract:
|
||||
self.width = segment["width"]
|
||||
self.height = segment["height"]
|
||||
|
||||
self.flip_horizontal = bool(segment.get("flip_x", False))
|
||||
self.flip_vertical = bool(segment.get("flip_y", False))
|
||||
|
||||
if segment.get("flip"):
|
||||
self.warn(f"'flip' parameter for img segments is deprecated; use flip_x and flip_y instead")
|
||||
flip = segment.get("flip")
|
||||
|
||||
self.flip_vertical = flip == "both" or flip.startswith("v") or flip == "y"
|
||||
self.flip_horizontal = flip == "both" or flip.startswith("h") or flip == "x"
|
||||
else:
|
||||
if self.extract:
|
||||
if len(segment) < 5:
|
||||
log.error(f"Error: {self.name} is missing width and height parameters")
|
||||
self.width = segment[3]
|
||||
self.height = segment[4]
|
||||
|
||||
self.flip_horizontal = False
|
||||
self.flip_vertical = False
|
||||
|
||||
if self.extract and self.max_length() is not None:
|
||||
expected_len = int(self.max_length())
|
||||
actual_len = self.rom_end - self.rom_start
|
||||
if actual_len > expected_len and actual_len - expected_len > self.subalign:
|
||||
log.error(f"Error: {self.name} should end at 0x{self.rom_start + expected_len:X}, but it ends at 0x{self.rom_end:X}\n(hint: add a 'bin' segment after it)")
|
||||
|
||||
def out_path(self) -> Optional[Path]:
|
||||
return options.get_asset_path() / self.dir / f"{self.name}.png"
|
||||
|
||||
def should_split(self) -> bool:
|
||||
return self.extract and options.mode_active("img")
|
||||
|
||||
def max_length(self) -> Optional[int]:
|
||||
return None
|
||||
|
@ -27,18 +27,19 @@ class N64SegPalette(N64Segment):
|
||||
self.name.split(".")[0]
|
||||
) if type(segment) is dict else self.name.split(".")[0]
|
||||
|
||||
if self.rom_end == "auto":
|
||||
log.error(f"segment {self.name} needs to know where it ends; add a position marker [0xDEADBEEF] after it")
|
||||
if self.extract:
|
||||
if self.rom_end == "auto":
|
||||
log.error(f"segment {self.name} needs to know where it ends; add a position marker [0xDEADBEEF] after it")
|
||||
|
||||
if self.max_length() and isinstance(self.rom_end, int):
|
||||
expected_len = int(self.max_length())
|
||||
actual_len = self.rom_end - self.rom_start
|
||||
if actual_len > expected_len and actual_len - expected_len > self.subalign:
|
||||
log.error(f"Error: {self.name} should end at 0x{self.rom_start + expected_len:X}, but it ends at 0x{self.rom_end:X}\n(hint: add a 'bin' segment after it)")
|
||||
if self.max_length() and isinstance(self.rom_end, int):
|
||||
expected_len = int(self.max_length())
|
||||
actual_len = self.rom_end - self.rom_start
|
||||
if actual_len > expected_len and actual_len - expected_len > self.subalign:
|
||||
log.error(f"Error: {self.name} should end at 0x{self.rom_start + expected_len:X}, but it ends at 0x{self.rom_end:X}\n(hint: add a 'bin' segment after it)")
|
||||
|
||||
def should_split(self):
|
||||
return super().should_split() or options.mode_active("img")
|
||||
|
||||
return self.extract and (super().should_split() or options.mode_active("img"))
|
||||
|
||||
def out_path(self) -> Optional[Path]:
|
||||
return options.get_asset_path() / self.dir / f"{self.name}.png"
|
||||
|
||||
|
@ -7,37 +7,6 @@ from util.color import unpack_color
|
||||
|
||||
# TODO: move common behaviour to N64ImgSegment and have all image segments extend that instead
|
||||
class N64SegRgba16(N64SegImg):
|
||||
def __init__(self, segment, rom_start, rom_end):
|
||||
super().__init__(segment, rom_start, rom_end)
|
||||
|
||||
if type(segment) is dict:
|
||||
self.width = segment["width"]
|
||||
self.height = segment["height"]
|
||||
self.flip = segment.get("flip", "noflip")
|
||||
elif len(segment) < 5:
|
||||
log.error("missing parameters")
|
||||
else:
|
||||
self.width = segment[3]
|
||||
self.height = segment[4]
|
||||
self.flip = "noflip"
|
||||
|
||||
if self.max_length():
|
||||
expected_len = int(self.max_length())
|
||||
actual_len = self.rom_end - self.rom_start
|
||||
if actual_len > expected_len and actual_len - expected_len > self.subalign:
|
||||
log.error(f"Error: {self.name} should end at 0x{self.rom_start + expected_len:X}, but it ends at 0x{self.rom_end:X}\n(hint: add a 'bin' segment after it)")
|
||||
|
||||
@property
|
||||
def flip_vertical(self):
|
||||
return self.flip == "both" or self.flip.startswith("v") or self.flip == "y"
|
||||
|
||||
@property
|
||||
def flip_horizontal(self):
|
||||
return self.flip == "both" or self.flip.startswith("h") or self.flip == "x"
|
||||
|
||||
def should_split(self):
|
||||
return super().should_split() or options.mode_active("img")
|
||||
|
||||
def split(self, rom_bytes):
|
||||
path = self.out_path()
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
@ -6,12 +6,12 @@ def iter_in_groups(iterable, n, fillvalue=None):
|
||||
return zip_longest(*args, fillvalue=fillvalue)
|
||||
|
||||
def iter_image_indexes(width, height, bytes_per_x=1, bytes_per_y=1, flip_h=False, flip_v=False):
|
||||
w = int(width * bytes_per_x)
|
||||
h = int(height * bytes_per_y)
|
||||
w = int(width * bytes_per_x)
|
||||
h = int(height * bytes_per_y)
|
||||
|
||||
xrange = range(w - ceil(bytes_per_x), -1, -ceil(bytes_per_x)) if flip_h else range(0, w, ceil(bytes_per_x))
|
||||
yrange = range(h - ceil(bytes_per_y), -1, -ceil(bytes_per_y)) if flip_v else range(0, h, ceil(bytes_per_y))
|
||||
xrange = range(w - ceil(bytes_per_x), -1, -ceil(bytes_per_x)) if flip_h else range(0, w, ceil(bytes_per_x))
|
||||
yrange = range(h - ceil(bytes_per_y), -1, -ceil(bytes_per_y)) if flip_v else range(0, h, ceil(bytes_per_y))
|
||||
|
||||
for y in yrange:
|
||||
for x in xrange:
|
||||
yield x, y, (y * w) + x
|
||||
for y in yrange:
|
||||
for x in xrange:
|
||||
yield x, y, (y * w) + x
|
||||
|
@ -1,12 +1,12 @@
|
||||
import sys
|
||||
from colorama import init, Fore, Style
|
||||
from typing import Union
|
||||
from typing import Optional
|
||||
|
||||
init(autoreset=True)
|
||||
|
||||
newline = True
|
||||
|
||||
Status = Union[None, str]
|
||||
Status = Optional[str]
|
||||
|
||||
def write(*args, status=None, **kwargs):
|
||||
global newline
|
||||
|
@ -22,12 +22,12 @@ def initialize(config: Dict, config_path: str, base_path=None, target_path=None)
|
||||
|
||||
def set(opt, val):
|
||||
opts[opt] = val
|
||||
|
||||
|
||||
def get(opt, default=None):
|
||||
return opts.get(opt, default)
|
||||
|
||||
def get_platform() -> str:
|
||||
return opts.get("platform", "n64")
|
||||
return opts.get("platform", "N64")
|
||||
|
||||
def get_compiler() -> str:
|
||||
return opts.get("compiler", "IDO")
|
||||
|
@ -2172,14 +2172,12 @@ segments:
|
||||
subsegments:
|
||||
- [0x38F900, c]
|
||||
- [0x390340, bin]
|
||||
- [0x3903D0, bin]
|
||||
- start: 0x390810
|
||||
type: ia4
|
||||
name: battle/text_action_command_ratings
|
||||
width: 64
|
||||
height: 125
|
||||
flip: vertical
|
||||
- [0x3917B0, bin]
|
||||
- [0x3903D0, ia4, battle/lucky, 64, 32]
|
||||
- [0x3907D0, ia4, battle/miss, 64, 32]
|
||||
- [0x390BD0, ia4, battle/good, 64, 32]
|
||||
- [0x390FD0, ia4, battle/nice, 64, 32]
|
||||
- [0x3913D0, ia4, battle/super, 64, 32]
|
||||
- [0x3917D0, bin]
|
||||
- type: code
|
||||
start: 0x391D30
|
||||
vram: 0xE0092000
|
||||
@ -2471,20 +2469,114 @@ segments:
|
||||
subsegments:
|
||||
- [0x3EB4E0, c]
|
||||
- [0x3EBC30, bin]
|
||||
- [0x3ED4E0, ia8, world/text_chapter, 128, 38]
|
||||
- [0x3EE7E0, bin]
|
||||
- [0x3EBE60, ia8, world/ch0, 144, 40]
|
||||
- [0x3ED4E0, ia8, world/text_chapter, 128, 40]
|
||||
- [0x3EE8E0, ia8, world/text_end_of, 104, 40]
|
||||
- [0x3EF920, ia8, world/exclamation_point, 16, 40]
|
||||
- [0x3EFBA0, ia8, world/ch1, 64, 64]
|
||||
- [0x3F0BA0, ia8, world/ch2, 64, 64]
|
||||
- [0x3F1BA0, ia8, world/ch3, 64, 64]
|
||||
- [0x3F2BA0, ia8, world/ch4, 64, 64]
|
||||
- [0x3F3BA0, ia8, world/ch5, 64, 64]
|
||||
- [0x3F4BA0, ia8, world/ch6, 64, 64]
|
||||
- [0x3F5BA0, ia8, world/ch7, 64, 64]
|
||||
- [0x3F6BA0, ia8, world/ch8, 64, 64]
|
||||
- [0x3F7BA0, rgba16, world/chapter_rainbow, 8, 16]
|
||||
- [0x3F7CA0, bin]
|
||||
- type: code
|
||||
start: 0x3F83F0
|
||||
vram: 0xE0110000
|
||||
subsegments:
|
||||
- [0x3F83F0, c]
|
||||
- [0x3F8CA0, bin]
|
||||
- [0x3F8CC0, i4, ice_smash, 64, 128]
|
||||
- [0x3F9CC0, bin]
|
||||
- type: code
|
||||
start: 0x3F9E50
|
||||
vram: 0xE0112000
|
||||
subsegments:
|
||||
- [0x3F9E50, c]
|
||||
- [0x3FA480, bin]
|
||||
- start: 0x3FA4B0
|
||||
type: ci4
|
||||
name: star_cards/card_front
|
||||
flip_y: true
|
||||
width: 32
|
||||
height: 32
|
||||
- [0x3FA6B0, palette, star_cards/card_front]
|
||||
- [0x3FA6D0, bin] # PAD
|
||||
- start: 0x3FA8B0
|
||||
type: ci4
|
||||
name: star_cards/card_back
|
||||
flip_y: true
|
||||
width: 32
|
||||
height: 64
|
||||
- [0x3FACB0, palette, star_cards/card_back]
|
||||
- [0x3FACD0, bin] # PAD
|
||||
- start: 0x3FAEB0
|
||||
type: ci4
|
||||
name: star_cards/wave
|
||||
flip_y: true
|
||||
width: 32
|
||||
height: 32
|
||||
- [0x3FB0B0, palette, star_cards/wave]
|
||||
- [0x3FB0D0, bin] # PAD
|
||||
- start: 0x3FB2B0
|
||||
type: ci4
|
||||
name: star_cards/squares
|
||||
flip_y: true
|
||||
width: 16
|
||||
height: 16
|
||||
- [0x3FB330, palette, star_cards/squares]
|
||||
- [0x3FB350, bin] # PAD
|
||||
- start: 0x3FB530
|
||||
type: ci4
|
||||
name: star_cards/eldstar
|
||||
flip_y: true
|
||||
width: 48
|
||||
height: 48
|
||||
- [0x3FB9B0, palette, star_cards/eldstar]
|
||||
- [0x3FB9D0, bin] # PAD
|
||||
- start: 0x3FBBB0
|
||||
type: ci4
|
||||
name: star_cards/mamar
|
||||
flip_y: true
|
||||
width: 48
|
||||
height: 48
|
||||
- [0x3FC030, palette, star_cards/mamar]
|
||||
- [0x3FC050, bin] # PAD
|
||||
- start: 0x3FC230
|
||||
type: ci4
|
||||
name: star_cards/skolar
|
||||
flip_y: true
|
||||
width: 48
|
||||
height: 48
|
||||
- [0x3FC6B0, palette, star_cards/skolar]
|
||||
- [0x3FC6D0, bin] # PAD
|
||||
- start: 0x3FC8B0
|
||||
type: ci4
|
||||
name: star_cards/muskular
|
||||
flip_y: true
|
||||
width: 48
|
||||
height: 48
|
||||
- [0x3FCD30, palette, star_cards/muskular]
|
||||
- [0x3FCD50, bin] # PAD
|
||||
- start: 0x3FCF30
|
||||
type: ci4
|
||||
name: star_cards/misstar
|
||||
flip_y: true
|
||||
width: 48
|
||||
height: 48
|
||||
- [0x3FD3B0, palette, star_cards/misstar]
|
||||
- [0x3FD3D0, bin] # PAD
|
||||
- start: 0x3FDC30
|
||||
type: ci4
|
||||
name: star_cards/klevar
|
||||
flip_y: true
|
||||
width: 48
|
||||
height: 48
|
||||
- [0x3FE0B0, palette, star_cards/klevar]
|
||||
- [0x3FE0D0, bin]
|
||||
- type: code
|
||||
start: 0x3FEAE0
|
||||
vram: 0xE0114000
|
||||
@ -2509,6 +2601,35 @@ segments:
|
||||
subsegments:
|
||||
- [0x404220, c]
|
||||
- [0x404E40, bin]
|
||||
- start: 0x404F40
|
||||
type: ci4
|
||||
name: world/cloud
|
||||
flip_y: true
|
||||
width: 32
|
||||
height: 32
|
||||
- [0x405140, palette, world/cloud]
|
||||
- start: 0x405340
|
||||
type: ci4
|
||||
name: world/waterblock
|
||||
flip_y: true
|
||||
width: 32
|
||||
height: 32
|
||||
- [0x405540, palette, world/waterblock]
|
||||
- start: 0x405740
|
||||
type: ci4
|
||||
name: world/yellow_carpet
|
||||
flip_y: true
|
||||
width: 32
|
||||
height: 32
|
||||
- [0x405940, palette, world/yellow_carpet]
|
||||
- start: 0x405B40
|
||||
type: ci4
|
||||
name: world/numbers
|
||||
flip_y: true
|
||||
width: 32
|
||||
height: 160
|
||||
- [0x406540, palette, world/numbers]
|
||||
- [0x406740, bin]
|
||||
- type: code
|
||||
start: 0x406B40
|
||||
vram: 0xE011C000
|
||||
|
Loading…
Reference in New Issue
Block a user