mirror of
https://github.com/pmret/papermario.git
synced 2024-11-09 12:32:38 +01:00
Merge branch 'master' into cornucopia
This commit is contained in:
commit
4400966849
2
.gitignore
vendored
2
.gitignore
vendored
@ -18,8 +18,10 @@ settings.mk
|
|||||||
/build/
|
/build/
|
||||||
/docs/doxygen/
|
/docs/doxygen/
|
||||||
/include/ld_addrs.h
|
/include/ld_addrs.h
|
||||||
|
/include/sprite/
|
||||||
|
|
||||||
# Assets
|
# Assets
|
||||||
/bin
|
/bin
|
||||||
/img
|
/img
|
||||||
/msg
|
/msg
|
||||||
|
/sprite
|
||||||
|
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
@ -10,9 +10,15 @@
|
|||||||
"-D_LANGUAGE_C",
|
"-D_LANGUAGE_C",
|
||||||
"-DSCRIPT(...)={}",
|
"-DSCRIPT(...)={}",
|
||||||
],
|
],
|
||||||
|
"clang-tidy.blacklist": [
|
||||||
|
"include/PR"
|
||||||
|
],
|
||||||
"git.ignoreLimitWarning": true,
|
"git.ignoreLimitWarning": true,
|
||||||
"search.exclude": {
|
"search.exclude": {
|
||||||
"build": true,
|
"build": true,
|
||||||
"docs/doxygen": true,
|
"docs/doxygen": true,
|
||||||
},
|
},
|
||||||
|
"python.autoComplete.extraPaths": [
|
||||||
|
"./tools"
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
36
Makefile
36
Makefile
@ -35,7 +35,8 @@ LD_SCRIPT := $(TARGET).ld
|
|||||||
LD_MAP := $(BUILD_DIR)/$(TARGET).map
|
LD_MAP := $(BUILD_DIR)/$(TARGET).map
|
||||||
ASSETS_BIN := $(BUILD_DIR)/bin/assets/assets.bin
|
ASSETS_BIN := $(BUILD_DIR)/bin/assets/assets.bin
|
||||||
MSG_BIN := $(BUILD_DIR)/msg.bin
|
MSG_BIN := $(BUILD_DIR)/msg.bin
|
||||||
GENERATED_HEADERS := include/ld_addrs.h
|
NPC_BIN := $(BUILD_DIR)/sprite/npc.bin
|
||||||
|
GENERATED_HEADERS := include/ld_addrs.h include/sprite
|
||||||
|
|
||||||
### Tools ###
|
### Tools ###
|
||||||
|
|
||||||
@ -103,14 +104,14 @@ submodules:
|
|||||||
git submodule update --init --recursive
|
git submodule update --init --recursive
|
||||||
|
|
||||||
split:
|
split:
|
||||||
rm -rf bin img
|
rm -rf bin msg img sprite
|
||||||
$(SPLAT) --modes bin Yay0 PaperMarioMapFS PaperMarioMessages img
|
$(SPLAT) --modes ld bin Yay0 PaperMarioMapFS PaperMarioMessages img PaperMarioNpcSprites
|
||||||
|
|
||||||
split-%:
|
split-%:
|
||||||
$(SPLAT) --modes $* --verbose
|
$(SPLAT) --modes ld $* --verbose
|
||||||
|
|
||||||
split-all:
|
split-all:
|
||||||
rm -rf bin img
|
rm -rf bin msg img sprite
|
||||||
$(SPLAT) --modes all
|
$(SPLAT) --modes all
|
||||||
|
|
||||||
test: $(ROM)
|
test: $(ROM)
|
||||||
@ -140,7 +141,7 @@ $(BUILD_DIR)/%.c.o: %.c $(MDEPS) | $(GENERATED_HEADERS)
|
|||||||
$(CPP) $(CPPFLAGS) -o - $(CPPMFLAGS) $< | iconv --from UTF-8 --to SHIFT-JIS | $(CC) $(CFLAGS) -o - | $(OLD_AS) $(OLDASFLAGS) -o $@ -
|
$(CPP) $(CPPFLAGS) -o - $(CPPMFLAGS) $< | iconv --from UTF-8 --to SHIFT-JIS | $(CC) $(CFLAGS) -o - | $(OLD_AS) $(OLDASFLAGS) -o $@ -
|
||||||
|
|
||||||
# Compile C files (with DSL macros)
|
# Compile C files (with DSL macros)
|
||||||
$(foreach cfile, $(DSL_C_FILES), $(BUILD_DIR)/$(cfile).o): $(BUILD_DIR)/%.c.o: %.c $(MDEPS) tools/compile_dsl_macros.py | include/ld_addrs.h
|
$(foreach cfile, $(DSL_C_FILES), $(BUILD_DIR)/$(cfile).o): $(BUILD_DIR)/%.c.o: %.c $(MDEPS) tools/compile_dsl_macros.py | $(GENERATED_HEADERS)
|
||||||
@mkdir -p $(shell dirname $@)
|
@mkdir -p $(shell dirname $@)
|
||||||
$(CPP) $(CPPFLAGS) -o - $< $(CPPMFLAGS) | $(PYTHON) tools/compile_dsl_macros.py | iconv --from UTF-8 --to SHIFT-JIS | $(CC) $(CFLAGS) -o - | $(OLD_AS) $(OLDASFLAGS) -o $@ -
|
$(CPP) $(CPPFLAGS) -o - $< $(CPPMFLAGS) | $(PYTHON) tools/compile_dsl_macros.py | iconv --from UTF-8 --to SHIFT-JIS | $(CC) $(CFLAGS) -o - | $(OLD_AS) $(OLDASFLAGS) -o $@ -
|
||||||
|
|
||||||
@ -202,11 +203,28 @@ $(MSG_BIN): $(MESSAGES)
|
|||||||
@echo "building $@"
|
@echo "building $@"
|
||||||
@$(PYTHON) tools/compile_messages.py $@ /dev/null $(MESSAGES)
|
@$(PYTHON) tools/compile_messages.py $@ /dev/null $(MESSAGES)
|
||||||
$(MSG_BIN:.bin=.o): $(MSG_BIN)
|
$(MSG_BIN:.bin=.o): $(MSG_BIN)
|
||||||
@mkdir -p $(shell dirname $@)
|
|
||||||
$(LD) -r -b binary -o $@ $<
|
$(LD) -r -b binary -o $@ $<
|
||||||
|
|
||||||
$(LD_SCRIPT): $(SPLAT_YAML)
|
# Sprites
|
||||||
|
$(foreach npc, $(NPC_SPRITES), $(eval $(BUILD_DIR)/sprite/npc/$(npc):: $(shell find sprite/npc/$(npc) -type f))) # dependencies
|
||||||
|
NPC_DIRS := $(foreach npc, $(NPC_SPRITES), sprite/npc/$(npc))
|
||||||
|
NPC_YAY0 := $(foreach npc, $(NPC_SPRITES), $(BUILD_DIR)/sprite/npc/$(npc).Yay0)
|
||||||
|
$(BUILD_DIR)/sprite/npc/%:: sprite/npc/% tools/compile_npc_sprite.py
|
||||||
@mkdir -p $(shell dirname $@)
|
@mkdir -p $(shell dirname $@)
|
||||||
|
$(PYTHON) tools/compile_npc_sprite.py $@ $<
|
||||||
|
$(NPC_BIN): $(NPC_YAY0) tools/compile_npc_sprites.py
|
||||||
|
@mkdir -p $(shell dirname $@)
|
||||||
|
@echo "building $@"
|
||||||
|
@$(PYTHON) tools/compile_npc_sprites.py $@ $(NPC_YAY0)
|
||||||
|
$(NPC_BIN:.bin=.o): $(NPC_BIN)
|
||||||
|
$(LD) -r -b binary -o $@ $<
|
||||||
|
include/sprite/npc/%.h: sprite/npc/%/SpriteSheet.xml tools/gen_sprite_animations_h.py
|
||||||
|
@mkdir -p $(shell dirname $@)
|
||||||
|
@echo "building $@"
|
||||||
|
@$(PYTHON) tools/gen_sprite_animations_h.py $@ sprite/npc/$* $(NPC_DIRS)
|
||||||
|
include/sprite: $(foreach dir, $(NPC_DIRS), include/$(dir).h)
|
||||||
|
|
||||||
|
$(LD_SCRIPT): $(SPLAT_YAML)
|
||||||
$(SPLAT) --modes ld
|
$(SPLAT) --modes ld
|
||||||
|
|
||||||
$(BUILD_DIR)/$(LD_SCRIPT): $(LD_SCRIPT)
|
$(BUILD_DIR)/$(LD_SCRIPT): $(LD_SCRIPT)
|
||||||
@ -230,7 +248,7 @@ include/ld_addrs.h: $(BUILD_DIR)/$(LD_SCRIPT)
|
|||||||
|
|
||||||
### Make Settings ###
|
### Make Settings ###
|
||||||
|
|
||||||
.PHONY: clean test setup submodules split $(ROM)
|
.PHONY: clean test setup submodules split $(ROM) include/sprite
|
||||||
.DELETE_ON_ERROR:
|
.DELETE_ON_ERROR:
|
||||||
.SECONDARY:
|
.SECONDARY:
|
||||||
.PRECIOUS: $(ROM) %.Yay0
|
.PRECIOUS: $(ROM) %.Yay0
|
||||||
|
235
include/enums.h
235
include/enums.h
@ -25,241 +25,6 @@ typedef s8 PartnerId;
|
|||||||
#define PartnerId_GOOMBARIA 0x0A
|
#define PartnerId_GOOMBARIA 0x0A
|
||||||
#define PartnerId_TWINK 0x0B
|
#define PartnerId_TWINK 0x0B
|
||||||
|
|
||||||
typedef UNK_TYPE SpriteId;
|
|
||||||
#define SpriteId_WORLD_GOOMBARIO 0x00000001
|
|
||||||
#define SpriteId_WORLD_KOOPER 0x00000002
|
|
||||||
#define SpriteId_WORLD_BOMBETTE 0x00000003
|
|
||||||
#define SpriteId_WORLD_PARAKARRY 0x00000004
|
|
||||||
#define SpriteId_WORLD_BOW 0x00000005
|
|
||||||
#define SpriteId_WORLD_WATT 0x00000006
|
|
||||||
#define SpriteId_WORLD_SUSHI 0x00000007
|
|
||||||
#define SpriteId_WORLD_LAKILESTER 0x00000008
|
|
||||||
#define SpriteId_BATTLE_GOOMBARIO 0x00000009
|
|
||||||
#define SpriteId_BATTLE_KOOPER 0x0000000A
|
|
||||||
#define SpriteId_BATTLE_BOMBETTE 0x0000000B
|
|
||||||
#define SpriteId_BATTLE_PARAKARRY 0x0000000C
|
|
||||||
#define SpriteId_BATTLE_BOW 0x0000000D
|
|
||||||
#define SpriteId_BATTLE_WATT 0x0000000E
|
|
||||||
#define SpriteId_BATTLE_SUSHI 0x0000000F
|
|
||||||
#define SpriteId_BATTLE_LAKILESTER 0x00000010
|
|
||||||
#define SpriteId_KOOPER_WITHOUT_SHELL 0x00000011
|
|
||||||
#define SpriteId_WORLD_ELDSTAR 0x00000012
|
|
||||||
#define SpriteId_WORLD_MAMAR 0x00000013
|
|
||||||
#define SpriteId_WORLD_SKOLAR 0x00000014
|
|
||||||
#define SpriteId_WORLD_MUSKULAR 0x00000015
|
|
||||||
#define SpriteId_WORLD_MISSTAR 0x00000016
|
|
||||||
#define SpriteId_WORLD_KLEVAR 0x00000017
|
|
||||||
#define SpriteId_WORLD_KALMAR 0x00000018
|
|
||||||
#define SpriteId_BATTLE_ELDSTAR 0x00000019
|
|
||||||
#define SpriteId_BATTLE_MAMAR 0x0000001A
|
|
||||||
#define SpriteId_BATTLE_SKOLAR 0x0000001B
|
|
||||||
#define SpriteId_BATTLE_MUSKULAR 0x0000001C
|
|
||||||
#define SpriteId_BATTLE_MISSTAR 0x0000001D
|
|
||||||
#define SpriteId_BATTLE_KLEVAR 0x0000001E
|
|
||||||
#define SpriteId_BATTLE_KALMAR 0x0000001F
|
|
||||||
#define SpriteId_TWINK 0x00000020
|
|
||||||
#define SpriteId_JR_TROOPA 0x00000021
|
|
||||||
#define SpriteId_SPIKED_JR_TROOPA 0x00000022
|
|
||||||
#define SpriteId_SPIKED_PARA_JR_TROOPA 0x00000023
|
|
||||||
#define SpriteId_MAGE_JR_TROOPA 0x00000024
|
|
||||||
#define SpriteId_PARA_JR_TROOPA 0x00000025
|
|
||||||
#define SpriteId_GOOMBA 0x00000026
|
|
||||||
#define SpriteId_SPIKED_GOOMBA 0x00000027
|
|
||||||
#define SpriteId_PARAGOOMBA 0x00000028
|
|
||||||
#define SpriteId_KOOPA_TROOPA 0x00000029
|
|
||||||
#define SpriteId_PARA_TROOPA 0x0000002A
|
|
||||||
#define SpriteId_FUZZY 0x0000002B
|
|
||||||
#define SpriteId_BOMBOMB 0x0000002C
|
|
||||||
#define SpriteId_BULLET_BILL 0x0000002D
|
|
||||||
#define SpriteId_BILL_BLASTER 0x0000002E
|
|
||||||
#define SpriteId_MONTY_MOLE 0x0000002F
|
|
||||||
#define SpriteId_CLEFT 0x00000030
|
|
||||||
#define SpriteId_POKEY 0x00000031
|
|
||||||
#define SpriteId_BANDIT 0x00000032
|
|
||||||
#define SpriteId_BUZZY_BEETLE 0x00000033
|
|
||||||
#define SpriteId_SWOOPER 0x00000034
|
|
||||||
#define SpriteId_STONE_CHOMP 0x00000035
|
|
||||||
#define SpriteId_PUTRID_PIRANHA 0x00000036
|
|
||||||
#define SpriteId_PIRANHA_PLANT 0x00000037
|
|
||||||
#define SpriteId_SENTINEL 0x00000038
|
|
||||||
#define SpriteId_WORLD_CLUBBA 0x00000039
|
|
||||||
#define SpriteId_BATTLE_CLUBBA 0x0000003A
|
|
||||||
#define SpriteId_SHY_GUY 0x0000003B
|
|
||||||
#define SpriteId_GROOVE_GUY 0x0000003C
|
|
||||||
#define SpriteId_SKY_GUY 0x0000003D
|
|
||||||
#define SpriteId_PYRO_GUY 0x0000003E
|
|
||||||
#define SpriteId_SPY_GUY 0x0000003F
|
|
||||||
#define SpriteId_MEDI_GUY 0x00000040
|
|
||||||
#define SpriteId_FUZZIPEDE 0x00000041
|
|
||||||
#define SpriteId_JUNGLE_GUY 0x00000042
|
|
||||||
#define SpriteId_HEART_PLANT 0x00000043
|
|
||||||
#define SpriteId_HURT_PLANT 0x00000044
|
|
||||||
#define SpriteId_M_BUSH 0x00000045
|
|
||||||
#define SpriteId_BUBBLE 0x00000046
|
|
||||||
#define SpriteId_KENT_C_KOOPA 0x00000047
|
|
||||||
#define SpriteId_DAYZEE 0x00000048
|
|
||||||
#define SpriteId_LAKITU 0x00000049
|
|
||||||
#define SpriteId_SPINY 0x0000004A
|
|
||||||
#define SpriteId_BZZAP 0x0000004B
|
|
||||||
#define SpriteId_RUFF_PUFF 0x0000004C
|
|
||||||
#define SpriteId_SPIKE_TOP 0x0000004D
|
|
||||||
#define SpriteId_DUPLIGHOST 0x0000004E
|
|
||||||
#define SpriteId_ALBINO_DINO 0x0000004F
|
|
||||||
#define SpriteId_BLOOPER 0x00000050
|
|
||||||
#define SpriteId_BABY_BLOOPER 0x00000051
|
|
||||||
#define SpriteId_GULPIT 0x00000052
|
|
||||||
#define SpriteId_DRY_BONES 0x00000053
|
|
||||||
#define SpriteId_THROWN_BONE 0x00000054
|
|
||||||
#define SpriteId_BONY_BEETLE 0x00000055
|
|
||||||
#define SpriteId_MAGIKOOPA 0x00000056
|
|
||||||
#define SpriteId_FLYING_MAGIKOOPA 0x00000057
|
|
||||||
#define SpriteId_WORLD_KOOPATROL 0x00000058
|
|
||||||
#define SpriteId_KOOPATROL 0x00000059
|
|
||||||
#define SpriteId_HAMMER_BROS 0x0000005A
|
|
||||||
#define SpriteId_BUSH_BASIC 0x0000005B
|
|
||||||
#define SpriteId_BUSH_BLOCKY 0x0000005C
|
|
||||||
#define SpriteId_BUSH_DRY 0x0000005D
|
|
||||||
#define SpriteId_BUSH_LEAFY 0x0000005E
|
|
||||||
#define SpriteId_BUSH_MATTED 0x0000005F
|
|
||||||
#define SpriteId_WORLD_KAMMY 0x00000060
|
|
||||||
#define SpriteId_BATTLE_KAMMY 0x00000061
|
|
||||||
#define SpriteId_GOOMBA_BROS 0x00000062
|
|
||||||
#define SpriteId_GOOMBA_KING 0x00000063
|
|
||||||
#define SpriteId_SPIKY_GOOMNUT 0x00000064
|
|
||||||
#define SpriteId_DARK_TOAD 0x00000065
|
|
||||||
#define SpriteId_KOOPA_BROS 0x00000066
|
|
||||||
#define SpriteId_BUZZAR 0x00000067
|
|
||||||
#define SpriteId_TUTANKOOPA 0x00000068
|
|
||||||
#define SpriteId_CHAIN_CHOMP 0x00000069
|
|
||||||
#define SpriteId_WORLD_TUBBA 0x0000006A
|
|
||||||
#define SpriteId_BATTLE_TUBBA 0x0000006B
|
|
||||||
#define SpriteId_TUBBAS_HEART 0x0000006C
|
|
||||||
#define SpriteId_BIG_LANTERN_GHOST 0x0000006D
|
|
||||||
#define SpriteId_SHY_SQUAD_GUY 0x0000006E
|
|
||||||
#define SpriteId_MARSHAL_GUY 0x0000006F
|
|
||||||
#define SpriteId_STILT_GUY 0x00000070
|
|
||||||
#define SpriteId_STILT_GUY_UNFOLD 0x00000071
|
|
||||||
#define SpriteId_SHY_STACK_GUY 0x00000072
|
|
||||||
#define SpriteId_SHY_STACK_UNFOLD 0x00000073
|
|
||||||
#define SpriteId_SHY_STACK_DAMAGE 0x00000074
|
|
||||||
#define SpriteId_SHY_STACK_ROCK 0x00000075
|
|
||||||
#define SpriteId_GENERAL_GUY 0x00000076
|
|
||||||
#define SpriteId_GENERAL_GUY_BOMB 0x00000077
|
|
||||||
#define SpriteId_TANK_GUY 0x00000078
|
|
||||||
#define SpriteId_LAVA_PIRANHA_HEAD 0x00000079
|
|
||||||
#define SpriteId_PETIT_PIRANHA 0x0000007A
|
|
||||||
#define SpriteId_LAVA_BUD 0x0000007B
|
|
||||||
#define SpriteId_HUFF_N_PUFF 0x0000007C
|
|
||||||
#define SpriteId_TUFF_PUFF 0x0000007D
|
|
||||||
#define SpriteId_MONSTAR 0x0000007E
|
|
||||||
#define SpriteId_CRYSTAL_KING 0x0000007F
|
|
||||||
#define SpriteId_WORLD_BOWSER 0x00000080
|
|
||||||
#define SpriteId_BATTLE_BOWSER 0x00000081
|
|
||||||
#define SpriteId_LUIGI 0x00000082
|
|
||||||
#define SpriteId_TOAD 0x00000083
|
|
||||||
#define SpriteId_THREE_SISTERS 0x00000084
|
|
||||||
#define SpriteId_VANNA_T 0x00000085
|
|
||||||
#define SpriteId_TOAD_KID 0x00000086
|
|
||||||
#define SpriteId_TOAD_GUARD 0x00000087
|
|
||||||
#define SpriteId_HARRY_T 0x00000088
|
|
||||||
#define SpriteId_TOAD_MINISTER 0x00000089
|
|
||||||
#define SpriteId_POSTMASTER 0x0000008A
|
|
||||||
#define SpriteId_CONDUCTOR_TOAD 0x0000008B
|
|
||||||
#define SpriteId_TRAIN_STATION_TOAD 0x0000008C
|
|
||||||
#define SpriteId_FISHMAEL 0x0000008D
|
|
||||||
#define SpriteId_ARTIST_TOAD 0x0000008E
|
|
||||||
#define SpriteId_KOOPA 0x0000008F
|
|
||||||
#define SpriteId_KOOPA_WITHOUT_SHELL 0x00000090
|
|
||||||
#define SpriteId_WORLD_BOMBOMB 0x00000091
|
|
||||||
#define SpriteId_WHACKA 0x00000092
|
|
||||||
#define SpriteId_DRYITE 0x00000093
|
|
||||||
#define SpriteId_MOUSER 0x00000094
|
|
||||||
#define SpriteId_BOO 0x00000095
|
|
||||||
#define SpriteId_YOSHI 0x00000096
|
|
||||||
#define SpriteId_YOSHI_KID 0x00000097
|
|
||||||
#define SpriteId_RAVEN 0x00000098
|
|
||||||
#define SpriteId_BUBULB 0x00000099
|
|
||||||
#define SpriteId_PENGUIN 0x0000009A
|
|
||||||
#define SpriteId_SHIVER_TOAD 0x0000009B
|
|
||||||
#define SpriteId_ALT_BANDIT 0x0000009C
|
|
||||||
#define SpriteId_GOOMPAPA 0x0000009D
|
|
||||||
#define SpriteId_GOOMBARIA 0x0000009E
|
|
||||||
#define SpriteId_GOOMAMA 0x0000009F
|
|
||||||
#define SpriteId_GOOMPA 0x000000A0
|
|
||||||
#define SpriteId_GOOMMA 0x000000A1
|
|
||||||
#define SpriteId_THE_MASTER 0x000000A2
|
|
||||||
#define SpriteId_CHAN 0x000000A3
|
|
||||||
#define SpriteId_LEE 0x000000A4
|
|
||||||
#define SpriteId_MERLON 0x000000A5
|
|
||||||
#define SpriteId_CHET_RIPPO 0x000000A6
|
|
||||||
#define SpriteId_ROWF 0x000000A7
|
|
||||||
#define SpriteId_MINH_T 0x000000A8
|
|
||||||
#define SpriteId_RUSS_T 0x000000A9
|
|
||||||
#define SpriteId_TAYCE_T 0x000000AA
|
|
||||||
#define SpriteId_FICE_T 0x000000AB
|
|
||||||
#define SpriteId_BARTENDER 0x000000AC
|
|
||||||
#define SpriteId_CHANTERELLE 0x000000AD
|
|
||||||
#define SpriteId_RIP_CHEATO 0x000000AE
|
|
||||||
#define SpriteId_CHUCK_QUIZMO 0x000000AF
|
|
||||||
#define SpriteId_MERLUVLEE 0x000000B0
|
|
||||||
#define SpriteId_MERLAR 0x000000B1
|
|
||||||
#define SpriteId_MERLOW 0x000000B2
|
|
||||||
#define SpriteId_STAR_KID 0x000000B3
|
|
||||||
#define SpriteId_KOLORADO_WIFE 0x000000B4
|
|
||||||
#define SpriteId_KOOPA_KOOT 0x000000B5
|
|
||||||
#define SpriteId_KOLORADO 0x000000B6
|
|
||||||
#define SpriteId_BATTLE_KOLORADO 0x000000B7
|
|
||||||
#define SpriteId_ARCHEOLOGIST 0x000000B8
|
|
||||||
#define SpriteId_NOMADIMOUSE 0x000000B9
|
|
||||||
#define SpriteId_WORLD_MERLEE 0x000000BA
|
|
||||||
#define SpriteId_BATTLE_MERLEE 0x000000BB
|
|
||||||
#define SpriteId_DISGUISED_MOUSTAFA 0x000000BC
|
|
||||||
#define SpriteId_MOUSTAFA 0x000000BD
|
|
||||||
#define SpriteId_OAKLIE 0x000000BE
|
|
||||||
#define SpriteId_BOOTLER 0x000000BF
|
|
||||||
#define SpriteId_YAKKEY 0x000000C0
|
|
||||||
#define SpriteId_GOURMET_GUY 0x000000C1
|
|
||||||
#define SpriteId_VILLAGE_LEADER 0x000000C2
|
|
||||||
#define SpriteId_LEADERS_FRIEND 0x000000C3
|
|
||||||
#define SpriteId_RAFAEL_RAVEN 0x000000C4
|
|
||||||
#define SpriteId_TOLIELUP 0x000000C5
|
|
||||||
#define SpriteId_GATE_FLOWER 0x000000C6
|
|
||||||
#define SpriteId_PETUNIA 0x000000C7
|
|
||||||
#define SpriteId_POSIE 0x000000C8
|
|
||||||
#define SpriteId_LILY 0x000000C9
|
|
||||||
#define SpriteId_ROSIE 0x000000CA
|
|
||||||
#define SpriteId_SUN 0x000000CB
|
|
||||||
#define SpriteId_LAKILULU 0x000000CC
|
|
||||||
#define SpriteId_NINJI 0x000000CD
|
|
||||||
#define SpriteId_MAYOR_PENGUIN 0x000000CE
|
|
||||||
#define SpriteId_MAYOR_PENGUIN_WIFE 0x000000CF
|
|
||||||
#define SpriteId_PENGUIN_PATROL 0x000000D0
|
|
||||||
#define SpriteId_HERRINGWAY 0x000000D1
|
|
||||||
#define SpriteId_MERLE 0x000000D2
|
|
||||||
#define SpriteId_STAR_ROD 0x000000D3
|
|
||||||
#define SpriteId_FIRE 0x000000D4
|
|
||||||
#define SpriteId_COIN 0x000000D5
|
|
||||||
#define SpriteId_PARADE_PEACH 0x000000D6
|
|
||||||
#define SpriteId_PARADE_KOOPAS 0x000000D7
|
|
||||||
#define SpriteId_PARADE_BURNT_BOWSER 0x000000D8
|
|
||||||
#define SpriteId_PARADE_LUIGI 0x000000D9
|
|
||||||
#define SpriteId_PARADE_PARTNERS 0x000000DA
|
|
||||||
#define SpriteId_PARADE_YOSHIS 0x000000DB
|
|
||||||
#define SpriteId_PARADA_KOLORADOS 0x000000DC
|
|
||||||
#define SpriteId_PARADE_CHICKS 0x000000DD
|
|
||||||
#define SpriteId_PARADE_ICE_SHOW 0x000000DE
|
|
||||||
#define SpriteId_PARADE_TOADS 0x000000DF
|
|
||||||
#define SpriteId_PARADE_BATONS 0x000000E0
|
|
||||||
#define SpriteId_PARADE_DRUMS 0x000000E1
|
|
||||||
#define SpriteId_PARADE_FLAGS 0x000000E2
|
|
||||||
#define SpriteId_PARADE_HORNS 0x000000E3
|
|
||||||
#define SpriteId_PARADE_TUBBA_BALLOON 0x000000E4
|
|
||||||
#define SpriteId_PARADE_WIZARDS 0x000000E5
|
|
||||||
#define SpriteId_PARADE_MARIO 0x000000E6
|
|
||||||
#define SpriteId_PARADE_SHY_GUYS 0x000000E7
|
|
||||||
#define SpriteId_PARADE_TWINK 0x000000E8
|
|
||||||
#define SpriteId_LEAF 0x000000E9
|
|
||||||
|
|
||||||
typedef s32 SongID;
|
typedef s32 SongID;
|
||||||
#define Song_TOAD_TOWN 0x00000000
|
#define Song_TOAD_TOWN 0x00000000
|
||||||
#define Song_NORMAL_BATTLE 0x00000002
|
#define Song_NORMAL_BATTLE 0x00000002
|
||||||
|
@ -164,8 +164,6 @@ typedef struct StatDrop {
|
|||||||
{ F16(100), F16(30), attempts, F16(40) }, \
|
{ F16(100), F16(30), attempts, F16(40) }, \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ANIMATION(sprite, palette, anim) ((sprite << 16) + (palette << 8) + anim)
|
|
||||||
|
|
||||||
#define OVERRIDE_MOVEMENT_SPEED(speed) (speed * 32767)
|
#define OVERRIDE_MOVEMENT_SPEED(speed) (speed * 32767)
|
||||||
#define NO_OVERRIDE_MOVEMENT_SPEED OVERRIDE_MOVEMENT_SPEED(-1)
|
#define NO_OVERRIDE_MOVEMENT_SPEED OVERRIDE_MOVEMENT_SPEED(-1)
|
||||||
|
|
||||||
@ -186,9 +184,9 @@ typedef struct StaticNPC {
|
|||||||
/* 0x0DC */ s16 maxCoinBonus;
|
/* 0x0DC */ s16 maxCoinBonus;
|
||||||
/* 0x0DE */ char unk_DE[2];
|
/* 0x0DE */ char unk_DE[2];
|
||||||
/* 0x0E0 */ s32 movement[48]; // TODO: type
|
/* 0x0E0 */ s32 movement[48]; // TODO: type
|
||||||
/* 0x1A0 */ s32 animations[16];
|
/* 0x1A0 */ NpcAnimID animations[16];
|
||||||
/* 0x1E0 */ char unk_1E0[8];
|
/* 0x1E0 */ char unk_1E0[8];
|
||||||
/* 0x1E8 */ UNK_PTR extraAnimations;
|
/* 0x1E8 */ NpcAnimID* extraAnimations;
|
||||||
/* 0x1EC */ MessageID tattle;
|
/* 0x1EC */ MessageID tattle;
|
||||||
} StaticNpc; // size = 0x1F0
|
} StaticNpc; // size = 0x1F0
|
||||||
|
|
||||||
|
@ -13,4 +13,7 @@
|
|||||||
typedef s32 FormationID;
|
typedef s32 FormationID;
|
||||||
#define FORMATION_ID(section, stage, index) ((section << 16) + (stage << 8) + index)
|
#define FORMATION_ID(section, stage, index) ((section << 16) + (stage << 8) + index)
|
||||||
|
|
||||||
|
typedef s32 NpcAnimID;
|
||||||
|
#define NPC_ANIM(sprite, palette, anim) ((_NPC_SPRITE_##sprite << 16) + (_NPC_PALETTE_##sprite##_##palette << 8) + _NPC_ANIM_##sprite##_##anim)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -58,5 +58,7 @@ ASSETS := \
|
|||||||
|
|
||||||
MESSAGES := $(shell find msg -type f -name "*.msg")
|
MESSAGES := $(shell find msg -type f -name "*.msg")
|
||||||
|
|
||||||
|
NPC_SPRITES := world_goombario world_kooper world_bombette world_parakarry world_bow world_watt world_sushi world_lakilester battle_goombario battle_kooper battle_bombette battle_parakarry battle_bow battle_watt battle_sushi battle_lakilester kooper_without_shell world_eldstar world_mamar world_skolar world_muskular world_misstar world_klevar world_kalmar battle_eldstar battle_mamar battle_skolar battle_muskular battle_misstar battle_klevar battle_kalmar twink jr_troopa spiked_jr_troopa spiked_para_jr_troopa mage_jr_troopa para_jr_troopa goomba spiked_goomba paragoomba koopa_troopa para_troopa fuzzy bob_omb bullet_bill bill_blaster monty_mole cleft pokey battle_bandit buzzy_beetle swooper stone_chomp putrid_piranha piranha_plant sentinel world_clubba battle_clubba shy_guy groove_guy sky_guy pyro_guy spy_guy medi_guy fuzzipede jungle_guy heart_plant hurt_plant m_bush bubble kent_c_koopa dayzee lakitu spiny bzzap ruff_puff spike_top duplighost albino_dino blooper baby_blooper gulpit dry_bones thrown_bone bony_beetle magikoopa flying_magikoopa world_koopatrol koopatrol hammer_bros bush_basic bush_blocky bush_dry bush_leafy bush_matted world_kammy battle_kammy goomba_bros goomba_king spiky_goomnut dark_toad koopa_bros buzzar tutankoopa chain_chomp world_tubba battle_tubba tubbas_heart big_lantern_ghost shy_squad_guy marshal_guy stilt_guy stilt_guy_unfold shy_stack_guy shy_stack_unfold shy_stack_damage shy_stack_rock general_guy general_guy_bomb tank_guy lava_piranha_head petit_piranha lava_bud huff_n_puff tuff_puff monstar crystal_king world_bowser battle_bowser luigi toad three_sisters vanna_t toad_kid toad_guard harry_t toad_minister postmaster conductor_toad train_station_toad fishmael artist_toad koopa koopa_without_shell world_bob_omb whacka dryite mouser boo yoshi yoshi_kid raven bubulb penguin shiver_toad world_bandit goompapa goombaria goomama goompa goomma the_master chan lee merlon chet_rippo rowf minh_t russ_t tayce_t fice_t bartender chanterelle rip_cheato chuck_quizmo merluvlee merlar merlow star_kid kolorado_wife koopa_koot kolorado battle_kolorado archeologist nomadimouse world_merlee battle_merlee disguised_moustafa moustafa oaklie bootler yakkey gourmet_guy village_leader leaders_friend rafael_raven tolielup gate_flower petunia posie lily rosie sun lakilulu ninji mayor_penguin mayor_penguin_wife penguin_patrol herringway merle star_rod fire coin parade_peach parade_koopas parade_burnt_bowser parade_luigi parade_partners parade_yoshis parada_kolorados parade_chicks parade_ice_show parade_toads parade_batons parade_drums parade_flags parade_horns parade_tubba_balloon parade_wizards parade_mario parade_shy_guys parade_twink leaf
|
||||||
|
|
||||||
# Image settings
|
# Image settings
|
||||||
$(BUILD_DIR)/img/battle/text_action_command_ratings.ia4.png: IMG_FLAGS = --flip-y
|
$(BUILD_DIR)/img/battle/text_action_command_ratings.ia4.png: IMG_FLAGS = --flip-y
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "kmr_12.h"
|
#include "kmr_12.h"
|
||||||
|
#include "sprite/npc/goomba.h"
|
||||||
|
|
||||||
Script M(ExitWest) = EXIT_WALK_SCRIPT(60, 0, "kmr_07", 1);
|
Script M(ExitWest) = EXIT_WALK_SCRIPT(60, 0, "kmr_07", 1);
|
||||||
Script M(ExitEast) = EXIT_WALK_SCRIPT(60, 1, "kmr_11", 0);
|
Script M(ExitEast) = EXIT_WALK_SCRIPT(60, 1, "kmr_11", 0);
|
||||||
@ -85,7 +86,7 @@ Script M(GoombaIdle) = SCRIPT({
|
|||||||
sleep 1
|
sleep 1
|
||||||
|
|
||||||
SetSelfVar(0, FALSE)
|
SetSelfVar(0, FALSE)
|
||||||
SetNpcAnimation(NpcId_SELF, ANIMATION(SpriteId_GOOMBA, 0, 13))
|
SetNpcAnimation(NpcId_SELF, NPC_ANIM(goomba, normal, fake_mushroom)) // TODO: work out why palette 0 is used here
|
||||||
EnableNpcShadow(NpcId_SELF, FALSE)
|
EnableNpcShadow(NpcId_SELF, FALSE)
|
||||||
SetSelfEnemyFlagBits(0x00000020, TRUE)
|
SetSelfEnemyFlagBits(0x00000020, TRUE)
|
||||||
|
|
||||||
@ -104,15 +105,15 @@ Script M(GoombaIdle) = SCRIPT({
|
|||||||
SetNpcRotation(NpcId_SELF, 0, SI_VAR(0), 0)
|
SetNpcRotation(NpcId_SELF, 0, SI_VAR(0), 0)
|
||||||
sleep 1
|
sleep 1
|
||||||
}
|
}
|
||||||
SetNpcAnimation(NpcId_SELF, ANIMATION(SpriteId_GOOMBA, 0, 0))
|
SetNpcAnimation(NpcId_SELF, NPC_ANIM(goomba, normal, still))
|
||||||
loop 9 {
|
loop 9 {
|
||||||
SI_VAR(0) += 10.0
|
SI_VAR(0) += 10.0
|
||||||
SetNpcRotation(NpcId_SELF, 0, SI_VAR(0), 0)
|
SetNpcRotation(NpcId_SELF, 0, SI_VAR(0), 0)
|
||||||
sleep 1
|
sleep 1
|
||||||
}
|
}
|
||||||
SetNpcAnimation(NpcId_SELF, ANIMATION(SpriteId_GOOMBA, 0, 7))
|
SetNpcAnimation(NpcId_SELF, NPC_ANIM(goomba, normal, dizzy))
|
||||||
sleep 20
|
sleep 20
|
||||||
SetNpcAnimation(NpcId_SELF, ANIMATION(SpriteId_GOOMBA, 0, 1))
|
SetNpcAnimation(NpcId_SELF, NPC_ANIM(goomba, normal, idle))
|
||||||
PlaySoundAtNpc(NpcId_SELF, 248, 0)
|
PlaySoundAtNpc(NpcId_SELF, 248, 0)
|
||||||
func_802CFE2C(NpcId_SELF, 8192)
|
func_802CFE2C(NpcId_SELF, 8192)
|
||||||
func_802CFD30(NpcId_SELF, 5, 6, 1, 1, 0)
|
func_802CFD30(NpcId_SELF, 5, 6, 1, 1, 0)
|
||||||
@ -166,22 +167,22 @@ StaticNpc M(goombaNpc) = {
|
|||||||
/* flying? */ TRUE,
|
/* flying? */ TRUE,
|
||||||
},
|
},
|
||||||
.animations = {
|
.animations = {
|
||||||
ANIMATION(SpriteId_GOOMBA, 0, 1),
|
NPC_ANIM(goomba, normal, idle),
|
||||||
ANIMATION(SpriteId_GOOMBA, 0, 2),
|
NPC_ANIM(goomba, normal, walk),
|
||||||
ANIMATION(SpriteId_GOOMBA, 0, 3),
|
NPC_ANIM(goomba, normal, run),
|
||||||
ANIMATION(SpriteId_GOOMBA, 0, 3),
|
NPC_ANIM(goomba, normal, run),
|
||||||
ANIMATION(SpriteId_GOOMBA, 0, 1),
|
NPC_ANIM(goomba, normal, idle),
|
||||||
ANIMATION(SpriteId_GOOMBA, 0, 1),
|
NPC_ANIM(goomba, normal, idle),
|
||||||
ANIMATION(SpriteId_GOOMBA, 0, 5),
|
NPC_ANIM(goomba, normal, pain),
|
||||||
ANIMATION(SpriteId_GOOMBA, 0, 5),
|
NPC_ANIM(goomba, normal, pain),
|
||||||
ANIMATION(SpriteId_GOOMBA, 0, 3),
|
NPC_ANIM(goomba, normal, run),
|
||||||
ANIMATION(SpriteId_GOOMBA, 0, 3),
|
NPC_ANIM(goomba, normal, run),
|
||||||
ANIMATION(SpriteId_GOOMBA, 0, 3),
|
NPC_ANIM(goomba, normal, run),
|
||||||
ANIMATION(SpriteId_GOOMBA, 0, 3),
|
NPC_ANIM(goomba, normal, run),
|
||||||
ANIMATION(SpriteId_GOOMBA, 0, 3),
|
NPC_ANIM(goomba, normal, run),
|
||||||
ANIMATION(SpriteId_GOOMBA, 0, 3),
|
NPC_ANIM(goomba, normal, run),
|
||||||
ANIMATION(SpriteId_GOOMBA, 0, 3),
|
NPC_ANIM(goomba, normal, run),
|
||||||
ANIMATION(SpriteId_GOOMBA, 0, 3),
|
NPC_ANIM(goomba, normal, run),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
115
tools/compile_npc_sprite.py
Executable file
115
tools/compile_npc_sprite.py
Executable file
@ -0,0 +1,115 @@
|
|||||||
|
#! /usr/bin/python3
|
||||||
|
|
||||||
|
from sys import argv, path
|
||||||
|
from pathlib import Path
|
||||||
|
import os
|
||||||
|
path.append(os.path.join(os.path.dirname(__file__), "n64splat"))
|
||||||
|
from splat_ext.PaperMarioNpcSprites import Sprite
|
||||||
|
from convert_image import pack_color, iter_in_groups
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(argv) != 3:
|
||||||
|
print("usage: compile_npc_sprite.py [OUTBIN] [DIR]")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
_, outfile, sprite_dir = argv
|
||||||
|
|
||||||
|
try:
|
||||||
|
sprite = Sprite.from_dir(Path(sprite_dir))
|
||||||
|
except AssertionError as e:
|
||||||
|
print("error:", e)
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
with open(outfile, "wb") as f:
|
||||||
|
f.seek(0x10) # leave space for header
|
||||||
|
|
||||||
|
# leave space for animation offset list
|
||||||
|
f.seek((len(sprite.animations) + 1) * 4, 1)
|
||||||
|
animation_offsets = []
|
||||||
|
|
||||||
|
# write animations
|
||||||
|
for i, components in enumerate(sprite.animations):
|
||||||
|
animation_offsets.append(f.tell())
|
||||||
|
|
||||||
|
# leave space for component offset list
|
||||||
|
f.seek((len(components) + 1) * 4, 1)
|
||||||
|
component_offsets = []
|
||||||
|
|
||||||
|
for comp in components:
|
||||||
|
offset = f.tell()
|
||||||
|
|
||||||
|
for command in comp.commands:
|
||||||
|
f.write(command.to_bytes(2, byteorder="big"))
|
||||||
|
|
||||||
|
f.seek(f.tell() % 4, 1)
|
||||||
|
component_offsets.append(f.tell())
|
||||||
|
|
||||||
|
f.write(offset.to_bytes(4, byteorder="big"))
|
||||||
|
f.write((len(comp.commands) * 2).to_bytes(2, byteorder="big"))
|
||||||
|
f.write(comp.x.to_bytes(2, byteorder="big"))
|
||||||
|
f.write(comp.y.to_bytes(2, byteorder="big"))
|
||||||
|
f.write(comp.z.to_bytes(2, byteorder="big"))
|
||||||
|
|
||||||
|
next_anim = f.tell()
|
||||||
|
|
||||||
|
# write component offset list
|
||||||
|
f.seek(animation_offsets[i])
|
||||||
|
component_offsets.append(-1)
|
||||||
|
for offset in component_offsets:
|
||||||
|
f.write(offset.to_bytes(4, byteorder="big", signed=True))
|
||||||
|
|
||||||
|
f.seek(next_anim)
|
||||||
|
|
||||||
|
# palettes start 8-byte aligned
|
||||||
|
if (f.tell() & 7) == 4:
|
||||||
|
f.seek(4, 1)
|
||||||
|
|
||||||
|
# write palettes
|
||||||
|
palette_offsets = []
|
||||||
|
for i, palette in enumerate(sprite.palettes):
|
||||||
|
palette_offsets.append(f.tell())
|
||||||
|
for rgba in palette:
|
||||||
|
if rgba[3] not in (0, 0xFF):
|
||||||
|
print("error: translucent pixels not allowed in palette {sprite.palette_names[i]}")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
color = pack_color(*rgba)
|
||||||
|
f.write(color.to_bytes(2, byteorder="big"))
|
||||||
|
|
||||||
|
# write images/rasters
|
||||||
|
image_offsets = []
|
||||||
|
for image in sprite.images:
|
||||||
|
offset = f.tell()
|
||||||
|
|
||||||
|
for a, b in iter_in_groups(image.raster, 2):
|
||||||
|
byte = (a << 4) | b
|
||||||
|
f.write(byte.to_bytes(1, byteorder="big"))
|
||||||
|
|
||||||
|
image_offsets.append(f.tell())
|
||||||
|
|
||||||
|
f.write(offset.to_bytes(4, byteorder="big"))
|
||||||
|
f.write(bytes([image.width, image.height, image.palette_index, 0xFF]))
|
||||||
|
|
||||||
|
# write image offset list
|
||||||
|
image_offset_list_offset = f.tell()
|
||||||
|
image_offsets.append(-1)
|
||||||
|
for offset in image_offsets:
|
||||||
|
f.write(offset.to_bytes(4, byteorder="big", signed=True))
|
||||||
|
|
||||||
|
# write palette offset list
|
||||||
|
palette_offset_list_offset = f.tell()
|
||||||
|
palette_offsets.append(-1)
|
||||||
|
for offset in palette_offsets:
|
||||||
|
f.write(offset.to_bytes(4, byteorder="big", signed=True))
|
||||||
|
|
||||||
|
# write header
|
||||||
|
f.seek(0)
|
||||||
|
f.write(image_offset_list_offset.to_bytes(4, byteorder="big"))
|
||||||
|
f.write(palette_offset_list_offset.to_bytes(4, byteorder="big"))
|
||||||
|
f.write(sprite.max_components.to_bytes(4, byteorder="big"))
|
||||||
|
f.write(sprite.num_variations.to_bytes(4, byteorder="big"))
|
||||||
|
|
||||||
|
# write animation offset list
|
||||||
|
animation_offsets.append(-1)
|
||||||
|
for offset in animation_offsets:
|
||||||
|
f.write(offset.to_bytes(4, byteorder="big", signed=True))
|
30
tools/compile_npc_sprites.py
Executable file
30
tools/compile_npc_sprites.py
Executable file
@ -0,0 +1,30 @@
|
|||||||
|
#! /usr/bin/python3
|
||||||
|
|
||||||
|
from sys import argv
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(argv) < 4:
|
||||||
|
print("usage: compile_npc_sprites.py [OUTBIN] [INFILES]")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
_, outfile, *infiles = argv
|
||||||
|
|
||||||
|
with open(outfile, "wb") as f:
|
||||||
|
offsets = []
|
||||||
|
|
||||||
|
f.seek(4 * (len(infiles) + 1))
|
||||||
|
|
||||||
|
for filename in infiles:
|
||||||
|
with open(filename, "rb") as spritef:
|
||||||
|
offsets.append(f.tell())
|
||||||
|
f.write(spritef.read())
|
||||||
|
|
||||||
|
# align
|
||||||
|
while f.tell() % 8 != 0:
|
||||||
|
f.write(bytes([0]))
|
||||||
|
|
||||||
|
offsets.append(f.tell())
|
||||||
|
|
||||||
|
f.seek(0)
|
||||||
|
for offset in offsets:
|
||||||
|
f.write(offset.to_bytes(4, byteorder="big"))
|
44
tools/gen_sprite_animations_h.py
Executable file
44
tools/gen_sprite_animations_h.py
Executable file
@ -0,0 +1,44 @@
|
|||||||
|
#! /usr/bin/python3
|
||||||
|
|
||||||
|
from sys import argv, path
|
||||||
|
from pathlib import Path
|
||||||
|
import os
|
||||||
|
path.append(os.path.join(os.path.dirname(__file__), "n64splat"))
|
||||||
|
from splat_ext.PaperMarioNpcSprites import Sprite
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(argv) < 4:
|
||||||
|
print("usage: gen_sprite_animations_h.py [OUT] [DIR] [ALLDIRS]")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
_, outfile, sprite_dir, *alldirs = argv
|
||||||
|
|
||||||
|
with open(outfile, "w") as f:
|
||||||
|
# get sprite index
|
||||||
|
s = alldirs.index(sprite_dir) + 1
|
||||||
|
assert s >= 1
|
||||||
|
|
||||||
|
sprite_dir = Path(sprite_dir)
|
||||||
|
|
||||||
|
sprite = Sprite.from_dir(sprite_dir, read_images=False)
|
||||||
|
sprite_name = sprite_dir.stem
|
||||||
|
|
||||||
|
f.write(f"#ifndef _SPRITE_{sprite_name.upper()}_H_\n")
|
||||||
|
f.write(f"#define _SPRITE_{sprite_name.upper()}_H_\n")
|
||||||
|
f.write("\n")
|
||||||
|
f.write('#include "types.h"\n')
|
||||||
|
f.write("\n")
|
||||||
|
|
||||||
|
f.write(f"#define _NPC_SPRITE_{sprite_name} 0x{s:02X}\n")
|
||||||
|
|
||||||
|
seen_palette_names = set()
|
||||||
|
for p, palette_name in enumerate(sprite.palette_names):
|
||||||
|
if palette_name not in seen_palette_names:
|
||||||
|
seen_palette_names.add(palette_name)
|
||||||
|
f.write(f"#define _NPC_PALETTE_{sprite_name}_{palette_name} 0x{p:02X}\n")
|
||||||
|
|
||||||
|
for a, name in enumerate(sprite.animation_names):
|
||||||
|
f.write(f"#define _NPC_ANIM_{sprite_name}_{name} 0x{a:02X}\n")
|
||||||
|
|
||||||
|
f.write("\n")
|
||||||
|
f.write("#endif\n")
|
@ -1 +1 @@
|
|||||||
Subproject commit 24aa8a9d284cbc170d691f20874171b018deb53e
|
Subproject commit 686be7cf19780b5dd619e0f51bb071f721b05b9a
|
0
tools/sort_symbol_addrs.py
Normal file → Executable file
0
tools/sort_symbol_addrs.py
Normal file → Executable file
886
tools/splat.yaml
886
tools/splat.yaml
@ -6869,400 +6869,497 @@ segments:
|
|||||||
vram: 0x802B7000
|
vram: 0x802B7000
|
||||||
files:
|
files:
|
||||||
- [0xE21870, c]
|
- [0xE21870, c]
|
||||||
- [0xE21EB0, bin]
|
- [0xE21EB0, "bin"]
|
||||||
- [0xE225B0, bin]
|
- [0xE225B0, "bin"]
|
||||||
- [0xF007C0, bin, Battle_Fanfare_02] # BGM start
|
- [0xF007C0, "bin", "Battle_Fanfare_02"] # BGM start
|
||||||
- [0xF02160, bin, Hey_You_03]
|
- [0xF02160, "bin", "Hey_You_03"]
|
||||||
- [0xF03740, bin, The_Goomba_King_s_Decree_07]
|
- [0xF03740, "bin", "The_Goomba_King_s_Decree_07"]
|
||||||
- [0xF043F0, bin, Attack_of_the_Koopa_Bros_08]
|
- [0xF043F0, "bin", "Attack_of_the_Koopa_Bros_08"]
|
||||||
- [0xF073C0, bin, Trojan_Bowser_09]
|
- [0xF073C0, "bin", "Trojan_Bowser_09"]
|
||||||
- [0xF08D40, bin, Chomp_Attack_0A]
|
- [0xF08D40, "bin", "Chomp_Attack_0A"]
|
||||||
- [0xF09600, bin, Ghost_Gulping_0B]
|
- [0xF09600, "bin", "Ghost_Gulping_0B"]
|
||||||
- [0xF0A550, bin, Keeping_Pace_0C]
|
- [0xF0A550, "bin", "Keeping_Pace_0C"]
|
||||||
- [0xF0BAE0, bin, Go_Mario_Go_0D]
|
- [0xF0BAE0, "bin", "Go_Mario_Go_0D"]
|
||||||
- [0xF0DEC0, bin, Huffin_and_Puffin_0E]
|
- [0xF0DEC0, "bin", "Huffin_and_Puffin_0E"]
|
||||||
- [0xF0FD20, bin, Freeze_0F]
|
- [0xF0FD20, "bin", "Freeze_0F"]
|
||||||
- [0xF110D0, bin, Winning_a_Battle_8B]
|
- [0xF110D0, "bin", "Winning_a_Battle_8B"]
|
||||||
- [0xF116C0, bin, Winning_a_Battle_and_Level_Up_8E]
|
- [0xF116C0, "bin", "Winning_a_Battle_and_Level_Up_8E"]
|
||||||
- [0xF12320, bin, Jr_Troopa_Battle_04]
|
- [0xF12320, "bin", "Jr_Troopa_Battle_04"]
|
||||||
- [0xF13C20, bin, Final_Bowser_Battle_interlude_05]
|
- [0xF13C20, "bin", "Final_Bowser_Battle_interlude_05"]
|
||||||
- [0xF15F40, bin, Master_Battle_2C]
|
- [0xF15F40, "bin", "Master_Battle_2C"]
|
||||||
- [0xF16F80, bin, Game_Over_87]
|
- [0xF16F80, "bin", "Game_Over_87"]
|
||||||
- [0xF171D0, bin, Resting_at_the_Toad_House_88]
|
- [0xF171D0, "bin", "Resting_at_the_Toad_House_88"]
|
||||||
- [0xF17370, bin, Running_around_the_Heart_Pillar_in_Ch1_84]
|
- [0xF17370, "bin", "Running_around_the_Heart_Pillar_in_Ch1_84"]
|
||||||
- [0xF17570, bin, Tutankoopa_s_Warning_45]
|
- [0xF17570, "bin", "Tutankoopa_s_Warning_45"]
|
||||||
- [0xF18940, bin, Kammy_Koopa_s_Theme_46]
|
- [0xF18940, "bin", "Kammy_Koopa_s_Theme_46"]
|
||||||
- [0xF193D0, bin, Jr_Troopa_s_Theme_47]
|
- [0xF193D0, "bin", "Jr_Troopa_s_Theme_47"]
|
||||||
- [0xF19BC0, bin, Goomba_King_s_Theme_50]
|
- [0xF19BC0, "bin", "Goomba_King_s_Theme_50"]
|
||||||
- [0xF1A6F0, bin, Koopa_Bros_Defeated_51]
|
- [0xF1A6F0, "bin", "Koopa_Bros_Defeated_51"]
|
||||||
- [0xF1ABD0, bin, Koopa_Bros_Theme_52]
|
- [0xF1ABD0, "bin", "Koopa_Bros_Theme_52"]
|
||||||
- [0xF1C810, bin, Tutankoopa_s_Warning_2_53]
|
- [0xF1C810, "bin", "Tutankoopa_s_Warning_2_53"]
|
||||||
- [0xF1DBF0, bin, Tutankoopa_s_Theme_54]
|
- [0xF1DBF0, "bin", "Tutankoopa_s_Theme_54"]
|
||||||
- [0xF1F2E0, bin, Tubba_Blubba_s_Theme_55]
|
- [0xF1F2E0, "bin", "Tubba_Blubba_s_Theme_55"]
|
||||||
- [0xF20FF0, bin, General_Guy_s_Theme_56]
|
- [0xF20FF0, "bin", "General_Guy_s_Theme_56"]
|
||||||
- [0xF21780, bin, Lava_Piranha_s_Theme_57]
|
- [0xF21780, "bin", "Lava_Piranha_s_Theme_57"]
|
||||||
- [0xF22A00, bin, Huff_N_Puff_s_Theme_58]
|
- [0xF22A00, "bin", "Huff_N_Puff_s_Theme_58"]
|
||||||
- [0xF23A00, bin, Crystal_King_s_Theme_59]
|
- [0xF23A00, "bin", "Crystal_King_s_Theme_59"]
|
||||||
- [0xF24810, bin, Blooper_s_Theme_5A]
|
- [0xF24810, "bin", "Blooper_s_Theme_5A"]
|
||||||
- [0xF25240, bin, Midboss_Theme_5B]
|
- [0xF25240, "bin", "Midboss_Theme_5B"]
|
||||||
- [0xF26260, bin, Monstar_s_Theme_5C]
|
- [0xF26260, "bin", "Monstar_s_Theme_5C"]
|
||||||
- [0xF27840, bin, Moustafa_s_Theme_86]
|
- [0xF27840, "bin", "Moustafa_s_Theme_86"]
|
||||||
- [0xF27E20, bin, Fuzzy_Searching_Minigame_85]
|
- [0xF27E20, "bin", "Fuzzy_Searching_Minigame_85"]
|
||||||
- [0xF28E20, bin, Phonograph_in_Mansion_44]
|
- [0xF28E20, "bin", "Phonograph_in_Mansion_44"]
|
||||||
- [0xF29AC0, bin, Toad_Town_00]
|
- [0xF29AC0, "bin", "Toad_Town_00"]
|
||||||
- [0xF2E130, bin, Bill_Blaster_Theme_48]
|
- [0xF2E130, "bin", "Bill_Blaster_Theme_48"]
|
||||||
- [0xF2EF90, bin, Monty_Mole_Theme_in_Flower_Fields_49]
|
- [0xF2EF90, "bin", "Monty_Mole_Theme_in_Flower_Fields_49"]
|
||||||
- [0xF30590, bin, Shy_Guys_in_Toad_Town_4A]
|
- [0xF30590, "bin", "Shy_Guys_in_Toad_Town_4A"]
|
||||||
- [0xF318B0, bin, Whale_s_Problem_4C]
|
- [0xF318B0, "bin", "Whale_s_Problem_4C"]
|
||||||
- [0xF32220, bin, Toad_Town_Sewers_4B]
|
- [0xF32220, "bin", "Toad_Town_Sewers_4B"]
|
||||||
- [0xF33060, bin, Unused_Theme_4D]
|
- [0xF33060, "bin", "Unused_Theme_4D"]
|
||||||
- [0xF33AA0, bin, Mario_s_House_Prologue_3E]
|
- [0xF33AA0, "bin", "Mario_s_House_Prologue_3E"]
|
||||||
- [0xF33F10, bin, Peach_s_Party_3F]
|
- [0xF33F10, "bin", "Peach_s_Party_3F"]
|
||||||
- [0xF354E0, bin, Goomba_Village_01]
|
- [0xF354E0, "bin", "Goomba_Village_01"]
|
||||||
- [0xF35ED0, bin, Pleasant_Path_11]
|
- [0xF35ED0, "bin", "Pleasant_Path_11"]
|
||||||
- [0xF36690, bin, Fuzzy_s_Took_My_Shell_12]
|
- [0xF36690, "bin", "Fuzzy_s_Took_My_Shell_12"]
|
||||||
- [0xF379E0, bin, Koopa_Village_13]
|
- [0xF379E0, "bin", "Koopa_Village_13"]
|
||||||
- [0xF38570, bin, Koopa_Bros_Fortress_14]
|
- [0xF38570, "bin", "Koopa_Bros_Fortress_14"]
|
||||||
- [0xF39160, bin, Dry_Dry_Ruins_18]
|
- [0xF39160, "bin", "Dry_Dry_Ruins_18"]
|
||||||
- [0xF3A0D0, bin, Dry_Dry_Ruins_Mystery_19]
|
- [0xF3A0D0, "bin", "Dry_Dry_Ruins_Mystery_19"]
|
||||||
- [0xF3A450, bin, Mt_Rugged_16]
|
- [0xF3A450, "bin", "Mt_Rugged_16"]
|
||||||
- [0xF3AF20, bin, Dry_Dry_Desert_Oasis_17]
|
- [0xF3AF20, "bin", "Dry_Dry_Desert_Oasis_17"]
|
||||||
- [0xF3C130, bin, Dry_Dry_Outpost_15]
|
- [0xF3C130, "bin", "Dry_Dry_Outpost_15"]
|
||||||
- [0xF3CCC0, bin, Forever_Forest_1A]
|
- [0xF3CCC0, "bin", "Forever_Forest_1A"]
|
||||||
- [0xF3E130, bin, Boo_s_Mansion_1B]
|
- [0xF3E130, "bin", "Boo_s_Mansion_1B"]
|
||||||
- [0xF3F3E0, bin, Bow_s_Theme_1C]
|
- [0xF3F3E0, "bin", "Bow_s_Theme_1C"]
|
||||||
- [0xF40F00, bin, Gusty_Gulch_Adventure_1D]
|
- [0xF40F00, "bin", "Gusty_Gulch_Adventure_1D"]
|
||||||
- [0xF42F30, bin, Tubba_Blubba_s_Castle_1E]
|
- [0xF42F30, "bin", "Tubba_Blubba_s_Castle_1E"]
|
||||||
- [0xF45500, bin, The_Castle_Crumbles_1F]
|
- [0xF45500, "bin", "The_Castle_Crumbles_1F"]
|
||||||
- [0xF465E0, bin, Shy_Guy_s_Toy_Box_20]
|
- [0xF465E0, "bin", "Shy_Guy_s_Toy_Box_20"]
|
||||||
- [0xF474A0, bin, Toy_Train_Travel_21]
|
- [0xF474A0, "bin", "Toy_Train_Travel_21"]
|
||||||
- [0xF47E10, bin, Big_Lantern_Ghost_s_Theme_22]
|
- [0xF47E10, "bin", "Big_Lantern_Ghost_s_Theme_22"]
|
||||||
- [0xF48410, bin, Jade_Jungle_24]
|
- [0xF48410, "bin", "Jade_Jungle_24"]
|
||||||
- [0xF4A880, bin, Deep_Jungle_25]
|
- [0xF4A880, "bin", "Deep_Jungle_25"]
|
||||||
- [0xF4BC00, bin, Lavalava_Island_26]
|
- [0xF4BC00, "bin", "Lavalava_Island_26"]
|
||||||
- [0xF4E690, bin, Search_for_the_Fearsome_5_27]
|
- [0xF4E690, "bin", "Search_for_the_Fearsome_5_27"]
|
||||||
- [0xF50A00, bin, Raphael_the_Raven_28]
|
- [0xF50A00, "bin", "Raphael_the_Raven_28"]
|
||||||
- [0xF52520, bin, Hot_Times_in_Mt_Lavalava_29]
|
- [0xF52520, "bin", "Hot_Times_in_Mt_Lavalava_29"]
|
||||||
- [0xF55C80, bin, Escape_from_Mt_Lavalava_2A]
|
- [0xF55C80, "bin", "Escape_from_Mt_Lavalava_2A"]
|
||||||
- [0xF58ED0, bin, Cloudy_Climb_32]
|
- [0xF58ED0, "bin", "Cloudy_Climb_32"]
|
||||||
- [0xF592B0, bin, Puff_Puff_Machine_33]
|
- [0xF592B0, "bin", "Puff_Puff_Machine_33"]
|
||||||
- [0xF5AFF0, bin, Flower_Fields_30]
|
- [0xF5AFF0, "bin", "Flower_Fields_30"]
|
||||||
- [0xF5C8D0, bin, Flower_Fields_Sunny_31]
|
- [0xF5C8D0, "bin", "Flower_Fields_Sunny_31"]
|
||||||
- [0xF5DF40, bin, Sun_s_Tower_34]
|
- [0xF5DF40, "bin", "Sun_s_Tower_34"]
|
||||||
- [0xF5F500, bin, Sun_s_Celebration_35]
|
- [0xF5F500, "bin", "Sun_s_Celebration_35"]
|
||||||
- [0xF61700, bin, Shiver_City_38]
|
- [0xF61700, "bin", "Shiver_City_38"]
|
||||||
- [0xF62E50, bin, Detective_Mario_39]
|
- [0xF62E50, "bin", "Detective_Mario_39"]
|
||||||
- [0xF64220, bin, Snow_Road_3A]
|
- [0xF64220, "bin", "Snow_Road_3A"]
|
||||||
- [0xF64CB0, bin, Over_Shiver_Mountain_3B]
|
- [0xF64CB0, "bin", "Over_Shiver_Mountain_3B"]
|
||||||
- [0xF65B30, bin, Starborn_Valley_3C]
|
- [0xF65B30, "bin", "Starborn_Valley_3C"]
|
||||||
- [0xF66690, bin, Sanctuary_3D]
|
- [0xF66690, "bin", "Sanctuary_3D"]
|
||||||
- [0xF66B70, bin, Crystal_Palace_37]
|
- [0xF66B70, "bin", "Crystal_Palace_37"]
|
||||||
- [0xF67F80, bin, Star_Haven_60]
|
- [0xF67F80, "bin", "Star_Haven_60"]
|
||||||
- [0xF69640, bin, Shooting_Star_Summit_61]
|
- [0xF69640, "bin", "Shooting_Star_Summit_61"]
|
||||||
- [0xF6A050, bin, Legendary_Star_Ship_62]
|
- [0xF6A050, "bin", "Legendary_Star_Ship_62"]
|
||||||
- [0xF6C270, bin, Star_Sanctuary_63]
|
- [0xF6C270, "bin", "Star_Sanctuary_63"]
|
||||||
- [0xF6CED0, bin, Bowser_s_Castle_-_Caves_65]
|
- [0xF6CED0, "bin", "Bowser_s_Castle_-_Caves_65"]
|
||||||
- [0xF6EE40, bin, Bowser_s_Castle_64]
|
- [0xF6EE40, "bin", "Bowser_s_Castle_64"]
|
||||||
- [0xF73390, bin, Star_Elevator_2B]
|
- [0xF73390, "bin", "Star_Elevator_2B"]
|
||||||
- [0xF751F0, bin, Goomba_Bros_Defeated_7E]
|
- [0xF751F0, "bin", "Goomba_Bros_Defeated_7E"]
|
||||||
- [0xF759C0, bin, Farewell_Twink_70]
|
- [0xF759C0, "bin", "Farewell_Twink_70"]
|
||||||
- [0xF77200, bin, Peach_Cooking_71]
|
- [0xF77200, "bin", "Peach_Cooking_71"]
|
||||||
- [0xF77680, bin, Gourmet_Guy_72]
|
- [0xF77680, "bin", "Gourmet_Guy_72"]
|
||||||
- [0xF78600, bin, Hope_on_the_Balcony_Peach_1_73]
|
- [0xF78600, "bin", "Hope_on_the_Balcony_Peach_1_73"]
|
||||||
- [0xF79070, bin, Peach_s_Theme_2_74]
|
- [0xF79070, "bin", "Peach_s_Theme_2_74"]
|
||||||
- [0xF7A0C0, bin, Peach_Sneaking_75]
|
- [0xF7A0C0, "bin", "Peach_Sneaking_75"]
|
||||||
- [0xF7AA40, bin, Peach_Captured_76]
|
- [0xF7AA40, "bin", "Peach_Captured_76"]
|
||||||
- [0xF7AD90, bin, Quiz_Show_Intro_77]
|
- [0xF7AD90, "bin", "Quiz_Show_Intro_77"]
|
||||||
- [0xF7BEA0, bin, Unconscious_Mario_78]
|
- [0xF7BEA0, "bin", "Unconscious_Mario_78"]
|
||||||
- [0xF7C780, bin, Petunia_s_Theme_89]
|
- [0xF7C780, "bin", "Petunia_s_Theme_89"]
|
||||||
- [0xF7DC00, bin, Flower_Fields_Door_appears_8A]
|
- [0xF7DC00, "bin", "Flower_Fields_Door_appears_8A"]
|
||||||
- [0xF7E190, bin, Beanstalk_7B]
|
- [0xF7E190, "bin", "Beanstalk_7B"]
|
||||||
- [0xF7EE20, bin, Lakilester_s_Theme_7D]
|
- [0xF7EE20, "bin", "Lakilester_s_Theme_7D"]
|
||||||
- [0xF80230, bin, The_Sun_s_Back_7F]
|
- [0xF80230, "bin", "The_Sun_s_Back_7F"]
|
||||||
- [0xF81260, bin, Shiver_City_in_Crisis_79]
|
- [0xF81260, "bin", "Shiver_City_in_Crisis_79"]
|
||||||
- [0xF82460, bin, Solved_Shiver_City_Mystery_7A]
|
- [0xF82460, "bin", "Solved_Shiver_City_Mystery_7A"]
|
||||||
- [0xF82D00, bin, Merlon_s_Spell_7C]
|
- [0xF82D00, "bin", "Merlon_s_Spell_7C"]
|
||||||
- [0xF83DC0, bin, Bowser_s_Theme_66]
|
- [0xF83DC0, "bin", "Bowser_s_Theme_66"]
|
||||||
- [0xF85590, bin, Train_Travel_80]
|
- [0xF85590, "bin", "Train_Travel_80"]
|
||||||
- [0xF860E0, bin, Whale_Trip_81]
|
- [0xF860E0, "bin", "Whale_Trip_81"]
|
||||||
- [0xF87000, bin, Chanterelle_s_Song_8C]
|
- [0xF87000, "bin", "Chanterelle_s_Song_8C"]
|
||||||
- [0xF87610, bin, Boo_s_Game_8D]
|
- [0xF87610, "bin", "Boo_s_Game_8D"]
|
||||||
- [0xF88B30, bin, Dry_Dry_Ruins_rises_up_83]
|
- [0xF88B30, "bin", "Dry_Dry_Ruins_rises_up_83"]
|
||||||
- [0xF89570, bin, End_of_Chapter_40]
|
- [0xF89570, "bin", "End_of_Chapter_40"]
|
||||||
- [0xF8AAF0, bin, Beginning_of_Chapter_41]
|
- [0xF8AAF0, "bin", "Beginning_of_Chapter_41"]
|
||||||
- [0xF8B820, bin, Hammer_and_Jump_Upgrade_42]
|
- [0xF8B820, "bin", "Hammer_and_Jump_Upgrade_42"]
|
||||||
- [0xF8BD90, bin, Found_Baby_Yoshi_s_4E]
|
- [0xF8BD90, "bin", "Found_Baby_Yoshi_s_4E"]
|
||||||
- [0xF8C360, bin, New_Partner_JAP_96]
|
- [0xF8C360, "bin", "New_Partner_JAP_96"]
|
||||||
- [0xF8D110, bin, Unused_YI_Fanfare_4F]
|
- [0xF8D110, "bin", "Unused_YI_Fanfare_4F"]
|
||||||
- [0xF8D3E0, bin, Unused_YI_Fanfare_2_5D]
|
- [0xF8D3E0, "bin", "Unused_YI_Fanfare_2_5D"]
|
||||||
- [0xF90880, bin, Peach_s_Castle_inside_Bubble_5E]
|
- [0xF90880, "bin", "Peach_s_Castle_inside_Bubble_5E"]
|
||||||
- [0xF92A50, bin, Angry_Bowser_67]
|
- [0xF92A50, "bin", "Angry_Bowser_67"]
|
||||||
- [0xF95510, bin, Bowser_s_Castle_explodes_5F]
|
- [0xF95510, "bin", "Bowser_s_Castle_explodes_5F"]
|
||||||
- [0xF96280, bin, Peach_s_Wish_68]
|
- [0xF96280, "bin", "Peach_s_Wish_68"]
|
||||||
- [0xF98520, bin, File_Select_69]
|
- [0xF98520, "bin", "File_Select_69"]
|
||||||
- [0xF98F90, bin, Title_Screen_6A]
|
- [0xF98F90, "bin", "Title_Screen_6A"]
|
||||||
- [0xF9B830, bin, Peach_s_Castle_in_Crisis_6B]
|
- [0xF9B830, "bin", "Peach_s_Castle_in_Crisis_6B"]
|
||||||
- [0xF9D3B0, bin, Mario_falls_from_Bowser_s_Castle_6C]
|
- [0xF9D3B0, "bin", "Mario_falls_from_Bowser_s_Castle_6C"]
|
||||||
- [0xF9D690, bin, Peach_s_Arrival_6D]
|
- [0xF9D690, "bin", "Peach_s_Arrival_6D"]
|
||||||
- [0xF9EF30, bin, Star_Rod_Recovered_6F]
|
- [0xF9EF30, "bin", "Star_Rod_Recovered_6F"]
|
||||||
- [0xF9FA30, bin, Mario_s_House_94]
|
- [0xF9FA30, "bin", "Mario_s_House_94"]
|
||||||
- [0xFA08A0, bin, Bowser_s_Attacks_95]
|
- [0xFA08A0, "bin", "Bowser_s_Attacks_95"]
|
||||||
- [0xFA3C60, bin, End_Parade_1_90]
|
- [0xFA3C60, "bin", "End_Parade_1_90"]
|
||||||
- [0xFA85F0, bin, End_Parade_2_91]
|
- [0xFA85F0, "bin", "End_Parade_2_91"]
|
||||||
- [0xFABE90, bin, The_End_6E]
|
- [0xFABE90, "bin", "The_End_6E"]
|
||||||
- [0xFACC80, bin, Koopa_Radio_Station_2D]
|
- [0xFACC80, "bin", "Koopa_Radio_Station_2D"]
|
||||||
- [0xFAD210, bin, The_End_Low_Frequency__2E]
|
- [0xFAD210, "bin", "The_End_Low_Frequency__2E"]
|
||||||
- [0xFAD8F0, bin, SMW_Remix_2F]
|
- [0xFAD8F0, "bin", "SMW_Remix_2F"]
|
||||||
- [0xFADE70, bin, New_Partner_82] # BGM end
|
- [0xFADE70, "bin", "New_Partner_82"] # BGM end
|
||||||
- [0xFAE860, bin]
|
- [0xFAE860, "bin"]
|
||||||
- [0x19E09A8, Yay0]
|
- [0x19E09A8, "Yay0"]
|
||||||
- [0x19E1390, Yay0]
|
- [0x19E1390, "Yay0"]
|
||||||
- [0x19E1888, Yay0]
|
- [0x19E1888, "Yay0"]
|
||||||
- [0x19E2330, Yay0]
|
- [0x19E2330, "Yay0"]
|
||||||
- [0x19E2DE0, Yay0]
|
- [0x19E2DE0, "Yay0"]
|
||||||
- [0x19E3208, Yay0]
|
- [0x19E3208, "Yay0"]
|
||||||
- [0x19E3BA8, Yay0]
|
- [0x19E3BA8, "Yay0"]
|
||||||
- [0x19E3FD8, Yay0]
|
- [0x19E3FD8, "Yay0"]
|
||||||
- [0x19E4828, Yay0]
|
- [0x19E4828, "Yay0"]
|
||||||
- [0x19E4BE0, Yay0]
|
- [0x19E4BE0, "Yay0"]
|
||||||
- [0x19E5758, Yay0]
|
- [0x19E5758, "Yay0"]
|
||||||
- [0x19E5950, Yay0]
|
- [0x19E5950, "Yay0"]
|
||||||
- [0x19E62A0, Yay0]
|
- [0x19E62A0, "Yay0"]
|
||||||
- [0x19E67B2, bin]
|
- start: 0x19E67B8
|
||||||
- [0x19E6B60, Yay0]
|
type: PaperMarioNpcSprites
|
||||||
- [0x19E7528, Yay0]
|
files:
|
||||||
- [0x19E9778, Yay0]
|
- name: world_goombario
|
||||||
- [0x19EAF38, Yay0]
|
frames:
|
||||||
- [0x19EC4E0, Yay0]
|
- walk1
|
||||||
- [0x19EDD30, Yay0]
|
- still
|
||||||
- [0x19EEB18, Yay0]
|
- walk2
|
||||||
- [0x19F0070, Yay0]
|
- pain
|
||||||
- [0x19F15A0, Yay0]
|
- headbonk
|
||||||
- [0x19F26D8, Yay0]
|
- still_copy1
|
||||||
- [0x19F5390, Yay0]
|
- still_copy2
|
||||||
- [0x19F7398, Yay0]
|
- jump
|
||||||
- [0x19FA128, Yay0]
|
- talk1
|
||||||
- [0x19FCAE8, Yay0]
|
- talk2
|
||||||
- [0x19FED70, Yay0]
|
- jump_copy
|
||||||
- [0x1A00958, Yay0]
|
- fall
|
||||||
- [0x1A02D00, Yay0]
|
- happy1
|
||||||
- [0x1A04400, Yay0]
|
- happy2
|
||||||
- [0x1A05550, Yay0]
|
- read_paper
|
||||||
- [0x1A06390, Yay0]
|
palettes:
|
||||||
- [0x1A06F98, Yay0]
|
- normal
|
||||||
- [0x1A07B68, Yay0]
|
- poisoned
|
||||||
- [0x1A0A0A0, Yay0]
|
- inactive
|
||||||
- [0x1A0ACC8, Yay0]
|
- electrified
|
||||||
- [0x1A0B780, Yay0]
|
- burnt
|
||||||
- [0x1A0BBE0, Yay0]
|
animations:
|
||||||
- [0x1A0C000, Yay0]
|
- still
|
||||||
- [0x1A0C438, Yay0]
|
- idle
|
||||||
- [0x1A0C860, Yay0]
|
- walk
|
||||||
- [0x1A0D1E8, Yay0]
|
- run
|
||||||
- [0x1A0D5B0, Yay0]
|
- jump
|
||||||
- [0x1A0D970, Yay0]
|
- fall
|
||||||
- [0x1A0EF00, Yay0]
|
- headbonk # centered at 0,0,0 rather than at base of sprite
|
||||||
- [0x1A13920, Yay0]
|
- pain
|
||||||
- [0x1A15850, Yay0]
|
- talk
|
||||||
- [0x1A183F8, Yay0]
|
- celebrate
|
||||||
- [0x1A1A608, Yay0]
|
- read_paper
|
||||||
- [0x1A1C5E8, Yay0]
|
- world_kooper
|
||||||
- [0x1A1D6D0, Yay0]
|
- world_bombette
|
||||||
- [0x1A1E478, Yay0]
|
- world_parakarry
|
||||||
- [0x1A1F370, Yay0]
|
- world_bow
|
||||||
- [0x1A226B0, Yay0]
|
- world_watt
|
||||||
- [0x1A249B8, Yay0]
|
- world_sushi
|
||||||
- [0x1A25E78, Yay0]
|
- world_lakilester
|
||||||
- [0x1A27FF0, Yay0]
|
- battle_goombario
|
||||||
- [0x1A28BE0, Yay0]
|
- battle_kooper
|
||||||
- [0x1A29680, Yay0]
|
- battle_bombette
|
||||||
- [0x1A2BC68, Yay0]
|
- battle_parakarry
|
||||||
- [0x1A2E120, Yay0]
|
- battle_bow
|
||||||
- [0x1A2F3F8, Yay0]
|
- battle_watt
|
||||||
- [0x1A31D18, Yay0]
|
- battle_sushi
|
||||||
- [0x1A33AB0, Yay0]
|
- battle_lakilester
|
||||||
- [0x1A35BB8, Yay0]
|
- kooper_without_shell
|
||||||
- [0x1A369A8, Yay0]
|
- world_eldstar
|
||||||
- [0x1A39600, Yay0]
|
- world_mamar
|
||||||
- [0x1A3B018, Yay0]
|
- world_skolar
|
||||||
- [0x1A3C310, Yay0]
|
- world_muskular
|
||||||
- [0x1A3FCC8, Yay0]
|
- world_misstar
|
||||||
- [0x1A423D8, Yay0]
|
- world_klevar
|
||||||
- [0x1A449C0, Yay0]
|
- world_kalmar
|
||||||
- [0x1A46568, Yay0]
|
- battle_eldstar
|
||||||
- [0x1A49340, Yay0]
|
- battle_mamar
|
||||||
- [0x1A4AC88, Yay0]
|
- battle_skolar
|
||||||
- [0x1A4D7E8, Yay0]
|
- battle_muskular
|
||||||
- [0x1A4E028, Yay0]
|
- battle_misstar
|
||||||
- [0x1A4FA60, Yay0]
|
- battle_klevar
|
||||||
- [0x1A531D0, Yay0]
|
- battle_kalmar
|
||||||
- [0x1A53D48, Yay0]
|
- twink
|
||||||
- [0x1A56C80, Yay0]
|
- jr_troopa
|
||||||
- [0x1A58F58, Yay0]
|
- spiked_jr_troopa
|
||||||
- [0x1A5A5A8, Yay0]
|
- spiked_para_jr_troopa
|
||||||
- [0x1A62B40, Yay0]
|
- mage_jr_troopa
|
||||||
- [0x1A641F8, Yay0]
|
- para_jr_troopa
|
||||||
- [0x1A666F0, Yay0]
|
- name: goomba
|
||||||
- [0x1A68870, Yay0]
|
frames:
|
||||||
- [0x1A6C630, Yay0]
|
- still
|
||||||
- [0x1A6D5A0, Yay0]
|
- lean_left
|
||||||
- [0x1A6EF50, Yay0]
|
- lean_right
|
||||||
- [0x1A70FF0, Yay0]
|
- pain1
|
||||||
- [0x1A74FC0, Yay0]
|
- pain2
|
||||||
- [0x1A78A40, Yay0]
|
- jump
|
||||||
- [0x1A79900, Yay0]
|
- open_mouth
|
||||||
- [0x1A7D798, Yay0]
|
- open_mouth_wide
|
||||||
- [0x1A7EEA0, Yay0]
|
- sleep
|
||||||
- [0x1A7EFD8, Yay0]
|
- dizzy1
|
||||||
- [0x1A83450, Yay0]
|
- dizzy2
|
||||||
- [0x1A85668, Yay0]
|
- dizzy3
|
||||||
- [0x1A87958, Yay0]
|
- dizzy4
|
||||||
- [0x1A8BF98, Yay0]
|
- burn_pain1
|
||||||
- [0x1A8FE28, Yay0]
|
- burn_pain2
|
||||||
- [0x1A93EA0, Yay0]
|
- burn_dead
|
||||||
- [0x1A94188, Yay0]
|
- tense
|
||||||
- [0x1A94480, Yay0]
|
- fake_plant
|
||||||
- [0x1A946A8, Yay0]
|
- fake_mushroom
|
||||||
- [0x1A94A00, Yay0]
|
- electrocute
|
||||||
- [0x1A94C58, Yay0]
|
palettes:
|
||||||
- [0x1A98D98, Yay0]
|
- normal
|
||||||
- [0x1A9BA80, Yay0]
|
- red # unused
|
||||||
- [0x1A9DB68, Yay0]
|
- hyper
|
||||||
- [0x1AA0048, Yay0]
|
- blue # unused
|
||||||
- [0x1AA0698, Yay0]
|
- gloomba
|
||||||
- [0x1AA1008, Yay0]
|
- poisoned
|
||||||
- [0x1AA6D58, Yay0]
|
- poisoned
|
||||||
- [0x1AAD600, Yay0]
|
- poisoned
|
||||||
- [0x1AB1BF0, Yay0]
|
- poisoned
|
||||||
- [0x1AB2368, Yay0]
|
- poisoned
|
||||||
- [0x1ABA290, Yay0]
|
- unk_purple_status
|
||||||
- [0x1AC14A8, Yay0]
|
- unk_purple_status
|
||||||
- [0x1AC3910, Yay0]
|
- unk_purple_status
|
||||||
- [0x1ACBC98, Yay0]
|
- unk_purple_status
|
||||||
- [0x1ACE058, Yay0]
|
- unk_purple_status
|
||||||
- [0x1ACF910, Yay0]
|
- electrified
|
||||||
- [0x1AD06D8, Yay0]
|
- electrified
|
||||||
- [0x1AD0B98, Yay0]
|
- electrified
|
||||||
- [0x1AD1E90, Yay0]
|
- electrified
|
||||||
- [0x1AD2348, Yay0]
|
- electrified
|
||||||
- [0x1AD27F8, Yay0]
|
- burnt
|
||||||
- [0x1AD28A8, Yay0]
|
- fake_mushroom
|
||||||
- [0x1AD44F0, Yay0]
|
- fake_plant
|
||||||
- [0x1AD4758, Yay0]
|
animations:
|
||||||
- [0x1AD57C0, Yay0]
|
- still
|
||||||
- [0x1AD9D50, Yay0]
|
- idle
|
||||||
- [0x1ADA498, Yay0]
|
- walk
|
||||||
- [0x1ADCFC0, Yay0]
|
- run
|
||||||
- [0x1AE2168, Yay0]
|
- headbonk # centered at 0,0,0 rather than at base of sprite
|
||||||
- [0x1AE2EA0, Yay0]
|
- pain
|
||||||
- [0x1AE6A58, Yay0]
|
- dead
|
||||||
- [0x1AEB778, Yay0]
|
- dizzy
|
||||||
- [0x1AF4958, Yay0]
|
- asleep
|
||||||
- [0x1AFCB18, Yay0]
|
- burn_pain
|
||||||
- [0x1AFF748, Yay0]
|
- burn_dead
|
||||||
- [0x1B00640, Yay0]
|
- pre_headbonk # centered at 0,0,0 rather than at base of sprite
|
||||||
- [0x1B01390, Yay0]
|
- fake_plant
|
||||||
- [0x1B01C08, Yay0]
|
- fake_mushroom
|
||||||
- [0x1B02128, Yay0]
|
- electrocute
|
||||||
- [0x1B02970, Yay0]
|
- spiked_goomba
|
||||||
- [0x1B03118, Yay0]
|
- paragoomba
|
||||||
- [0x1B03C18, Yay0]
|
- koopa_troopa
|
||||||
- [0x1B045E8, Yay0]
|
- para_troopa
|
||||||
- [0x1B04FC0, Yay0]
|
- fuzzy
|
||||||
- [0x1B05998, Yay0]
|
- bob_omb
|
||||||
- [0x1B06C88, Yay0]
|
- bullet_bill
|
||||||
- [0x1B07C48, Yay0]
|
- bill_blaster
|
||||||
- [0x1B09440, Yay0]
|
- monty_mole
|
||||||
- [0x1B0B290, Yay0]
|
- cleft
|
||||||
- [0x1B0B9A0, Yay0]
|
- pokey
|
||||||
- [0x1B0C548, Yay0]
|
- battle_bandit
|
||||||
- [0x1B0CAC0, Yay0]
|
- buzzy_beetle
|
||||||
- [0x1B0D130, Yay0]
|
- swooper
|
||||||
- [0x1B0EB80, Yay0]
|
- stone_chomp
|
||||||
- [0x1B10CC0, Yay0]
|
- putrid_piranha
|
||||||
- [0x1B129A0, Yay0]
|
- piranha_plant
|
||||||
- [0x1B13548, Yay0]
|
- sentinel
|
||||||
- [0x1B16420, Yay0]
|
- world_clubba
|
||||||
- [0x1B17128, Yay0]
|
- battle_clubba
|
||||||
- [0x1B17840, Yay0]
|
- shy_guy
|
||||||
- [0x1B19318, Yay0]
|
- groove_guy
|
||||||
- [0x1B1A030, Yay0]
|
- sky_guy
|
||||||
- [0x1B1B8C8, Yay0]
|
- pyro_guy
|
||||||
- [0x1B1BC88, Yay0]
|
- spy_guy
|
||||||
- [0x1B1C7A0, Yay0]
|
- medi_guy
|
||||||
- [0x1B1CD28, Yay0]
|
- fuzzipede
|
||||||
- [0x1B21C48, Yay0]
|
- jungle_guy
|
||||||
- [0x1B23290, Yay0]
|
- heart_plant
|
||||||
- [0x1B253E0, Yay0]
|
- hurt_plant
|
||||||
- [0x1B26660, Yay0]
|
- m_bush
|
||||||
- [0x1B283F8, Yay0]
|
- bubble
|
||||||
- [0x1B29C60, Yay0]
|
- kent_c_koopa
|
||||||
- [0x1B2A688, Yay0]
|
- dayzee
|
||||||
- [0x1B2B3E8, Yay0]
|
- lakitu
|
||||||
- [0x1B2C8D8, Yay0]
|
- spiny
|
||||||
- [0x1B2D7B0, Yay0]
|
- bzzap
|
||||||
- [0x1B2E328, Yay0]
|
- ruff_puff
|
||||||
- [0x1B2ED60, Yay0]
|
- spike_top
|
||||||
- [0x1B2FA18, Yay0]
|
- duplighost
|
||||||
- [0x1B31A18, Yay0]
|
- albino_dino
|
||||||
- [0x1B33000, Yay0]
|
- blooper
|
||||||
- [0x1B34098, Yay0]
|
- baby_blooper
|
||||||
- [0x1B34928, Yay0]
|
- gulpit
|
||||||
- [0x1B34C00, Yay0]
|
- dry_bones
|
||||||
- [0x1B35480, Yay0]
|
- thrown_bone
|
||||||
- [0x1B36440, Yay0]
|
- bony_beetle
|
||||||
- [0x1B38748, Yay0]
|
- magikoopa
|
||||||
- [0x1B39A98, Yay0]
|
- flying_magikoopa
|
||||||
- [0x1B3A2E8, Yay0]
|
- world_koopatrol
|
||||||
- [0x1B3A818, Yay0]
|
- koopatrol
|
||||||
- [0x1B3C488, Yay0]
|
- hammer_bros
|
||||||
- [0x1B3CAC8, Yay0]
|
- bush_basic
|
||||||
- [0x1B3D0A0, Yay0]
|
- bush_blocky
|
||||||
- [0x1B3D920, Yay0]
|
- bush_dry
|
||||||
- [0x1B3F060, Yay0]
|
- bush_leafy
|
||||||
- [0x1B40048, Yay0]
|
- bush_matted
|
||||||
- [0x1B40720, Yay0]
|
- world_kammy
|
||||||
- [0x1B49570, Yay0]
|
- battle_kammy
|
||||||
- [0x1B4C3E8, Yay0]
|
- goomba_bros
|
||||||
- [0x1B4DEA0, Yay0]
|
- goomba_king
|
||||||
- [0x1B4FD98, Yay0]
|
- spiky_goomnut
|
||||||
- [0x1B50CD8, Yay0]
|
- dark_toad
|
||||||
- [0x1B51B08, Yay0]
|
- koopa_bros
|
||||||
- [0x1B54258, Yay0]
|
- buzzar
|
||||||
- [0x1B580A0, Yay0]
|
- tutankoopa
|
||||||
- [0x1B5A248, Yay0]
|
- chain_chomp
|
||||||
- [0x1B5BB88, Yay0]
|
- world_tubba
|
||||||
- [0x1B5CC90, Yay0]
|
- battle_tubba
|
||||||
- [0x1B5E968, Yay0]
|
- tubbas_heart
|
||||||
- [0x1B5ED88, Yay0]
|
- big_lantern_ghost
|
||||||
- [0x1B608C0, Yay0]
|
- shy_squad_guy
|
||||||
- [0x1B625F8, Yay0]
|
- marshal_guy
|
||||||
- [0x1B633D0, Yay0]
|
- stilt_guy
|
||||||
- [0x1B64878, Yay0]
|
- stilt_guy_unfold
|
||||||
- [0x1B657E0, Yay0]
|
- shy_stack_guy
|
||||||
- [0x1B65A08, Yay0]
|
- shy_stack_unfold
|
||||||
- [0x1B65E50, Yay0]
|
- shy_stack_damage
|
||||||
- [0x1B66238, Yay0]
|
- shy_stack_rock
|
||||||
- [0x1B69580, Yay0]
|
- general_guy
|
||||||
- [0x1B6C318, Yay0]
|
- general_guy_bomb
|
||||||
- [0x1B6DD98, Yay0]
|
- tank_guy
|
||||||
- [0x1B6F150, Yay0]
|
- lava_piranha_head
|
||||||
- [0x1B71618, Yay0]
|
- petit_piranha
|
||||||
- [0x1B72890, Yay0]
|
- lava_bud
|
||||||
- [0x1B73B08, Yay0]
|
- huff_n_puff
|
||||||
- [0x1B747B8, Yay0]
|
- tuff_puff
|
||||||
- [0x1B76E30, Yay0]
|
- monstar
|
||||||
- [0x1B78EC0, Yay0]
|
- crystal_king
|
||||||
- [0x1B79A20, Yay0]
|
- world_bowser
|
||||||
- [0x1B79F08, Yay0]
|
- battle_bowser
|
||||||
- [0x1B7AA08, Yay0]
|
- luigi
|
||||||
- [0x1B7B008, Yay0]
|
- toad
|
||||||
- [0x1B7BB50, Yay0]
|
- three_sisters
|
||||||
- [0x1B7EC68, Yay0]
|
- vanna_t
|
||||||
- [0x1B7FF48, Yay0]
|
- toad_kid
|
||||||
- [0x1B81E88, Yay0]
|
- toad_guard
|
||||||
- [0x1B82058, Yay0]
|
- harry_t
|
||||||
- [0x1B82202, bin]
|
- toad_minister
|
||||||
|
- postmaster
|
||||||
|
- conductor_toad
|
||||||
|
- train_station_toad
|
||||||
|
- fishmael
|
||||||
|
- artist_toad
|
||||||
|
- koopa
|
||||||
|
- koopa_without_shell
|
||||||
|
- world_bob_omb
|
||||||
|
- whacka
|
||||||
|
- dryite
|
||||||
|
- mouser
|
||||||
|
- boo
|
||||||
|
- yoshi
|
||||||
|
- yoshi_kid
|
||||||
|
- raven
|
||||||
|
- bubulb
|
||||||
|
- penguin
|
||||||
|
- shiver_toad
|
||||||
|
- world_bandit
|
||||||
|
- goompapa
|
||||||
|
- goombaria
|
||||||
|
- goomama
|
||||||
|
- goompa
|
||||||
|
- goomma
|
||||||
|
- the_master
|
||||||
|
- chan
|
||||||
|
- lee
|
||||||
|
- merlon
|
||||||
|
- chet_rippo
|
||||||
|
- rowf
|
||||||
|
- minh_t
|
||||||
|
- russ_t
|
||||||
|
- tayce_t
|
||||||
|
- fice_t
|
||||||
|
- bartender
|
||||||
|
- chanterelle
|
||||||
|
- rip_cheato
|
||||||
|
- chuck_quizmo
|
||||||
|
- merluvlee
|
||||||
|
- merlar
|
||||||
|
- merlow
|
||||||
|
- star_kid
|
||||||
|
- kolorado_wife
|
||||||
|
- koopa_koot
|
||||||
|
- kolorado
|
||||||
|
- battle_kolorado
|
||||||
|
- archeologist
|
||||||
|
- nomadimouse
|
||||||
|
- world_merlee
|
||||||
|
- battle_merlee
|
||||||
|
- disguised_moustafa
|
||||||
|
- moustafa
|
||||||
|
- oaklie
|
||||||
|
- bootler
|
||||||
|
- yakkey
|
||||||
|
- gourmet_guy
|
||||||
|
- village_leader
|
||||||
|
- leaders_friend
|
||||||
|
- rafael_raven
|
||||||
|
- tolielup
|
||||||
|
- gate_flower
|
||||||
|
- petunia
|
||||||
|
- posie
|
||||||
|
- lily
|
||||||
|
- rosie
|
||||||
|
- sun
|
||||||
|
- lakilulu
|
||||||
|
- ninji
|
||||||
|
- mayor_penguin
|
||||||
|
- mayor_penguin_wife
|
||||||
|
- penguin_patrol
|
||||||
|
- herringway
|
||||||
|
- merle
|
||||||
|
- star_rod
|
||||||
|
- fire
|
||||||
|
- coin
|
||||||
|
- parade_peach
|
||||||
|
- parade_koopas
|
||||||
|
- parade_burnt_bowser
|
||||||
|
- parade_luigi
|
||||||
|
- parade_partners
|
||||||
|
- parade_yoshis
|
||||||
|
- parada_kolorados
|
||||||
|
- parade_chicks
|
||||||
|
- parade_ice_show
|
||||||
|
- parade_toads
|
||||||
|
- parade_batons
|
||||||
|
- parade_drums
|
||||||
|
- parade_flags
|
||||||
|
- parade_horns
|
||||||
|
- parade_tubba_balloon
|
||||||
|
- parade_wizards
|
||||||
|
- parade_mario
|
||||||
|
- parade_shy_guys
|
||||||
|
- parade_twink
|
||||||
|
- leaf
|
||||||
|
- [0x1B82208, bin]
|
||||||
- start: 0x1B83000
|
- start: 0x1B83000
|
||||||
type: PaperMarioMessages
|
type: PaperMarioMessages
|
||||||
files:
|
files:
|
||||||
@ -7314,6 +7411,7 @@ segments:
|
|||||||
- quiz/options
|
- quiz/options
|
||||||
- end/credits
|
- end/credits
|
||||||
- [0x1C84D30, bin]
|
- [0x1C84D30, bin]
|
||||||
|
- [0x1E00000, bin] # sprites here; Star Rod considers this a copy of sprite/npc.bin, but that doesnt appear to be true
|
||||||
- [0x1E40000, PaperMarioMapFS]
|
- [0x1E40000, PaperMarioMapFS]
|
||||||
- [0x27FEE22, bin]
|
- [0x27FEE22, bin]
|
||||||
- [0x2800000]
|
- [0x2800000]
|
||||||
|
301
tools/splat_ext/PaperMarioNpcSprites.py
Normal file
301
tools/splat_ext/PaperMarioNpcSprites.py
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
from segtypes.segment import N64Segment
|
||||||
|
from pathlib import Path
|
||||||
|
from util import Yay0decompress
|
||||||
|
from util.iter import iter_in_groups
|
||||||
|
from util.color import unpack_color
|
||||||
|
import png
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
class Sprite:
|
||||||
|
def __init__(self):
|
||||||
|
self.max_components = 0
|
||||||
|
self.num_variations = 0
|
||||||
|
|
||||||
|
self.images = []
|
||||||
|
self.palettes = []
|
||||||
|
self.animations = []
|
||||||
|
|
||||||
|
self.image_names = []
|
||||||
|
self.palette_names = []
|
||||||
|
self.animation_names = []
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_bytes(data):
|
||||||
|
self = Sprite()
|
||||||
|
|
||||||
|
image_offsets = Sprite.read_offset_list(data[int.from_bytes(data[0:4], byteorder="big"):])
|
||||||
|
palette_offsets = Sprite.read_offset_list(data[int.from_bytes(data[4:8], byteorder="big"):])
|
||||||
|
self.max_components = int.from_bytes(data[8:0xC], byteorder="big")
|
||||||
|
self.num_variations = int.from_bytes(data[0xC:0x10], byteorder="big")
|
||||||
|
animation_offsets = Sprite.read_offset_list(data[0x10:])
|
||||||
|
|
||||||
|
for offset in palette_offsets:
|
||||||
|
# 16 colors
|
||||||
|
color_data = data[offset : offset + 16 * 2]
|
||||||
|
self.palettes.append([unpack_color(c) for c in iter_in_groups(color_data, 2)])
|
||||||
|
|
||||||
|
for offset in image_offsets:
|
||||||
|
img = Image.from_bytes(data[offset:], data)
|
||||||
|
self.images.append(img)
|
||||||
|
|
||||||
|
for offset in animation_offsets:
|
||||||
|
anim = []
|
||||||
|
|
||||||
|
for comp_offset in Sprite.read_offset_list(data[offset:]):
|
||||||
|
comp = Component.from_bytes(data[comp_offset:], data)
|
||||||
|
anim.append(comp)
|
||||||
|
|
||||||
|
self.animations.append(anim)
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def read_offset_list(data):
|
||||||
|
l = []
|
||||||
|
pos = 0
|
||||||
|
|
||||||
|
while True:
|
||||||
|
offset = int.from_bytes(data[pos:pos+4], byteorder="big", signed=True)
|
||||||
|
|
||||||
|
if offset == -1:
|
||||||
|
break
|
||||||
|
|
||||||
|
l.append(offset)
|
||||||
|
|
||||||
|
pos += 4
|
||||||
|
|
||||||
|
return l
|
||||||
|
|
||||||
|
def write_to_dir(self, path):
|
||||||
|
SpriteSheet = ET.Element("SpriteSheet", {
|
||||||
|
"a": str(self.max_components),
|
||||||
|
"b": str(self.num_variations),
|
||||||
|
})
|
||||||
|
|
||||||
|
PaletteList = ET.SubElement(SpriteSheet, "PaletteList")
|
||||||
|
RasterList = ET.SubElement(SpriteSheet, "RasterList")
|
||||||
|
AnimationList = ET.SubElement(SpriteSheet, "AnimationList")
|
||||||
|
|
||||||
|
palette_to_raster = {}
|
||||||
|
|
||||||
|
for i, image in enumerate(self.images):
|
||||||
|
name = self.image_names[i] if self.image_names else f"Raster_{i:02X}"
|
||||||
|
image.write(path / (name + ".png"), self.palettes[image.palette_index])
|
||||||
|
|
||||||
|
if image.palette_index not in palette_to_raster:
|
||||||
|
palette_to_raster[image.palette_index] = []
|
||||||
|
palette_to_raster[image.palette_index].append(image)
|
||||||
|
|
||||||
|
ET.SubElement(RasterList, "Raster", {
|
||||||
|
"id": f"{i:X}",
|
||||||
|
"palette": f"{image.palette_index:X}",
|
||||||
|
"src": name + ".png",
|
||||||
|
})
|
||||||
|
|
||||||
|
for i, palette in enumerate(self.palettes):
|
||||||
|
name = self.palette_names[i] if self.palette_names else f"Palette_{i:02X}"
|
||||||
|
|
||||||
|
if i in palette_to_raster:
|
||||||
|
img = palette_to_raster[i][0]
|
||||||
|
else:
|
||||||
|
img = self.images[0]
|
||||||
|
|
||||||
|
img.write(path / (name + ".png"), palette)
|
||||||
|
|
||||||
|
ET.SubElement(PaletteList, "Palette", {
|
||||||
|
"id": f"{i:X}",
|
||||||
|
"src": name + ".png",
|
||||||
|
})
|
||||||
|
|
||||||
|
for i, components in enumerate(self.animations):
|
||||||
|
Animation = ET.SubElement(AnimationList, "Animation", {
|
||||||
|
"name": self.animation_names[i] if self.animation_names else f"Anim_{i:X}",
|
||||||
|
})
|
||||||
|
|
||||||
|
for j, comp in enumerate(components):
|
||||||
|
Component = ET.SubElement(Animation, "Component", {
|
||||||
|
"name": f"Comp_{j:X}",
|
||||||
|
"xyz": ",".join(map(str, [comp.x, comp.y, comp.z])),
|
||||||
|
})
|
||||||
|
|
||||||
|
for cmd in comp.commands:
|
||||||
|
ET.SubElement(Component, "Command", {"val": f"{cmd:X}"})
|
||||||
|
|
||||||
|
xml = ET.ElementTree(SpriteSheet)
|
||||||
|
|
||||||
|
# pretty print (Python 3.9+)
|
||||||
|
if hasattr(ET, "indent"):
|
||||||
|
ET.indent(xml, " ")
|
||||||
|
|
||||||
|
xml.write(str(path / "SpriteSheet.xml"), encoding="unicode")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_dir(path, read_images=True):
|
||||||
|
self = Sprite()
|
||||||
|
|
||||||
|
xml = ET.parse(str(path / "SpriteSheet.xml"))
|
||||||
|
SpriteSheet = xml.getroot()
|
||||||
|
|
||||||
|
true_max_components = 0
|
||||||
|
self.max_components = int(SpriteSheet.get("a"))
|
||||||
|
self.num_variations = int(SpriteSheet.get("b"))
|
||||||
|
|
||||||
|
for Palette in SpriteSheet.findall("./PaletteList/Palette"):
|
||||||
|
if read_images:
|
||||||
|
img = png.Reader(str(path / Palette.get("src")))
|
||||||
|
img.preamble(True)
|
||||||
|
palette = img.palette(alpha="force")
|
||||||
|
|
||||||
|
assert len(palette) == 16
|
||||||
|
|
||||||
|
self.palettes.append(palette)
|
||||||
|
|
||||||
|
self.palette_names.append(Palette.get("src").split(".png")[0])
|
||||||
|
|
||||||
|
for Raster in SpriteSheet.findall("./RasterList/Raster"):
|
||||||
|
if read_images:
|
||||||
|
img_path = str(path / Raster.get("src"))
|
||||||
|
width, height, raster, info = png.Reader(img_path).read_flat()
|
||||||
|
|
||||||
|
image = Image()
|
||||||
|
image.width = width
|
||||||
|
image.height = height
|
||||||
|
image.raster = raster
|
||||||
|
image.palette_index = int(Raster.get("palette"), base=16)
|
||||||
|
|
||||||
|
assert (image.width % 8) == 0, f"{img_path} width is not a multiple of 8"
|
||||||
|
assert (image.height % 8) == 0, f"{img_path} height is not a multiple of 8"
|
||||||
|
|
||||||
|
self.images.append(image)
|
||||||
|
|
||||||
|
self.image_names.append(Raster.get("src").split(".png")[0])
|
||||||
|
|
||||||
|
for i, Animation in enumerate(SpriteSheet.findall("./AnimationList/Animation")):
|
||||||
|
components = []
|
||||||
|
|
||||||
|
for ComponentEl in Animation.findall("Component"):
|
||||||
|
comp = Component()
|
||||||
|
|
||||||
|
x, y, z = ComponentEl.get("xyz", "0,0,0").split(",")
|
||||||
|
comp.x = int(x)
|
||||||
|
comp.y = int(y)
|
||||||
|
comp.z = int(z)
|
||||||
|
|
||||||
|
for Command in ComponentEl:
|
||||||
|
comp.commands.append(int(Command.get("val"), base=16))
|
||||||
|
|
||||||
|
components.append(comp)
|
||||||
|
|
||||||
|
self.animation_names.append(Animation.get("name"))
|
||||||
|
self.animations.append(components)
|
||||||
|
|
||||||
|
if len(components) > true_max_components:
|
||||||
|
true_max_components = len(components)
|
||||||
|
|
||||||
|
assert self.max_components == true_max_components, f"{true_max_components} component(s) used, but SpriteSheet.a = {self.max_components}"
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
|
class Image:
|
||||||
|
@staticmethod
|
||||||
|
def from_bytes(data, sprite_data):
|
||||||
|
self = Image()
|
||||||
|
|
||||||
|
raster_offset = int.from_bytes(data[0:4], byteorder="big")
|
||||||
|
self.width = data[4] & 0xFF
|
||||||
|
self.height = data[5] & 0xFF
|
||||||
|
self.palette_index = data[6]
|
||||||
|
assert data[7] == 0xFF
|
||||||
|
|
||||||
|
self.set_raster_from_bytes(sprite_data[raster_offset:])
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
|
# CI-4
|
||||||
|
def set_raster_from_bytes(self, data):
|
||||||
|
self.raster = bytearray()
|
||||||
|
|
||||||
|
for i in range(self.width * self.height // 2):
|
||||||
|
self.raster.append(data[i] >> 4)
|
||||||
|
self.raster.append(data[i] & 0xF)
|
||||||
|
|
||||||
|
def write(self, path, palette):
|
||||||
|
w = png.Writer(self.width, self.height, palette=palette)
|
||||||
|
|
||||||
|
with open(path, "wb") as f:
|
||||||
|
w.write_array(f, self.raster)
|
||||||
|
|
||||||
|
class Component:
|
||||||
|
def __init__(self):
|
||||||
|
self.x = 0
|
||||||
|
self.y = 0
|
||||||
|
self.z = 0
|
||||||
|
self.commands = []
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_bytes(data, sprite_data):
|
||||||
|
self = Component()
|
||||||
|
|
||||||
|
commands_offset = int.from_bytes(data[0:4], byteorder="big")
|
||||||
|
commands_size = int.from_bytes(data[4:6], byteorder="big") # size in bytes, not length!
|
||||||
|
commands_data = sprite_data[commands_offset : commands_offset + commands_size]
|
||||||
|
self.commands = [int.from_bytes(d[0:2], byteorder="big") for d in iter_in_groups(commands_data, 2)]
|
||||||
|
|
||||||
|
self.x = int.from_bytes(data[6:8], byteorder="big")
|
||||||
|
self.y = int.from_bytes(data[8:10], byteorder="big")
|
||||||
|
self.z = int.from_bytes(data[10:12], byteorder="big")
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
|
class N64SegPaperMarioNpcSprites(N64Segment):
|
||||||
|
DEFAULT_SPRITE_NAMES = [f"{i:02X}" for i in range(0xEA)]
|
||||||
|
|
||||||
|
def __init__(self, segment, next_segment, options):
|
||||||
|
super().__init__(segment, next_segment, options)
|
||||||
|
|
||||||
|
if type(segment) is dict and "files" in segment:
|
||||||
|
self.files = segment["files"]
|
||||||
|
else:
|
||||||
|
self.files = DEFAULT_SPRITE_NAMES
|
||||||
|
|
||||||
|
def split(self, rom_bytes, base_path):
|
||||||
|
out_dir = self.create_split_dir(base_path, "sprite/" + self.name)
|
||||||
|
|
||||||
|
data = rom_bytes[self.rom_start:self.rom_end]
|
||||||
|
pos = 0
|
||||||
|
|
||||||
|
for i, file in enumerate(self.files):
|
||||||
|
if type(file) is dict:
|
||||||
|
sprite_name = file["name"]
|
||||||
|
else:
|
||||||
|
sprite_name = file
|
||||||
|
|
||||||
|
self.log(f"Splitting sprite {sprite_name}...")
|
||||||
|
|
||||||
|
sprite_dir = self.create_split_dir(out_dir, sprite_name)
|
||||||
|
|
||||||
|
start = int.from_bytes(data[i * 4 : (i + 1) * 4], byteorder="big")
|
||||||
|
end = int.from_bytes(data[(i + 1) * 4 : (i + 2) * 4], byteorder="big")
|
||||||
|
|
||||||
|
sprite_data = Yay0decompress.decompress_yay0(data[start:end])
|
||||||
|
|
||||||
|
"""
|
||||||
|
with open(sprite_dir / "raw.bin", "wb") as f:
|
||||||
|
f.write(sprite_data)
|
||||||
|
"""
|
||||||
|
|
||||||
|
sprite = Sprite.from_bytes(sprite_data)
|
||||||
|
|
||||||
|
if type(file) is dict:
|
||||||
|
sprite.image_names = file.get("frames", [])
|
||||||
|
sprite.palette_names = file.get("palettes", [])
|
||||||
|
sprite.animation_names = file.get("animations", [])
|
||||||
|
|
||||||
|
sprite.write_to_dir(sprite_dir)
|
||||||
|
|
||||||
|
def get_ld_files(self):
|
||||||
|
return [("sprite", self.name, ".data")]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_default_name(addr):
|
||||||
|
return "npc"
|
Loading…
Reference in New Issue
Block a user