diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 9e05766838..0000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "tools/ZAP2"] - path = tools/ZAP2 - url = https://github.com/zeldaret/ZAPD.git diff --git a/Makefile b/Makefile index 15ee7e0de2..fe92cad2cc 100644 --- a/Makefile +++ b/Makefile @@ -70,7 +70,7 @@ CC_CHECK := gcc -fno-builtin -fsyntax-only -fsigned-char -std=gnu90 -D _LANGUA CPP := cpp MKLDSCRIPT := tools/mkldscript ELF2ROM := tools/elf2rom -ZAP2 := tools/ZAP2/ZAP2.out +ZAPD := tools/ZAPD/ZAPD.out OPTFLAGS := -O2 ASFLAGS := -march=vr4300 -32 -Iinclude @@ -194,7 +194,6 @@ clean: $(RM) -r $(ROM) $(ELF) build setup: - git submodule update --init --recursive $(MAKE) -C tools -j python3 fixbaserom.py python3 extract_baserom.py @@ -224,7 +223,7 @@ build/assets/%.o: assets/%.c build/src/overlays/%.o: src/overlays/%.c $(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $^ $(CC_CHECK) $^ - $(ZAP2) bovl -i $@ -cfg $^ --outputpath $(@D)/$(notdir $(@D))_reloc.s + $(ZAPD) bovl -i $@ -cfg $^ --outputpath $(@D)/$(notdir $(@D))_reloc.s -test -f $(@D)/$(notdir $(@D))_reloc.s && $(AS) $(ASFLAGS) $(@D)/$(notdir $(@D))_reloc.s -o $(@D)/$(notdir $(@D))_reloc.o @$(OBJDUMP) -d $@ > $(@:.o=.s) @@ -240,46 +239,46 @@ build/src/libultra_code_O1/llcvt.o: src/libultra_code_O1/llcvt.c @$(OBJDUMP) -d $@ > $(@:.o=.s) assets/%.c: assets/%.xml -# $(ZAP2) bsf -i $< -o $(dir $@) - $(ZAP2) bsf -eh -i $< -o $(dir $<) +# $(ZAPD) bsf -i $< -o $(dir $@) + $(ZAPD) bsf -eh -i $< -o $(dir $<) $(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o build/$(@:.c=.o) $@ build/%.rgba32.inc.c: %.rgba32.png python3 tools/touchasset.py $(addsuffix basefile.txt, $(dir $@)) - $(ZAP2) btex -tt rgba32 -i $< -o $@ + $(ZAPD) btex -tt rgba32 -i $< -o $@ build/%.rgb5a1.inc.c: %.rgb5a1.png python3 tools/touchasset.py $(addsuffix basefile.txt, $(dir $@)) - $(ZAP2) btex -tt rgb5a1 -i $< -o $@ + $(ZAPD) btex -tt rgb5a1 -i $< -o $@ build/%.i4.inc.c: %.i4.png python3 tools/touchasset.py $(addsuffix basefile.txt, $(dir $@)) - $(ZAP2) btex -tt i4 -i $< -o $@ + $(ZAPD) btex -tt i4 -i $< -o $@ build/%.i8.inc.c: %.i8.png python3 tools/touchasset.py $(addsuffix basefile.txt, $(dir $@)) - $(ZAP2) btex -tt i8 -i $< -o $@ + $(ZAPD) btex -tt i8 -i $< -o $@ build/%.ia4.inc.c: %.ia4.png python3 tools/touchasset.py $(addsuffix basefile.txt, $(dir $@)) - $(ZAP2) btex -tt ia4 -i $< -o $@ + $(ZAPD) btex -tt ia4 -i $< -o $@ build/%.ia8.inc.c: %.ia8.png python3 tools/touchasset.py $(addsuffix basefile.txt, $(dir $@)) - $(ZAP2) btex -tt ia8 -i $< -o $@ + $(ZAPD) btex -tt ia8 -i $< -o $@ build/%.ia16.inc.c: %.ia16.png python3 tools/touchasset.py $(addsuffix basefile.txt, $(dir $@)) - $(ZAP2) btex -tt ia16 -i $< -o $@ + $(ZAPD) btex -tt ia16 -i $< -o $@ build/assets/%.ci4.inc.c: assets/%.ci4.png python3 tools/touchasset.py $(addsuffix basefile.txt, $(dir $@)) - $(ZAP2) btex -tt ci4 -i $< -o $@ + $(ZAPD) btex -tt ci4 -i $< -o $@ build/%.ci8.inc.c: %.ci8.png python3 tools/touchasset.py $(addsuffix basefile.txt, $(dir $@)) - $(ZAP2) btex -tt ci8 -i $< -o $@ + $(ZAPD) btex -tt ci8 -i $< -o $@ build/assets/%.bin.inc.c: assets/%.bin python3 tools/touchasset.py $(addsuffix basefile.txt, $(dir $@)) - $(ZAP2) bblb -i $< -o $@ + $(ZAPD) bblb -i $< -o $@ diff --git a/THANKS.md b/THANKS.md deleted file mode 100644 index 0a66aa6dc7..0000000000 --- a/THANKS.md +++ /dev/null @@ -1 +0,0 @@ -Thanks to z64me and CrookedPoe for their actor documentation. diff --git a/assets/xml/objects/gameplay_field_keep.xml.ignore b/assets/xml/objects/gameplay_field_keep.xml.ignore index cbd4d5b78a..86574f2e48 100644 --- a/assets/xml/objects/gameplay_field_keep.xml.ignore +++ b/assets/xml/objects/gameplay_field_keep.xml.ignore @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@ - + @@ -42,7 +42,7 @@ - + diff --git a/assets/xml/objects/object_sk2.xml b/assets/xml/objects/object_sk2.xml index df672de691..5dc3a60597 100644 --- a/assets/xml/objects/object_sk2.xml +++ b/assets/xml/objects/object_sk2.xml @@ -29,7 +29,7 @@ - + diff --git a/extract_assets.py b/extract_assets.py index f234ca4a7f..fa378eb347 100755 --- a/extract_assets.py +++ b/extract_assets.py @@ -11,7 +11,7 @@ def ExtractScene(xmlPath, outputPath): ExtractFile(xmlPath, outputPath, 1, 1) def ExtractFile(xmlPath, outputPath, genSrcFile, incFilePrefix): - execStr = "tools/ZAP2/ZAP2.out e -eh -i %s -b baserom/ -o %s -gsf %i -ifp %i -sm tools/ZAP2/SymbolMap_OoTMqDbg.txt" % (xmlPath, outputPath, genSrcFile, incFilePrefix) + execStr = "tools/ZAPD/ZAPD.out e -eh -i %s -b baserom/ -o %s -gsf %i -ifp %i -sm tools/ZAPD/SymbolMap_OoTMqDbg.txt" % (xmlPath, outputPath, genSrcFile, incFilePrefix) print(execStr) os.system(execStr) diff --git a/spec b/spec index 51c40b3ae5..95b3b18a2c 100644 --- a/spec +++ b/spec @@ -3544,9 +3544,8 @@ endseg beginseg name "gameplay_keep" romalign 0x1000 - //include "build/baserom/gameplay_keep.o" include "build/assets/objects/gameplay_keep/gameplay_keep.o" - number 04 + number 4 endseg beginseg @@ -3816,9 +3815,8 @@ endseg beginseg name "object_sk2" romalign 0x1000 - //include "build/baserom/object_sk2.o" include "build/assets/objects/object_sk2/object_sk2.o" - number 06 + number 6 endseg beginseg @@ -4232,9 +4230,8 @@ endseg beginseg name "object_pu_box" romalign 0x1000 - //include "build/baserom/object_pu_box.o" include "build/assets/objects/object_pu_box/object_pu_box.o" - number 06 + number 6 endseg beginseg @@ -4247,7 +4244,7 @@ beginseg name "object_vase" romalign 0x1000 include "build/assets/objects/object_vase/object_vase.o" - number 06 + number 6 endseg beginseg @@ -4487,9 +4484,8 @@ endseg beginseg name "object_spot09_obj" romalign 0x1000 - //include "build/baserom/object_spot09_obj.o" include "build/assets/objects/object_spot09_obj/object_spot09_obj.o" - number 06 + number 6 endseg beginseg @@ -4507,9 +4503,8 @@ endseg beginseg name "object_spot17_obj" romalign 0x1000 - //include "build/baserom/object_spot17_obj.o" include "build/assets/objects/object_spot17_obj/object_spot17_obj.o" - number 06 + number 6 endseg beginseg @@ -5619,9 +5614,8 @@ endseg beginseg name "object_spot11_obj" romalign 0x1000 - //include "build/baserom/object_spot11_obj.o" include "build/assets/objects/object_spot11_obj/object_spot11_obj.o" - number 06 + number 6 endseg beginseg @@ -6612,3577 +6606,3577 @@ beginseg name "ydan_scene" romalign 0x1000 include "build/assets/scenes/dungeons/ydan/ydan_scene.o" - number 02 + number 2 endseg beginseg name "ydan_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/ydan/ydan_room_0.o" - number 03 + number 3 endseg beginseg name "ydan_room_1" romalign 0x1000 include "build/assets/scenes/dungeons/ydan/ydan_room_1.o" - number 03 + number 3 endseg beginseg name "ydan_room_2" romalign 0x1000 include "build/assets/scenes/dungeons/ydan/ydan_room_2.o" - number 03 + number 3 endseg beginseg name "ydan_room_3" romalign 0x1000 include "build/assets/scenes/dungeons/ydan/ydan_room_3.o" - number 03 + number 3 endseg beginseg name "ydan_room_4" romalign 0x1000 include "build/assets/scenes/dungeons/ydan/ydan_room_4.o" - number 03 + number 3 endseg beginseg name "ydan_room_5" romalign 0x1000 include "build/assets/scenes/dungeons/ydan/ydan_room_5.o" - number 03 + number 3 endseg beginseg name "ydan_room_6" romalign 0x1000 include "build/assets/scenes/dungeons/ydan/ydan_room_6.o" - number 03 + number 3 endseg beginseg name "ydan_room_7" romalign 0x1000 include "build/assets/scenes/dungeons/ydan/ydan_room_7.o" - number 03 + number 3 endseg beginseg name "ydan_room_8" romalign 0x1000 include "build/assets/scenes/dungeons/ydan/ydan_room_8.o" - number 03 + number 3 endseg beginseg name "ydan_room_9" romalign 0x1000 include "build/assets/scenes/dungeons/ydan/ydan_room_9.o" - number 03 + number 3 endseg beginseg name "ydan_room_10" romalign 0x1000 include "build/assets/scenes/dungeons/ydan/ydan_room_10.o" - number 03 + number 3 endseg beginseg name "ydan_room_11" romalign 0x1000 include "build/assets/scenes/dungeons/ydan/ydan_room_11.o" - number 03 + number 3 endseg beginseg name "ddan_scene" romalign 0x1000 include "build/assets/scenes/dungeons/ddan/ddan_scene.o" - number 02 + number 2 endseg beginseg name "ddan_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/ddan/ddan_room_0.o" - number 03 + number 3 endseg beginseg name "ddan_room_1" romalign 0x1000 include "build/assets/scenes/dungeons/ddan/ddan_room_1.o" - number 03 + number 3 endseg beginseg name "ddan_room_2" romalign 0x1000 include "build/assets/scenes/dungeons/ddan/ddan_room_2.o" - number 03 + number 3 endseg beginseg name "ddan_room_3" romalign 0x1000 include "build/assets/scenes/dungeons/ddan/ddan_room_3.o" - number 03 + number 3 endseg beginseg name "ddan_room_4" romalign 0x1000 include "build/assets/scenes/dungeons/ddan/ddan_room_4.o" - number 03 + number 3 endseg beginseg name "ddan_room_5" romalign 0x1000 include "build/assets/scenes/dungeons/ddan/ddan_room_5.o" - number 03 + number 3 endseg beginseg name "ddan_room_6" romalign 0x1000 include "build/assets/scenes/dungeons/ddan/ddan_room_6.o" - number 03 + number 3 endseg beginseg name "ddan_room_7" romalign 0x1000 include "build/assets/scenes/dungeons/ddan/ddan_room_7.o" - number 03 + number 3 endseg beginseg name "ddan_room_8" romalign 0x1000 include "build/assets/scenes/dungeons/ddan/ddan_room_8.o" - number 03 + number 3 endseg beginseg name "ddan_room_9" romalign 0x1000 include "build/assets/scenes/dungeons/ddan/ddan_room_9.o" - number 03 + number 3 endseg beginseg name "ddan_room_10" romalign 0x1000 include "build/assets/scenes/dungeons/ddan/ddan_room_10.o" - number 03 + number 3 endseg beginseg name "ddan_room_11" romalign 0x1000 include "build/assets/scenes/dungeons/ddan/ddan_room_11.o" - number 03 + number 3 endseg beginseg name "ddan_room_12" romalign 0x1000 include "build/assets/scenes/dungeons/ddan/ddan_room_12.o" - number 03 + number 3 endseg beginseg name "ddan_room_13" romalign 0x1000 include "build/assets/scenes/dungeons/ddan/ddan_room_13.o" - number 03 + number 3 endseg beginseg name "ddan_room_14" romalign 0x1000 include "build/assets/scenes/dungeons/ddan/ddan_room_14.o" - number 03 + number 3 endseg beginseg name "ddan_room_15" romalign 0x1000 include "build/assets/scenes/dungeons/ddan/ddan_room_15.o" - number 03 + number 3 endseg beginseg name "ddan_room_16" romalign 0x1000 include "build/assets/scenes/dungeons/ddan/ddan_room_16.o" - number 03 + number 3 endseg beginseg name "bdan_scene" romalign 0x1000 include "build/assets/scenes/dungeons/bdan/bdan_scene.o" - number 02 + number 2 endseg beginseg name "bdan_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/bdan/bdan_room_0.o" - number 03 + number 3 endseg beginseg name "bdan_room_1" romalign 0x1000 include "build/assets/scenes/dungeons/bdan/bdan_room_1.o" - number 03 + number 3 endseg beginseg name "bdan_room_2" romalign 0x1000 include "build/assets/scenes/dungeons/bdan/bdan_room_2.o" - number 03 + number 3 endseg beginseg name "bdan_room_3" romalign 0x1000 include "build/assets/scenes/dungeons/bdan/bdan_room_3.o" - number 03 + number 3 endseg beginseg name "bdan_room_4" romalign 0x1000 include "build/assets/scenes/dungeons/bdan/bdan_room_4.o" - number 03 + number 3 endseg beginseg name "bdan_room_5" romalign 0x1000 include "build/assets/scenes/dungeons/bdan/bdan_room_5.o" - number 03 + number 3 endseg beginseg name "bdan_room_6" romalign 0x1000 include "build/assets/scenes/dungeons/bdan/bdan_room_6.o" - number 03 + number 3 endseg beginseg name "bdan_room_7" romalign 0x1000 include "build/assets/scenes/dungeons/bdan/bdan_room_7.o" - number 03 + number 3 endseg beginseg name "bdan_room_8" romalign 0x1000 include "build/assets/scenes/dungeons/bdan/bdan_room_8.o" - number 03 + number 3 endseg beginseg name "bdan_room_9" romalign 0x1000 include "build/assets/scenes/dungeons/bdan/bdan_room_9.o" - number 03 + number 3 endseg beginseg name "bdan_room_10" romalign 0x1000 include "build/assets/scenes/dungeons/bdan/bdan_room_10.o" - number 03 + number 3 endseg beginseg name "bdan_room_11" romalign 0x1000 include "build/assets/scenes/dungeons/bdan/bdan_room_11.o" - number 03 + number 3 endseg beginseg name "bdan_room_12" romalign 0x1000 include "build/assets/scenes/dungeons/bdan/bdan_room_12.o" - number 03 + number 3 endseg beginseg name "bdan_room_13" romalign 0x1000 include "build/assets/scenes/dungeons/bdan/bdan_room_13.o" - number 03 + number 3 endseg beginseg name "bdan_room_14" romalign 0x1000 include "build/assets/scenes/dungeons/bdan/bdan_room_14.o" - number 03 + number 3 endseg beginseg name "bdan_room_15" romalign 0x1000 include "build/assets/scenes/dungeons/bdan/bdan_room_15.o" - number 03 + number 3 endseg beginseg name "Bmori1_scene" romalign 0x1000 include "build/assets/scenes/dungeons/Bmori1/Bmori1_scene.o" - number 02 + number 2 endseg beginseg name "Bmori1_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/Bmori1/Bmori1_room_0.o" - number 03 + number 3 endseg beginseg name "Bmori1_room_1" romalign 0x1000 include "build/assets/scenes/dungeons/Bmori1/Bmori1_room_1.o" - number 03 + number 3 endseg beginseg name "Bmori1_room_2" romalign 0x1000 include "build/assets/scenes/dungeons/Bmori1/Bmori1_room_2.o" - number 03 + number 3 endseg beginseg name "Bmori1_room_3" romalign 0x1000 include "build/assets/scenes/dungeons/Bmori1/Bmori1_room_3.o" - number 03 + number 3 endseg beginseg name "Bmori1_room_4" romalign 0x1000 include "build/assets/scenes/dungeons/Bmori1/Bmori1_room_4.o" - number 03 + number 3 endseg beginseg name "Bmori1_room_5" romalign 0x1000 include "build/assets/scenes/dungeons/Bmori1/Bmori1_room_5.o" - number 03 + number 3 endseg beginseg name "Bmori1_room_6" romalign 0x1000 include "build/assets/scenes/dungeons/Bmori1/Bmori1_room_6.o" - number 03 + number 3 endseg beginseg name "Bmori1_room_7" romalign 0x1000 include "build/assets/scenes/dungeons/Bmori1/Bmori1_room_7.o" - number 03 + number 3 endseg beginseg name "Bmori1_room_8" romalign 0x1000 include "build/assets/scenes/dungeons/Bmori1/Bmori1_room_8.o" - number 03 + number 3 endseg beginseg name "Bmori1_room_9" romalign 0x1000 include "build/assets/scenes/dungeons/Bmori1/Bmori1_room_9.o" - number 03 + number 3 endseg beginseg name "Bmori1_room_10" romalign 0x1000 include "build/assets/scenes/dungeons/Bmori1/Bmori1_room_10.o" - number 03 + number 3 endseg beginseg name "Bmori1_room_11" romalign 0x1000 include "build/assets/scenes/dungeons/Bmori1/Bmori1_room_11.o" - number 03 + number 3 endseg beginseg name "Bmori1_room_12" romalign 0x1000 include "build/assets/scenes/dungeons/Bmori1/Bmori1_room_12.o" - number 03 + number 3 endseg beginseg name "Bmori1_room_13" romalign 0x1000 include "build/assets/scenes/dungeons/Bmori1/Bmori1_room_13.o" - number 03 + number 3 endseg beginseg name "Bmori1_room_14" romalign 0x1000 include "build/assets/scenes/dungeons/Bmori1/Bmori1_room_14.o" - number 03 + number 3 endseg beginseg name "Bmori1_room_15" romalign 0x1000 include "build/assets/scenes/dungeons/Bmori1/Bmori1_room_15.o" - number 03 + number 3 endseg beginseg name "Bmori1_room_16" romalign 0x1000 include "build/assets/scenes/dungeons/Bmori1/Bmori1_room_16.o" - number 03 + number 3 endseg beginseg name "Bmori1_room_17" romalign 0x1000 include "build/assets/scenes/dungeons/Bmori1/Bmori1_room_17.o" - number 03 + number 3 endseg beginseg name "Bmori1_room_18" romalign 0x1000 include "build/assets/scenes/dungeons/Bmori1/Bmori1_room_18.o" - number 03 + number 3 endseg beginseg name "Bmori1_room_19" romalign 0x1000 include "build/assets/scenes/dungeons/Bmori1/Bmori1_room_19.o" - number 03 + number 3 endseg beginseg name "Bmori1_room_20" romalign 0x1000 include "build/assets/scenes/dungeons/Bmori1/Bmori1_room_20.o" - number 03 + number 3 endseg beginseg name "Bmori1_room_21" romalign 0x1000 include "build/assets/scenes/dungeons/Bmori1/Bmori1_room_21.o" - number 03 + number 3 endseg beginseg name "Bmori1_room_22" romalign 0x1000 include "build/assets/scenes/dungeons/Bmori1/Bmori1_room_22.o" - number 03 + number 3 endseg beginseg name "HIDAN_scene" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_scene.o" - number 02 + number 2 endseg beginseg name "HIDAN_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_0.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_1" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_1.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_2" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_2.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_3" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_3.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_4" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_4.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_5" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_5.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_6" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_6.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_7" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_7.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_8" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_8.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_9" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_9.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_10" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_10.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_11" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_11.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_12" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_12.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_13" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_13.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_14" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_14.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_15" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_15.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_16" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_16.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_17" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_17.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_18" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_18.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_19" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_19.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_20" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_20.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_21" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_21.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_22" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_22.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_23" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_23.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_24" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_24.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_25" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_25.o" - number 03 + number 3 endseg beginseg name "HIDAN_room_26" romalign 0x1000 include "build/assets/scenes/dungeons/HIDAN/HIDAN_room_26.o" - number 03 + number 3 endseg beginseg name "MIZUsin_scene" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin/MIZUsin_scene.o" - number 02 + number 2 endseg beginseg name "MIZUsin_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin/MIZUsin_room_0.o" - number 03 + number 3 endseg beginseg name "MIZUsin_room_1" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin/MIZUsin_room_1.o" - number 03 + number 3 endseg beginseg name "MIZUsin_room_2" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin/MIZUsin_room_2.o" - number 03 + number 3 endseg beginseg name "MIZUsin_room_3" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin/MIZUsin_room_3.o" - number 03 + number 3 endseg beginseg name "MIZUsin_room_4" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin/MIZUsin_room_4.o" - number 03 + number 3 endseg beginseg name "MIZUsin_room_5" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin/MIZUsin_room_5.o" - number 03 + number 3 endseg beginseg name "MIZUsin_room_6" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin/MIZUsin_room_6.o" - number 03 + number 3 endseg beginseg name "MIZUsin_room_7" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin/MIZUsin_room_7.o" - number 03 + number 3 endseg beginseg name "MIZUsin_room_8" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin/MIZUsin_room_8.o" - number 03 + number 3 endseg beginseg name "MIZUsin_room_9" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin/MIZUsin_room_9.o" - number 03 + number 3 endseg beginseg name "MIZUsin_room_10" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin/MIZUsin_room_10.o" - number 03 + number 3 endseg beginseg name "MIZUsin_room_11" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin/MIZUsin_room_11.o" - number 03 + number 3 endseg beginseg name "MIZUsin_room_12" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin/MIZUsin_room_12.o" - number 03 + number 3 endseg beginseg name "MIZUsin_room_13" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin/MIZUsin_room_13.o" - number 03 + number 3 endseg beginseg name "MIZUsin_room_14" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin/MIZUsin_room_14.o" - number 03 + number 3 endseg beginseg name "MIZUsin_room_15" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin/MIZUsin_room_15.o" - number 03 + number 3 endseg beginseg name "MIZUsin_room_16" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin/MIZUsin_room_16.o" - number 03 + number 3 endseg beginseg name "MIZUsin_room_17" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin/MIZUsin_room_17.o" - number 03 + number 3 endseg beginseg name "MIZUsin_room_18" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin/MIZUsin_room_18.o" - number 03 + number 3 endseg beginseg name "MIZUsin_room_19" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin/MIZUsin_room_19.o" - number 03 + number 3 endseg beginseg name "MIZUsin_room_20" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin/MIZUsin_room_20.o" - number 03 + number 3 endseg beginseg name "MIZUsin_room_21" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin/MIZUsin_room_21.o" - number 03 + number 3 endseg beginseg name "MIZUsin_room_22" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin/MIZUsin_room_22.o" - number 03 + number 3 endseg beginseg name "jyasinzou_scene" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_scene.o" - number 02 + number 2 endseg beginseg name "jyasinzou_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_0.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_1" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_1.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_2" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_2.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_3" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_3.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_4" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_4.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_5" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_5.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_6" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_6.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_7" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_7.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_8" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_8.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_9" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_9.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_10" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_10.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_11" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_11.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_12" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_12.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_13" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_13.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_14" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_14.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_15" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_15.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_16" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_16.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_17" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_17.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_18" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_18.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_19" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_19.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_20" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_20.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_21" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_21.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_22" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_22.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_23" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_23.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_24" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_24.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_25" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_25.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_26" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_26.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_27" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_27.o" - number 03 + number 3 endseg beginseg name "jyasinzou_room_28" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinzou/jyasinzou_room_28.o" - number 03 + number 3 endseg beginseg name "HAKAdan_scene" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan/HAKAdan_scene.o" - number 02 + number 2 endseg beginseg name "HAKAdan_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan/HAKAdan_room_0.o" - number 03 + number 3 endseg beginseg name "HAKAdan_room_1" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan/HAKAdan_room_1.o" - number 03 + number 3 endseg beginseg name "HAKAdan_room_2" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan/HAKAdan_room_2.o" - number 03 + number 3 endseg beginseg name "HAKAdan_room_3" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan/HAKAdan_room_3.o" - number 03 + number 3 endseg beginseg name "HAKAdan_room_4" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan/HAKAdan_room_4.o" - number 03 + number 3 endseg beginseg name "HAKAdan_room_5" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan/HAKAdan_room_5.o" - number 03 + number 3 endseg beginseg name "HAKAdan_room_6" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan/HAKAdan_room_6.o" - number 03 + number 3 endseg beginseg name "HAKAdan_room_7" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan/HAKAdan_room_7.o" - number 03 + number 3 endseg beginseg name "HAKAdan_room_8" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan/HAKAdan_room_8.o" - number 03 + number 3 endseg beginseg name "HAKAdan_room_9" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan/HAKAdan_room_9.o" - number 03 + number 3 endseg beginseg name "HAKAdan_room_10" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan/HAKAdan_room_10.o" - number 03 + number 3 endseg beginseg name "HAKAdan_room_11" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan/HAKAdan_room_11.o" - number 03 + number 3 endseg beginseg name "HAKAdan_room_12" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan/HAKAdan_room_12.o" - number 03 + number 3 endseg beginseg name "HAKAdan_room_13" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan/HAKAdan_room_13.o" - number 03 + number 3 endseg beginseg name "HAKAdan_room_14" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan/HAKAdan_room_14.o" - number 03 + number 3 endseg beginseg name "HAKAdan_room_15" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan/HAKAdan_room_15.o" - number 03 + number 3 endseg beginseg name "HAKAdan_room_16" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan/HAKAdan_room_16.o" - number 03 + number 3 endseg beginseg name "HAKAdan_room_17" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan/HAKAdan_room_17.o" - number 03 + number 3 endseg beginseg name "HAKAdan_room_18" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan/HAKAdan_room_18.o" - number 03 + number 3 endseg beginseg name "HAKAdan_room_19" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan/HAKAdan_room_19.o" - number 03 + number 3 endseg beginseg name "HAKAdan_room_20" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan/HAKAdan_room_20.o" - number 03 + number 3 endseg beginseg name "HAKAdan_room_21" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan/HAKAdan_room_21.o" - number 03 + number 3 endseg beginseg name "HAKAdan_room_22" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan/HAKAdan_room_22.o" - number 03 + number 3 endseg beginseg name "HAKAdanCH_scene" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdanCH/HAKAdanCH_scene.o" - number 02 + number 2 endseg beginseg name "HAKAdanCH_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdanCH/HAKAdanCH_room_0.o" - number 03 + number 3 endseg beginseg name "HAKAdanCH_room_1" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdanCH/HAKAdanCH_room_1.o" - number 03 + number 3 endseg beginseg name "HAKAdanCH_room_2" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdanCH/HAKAdanCH_room_2.o" - number 03 + number 3 endseg beginseg name "HAKAdanCH_room_3" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdanCH/HAKAdanCH_room_3.o" - number 03 + number 3 endseg beginseg name "HAKAdanCH_room_4" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdanCH/HAKAdanCH_room_4.o" - number 03 + number 3 endseg beginseg name "HAKAdanCH_room_5" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdanCH/HAKAdanCH_room_5.o" - number 03 + number 3 endseg beginseg name "HAKAdanCH_room_6" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdanCH/HAKAdanCH_room_6.o" - number 03 + number 3 endseg beginseg name "ice_doukutu_scene" romalign 0x1000 include "build/assets/scenes/dungeons/ice_doukutu/ice_doukutu_scene.o" - number 02 + number 2 endseg beginseg name "ice_doukutu_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/ice_doukutu/ice_doukutu_room_0.o" - number 03 + number 3 endseg beginseg name "ice_doukutu_room_1" romalign 0x1000 include "build/assets/scenes/dungeons/ice_doukutu/ice_doukutu_room_1.o" - number 03 + number 3 endseg beginseg name "ice_doukutu_room_2" romalign 0x1000 include "build/assets/scenes/dungeons/ice_doukutu/ice_doukutu_room_2.o" - number 03 + number 3 endseg beginseg name "ice_doukutu_room_3" romalign 0x1000 include "build/assets/scenes/dungeons/ice_doukutu/ice_doukutu_room_3.o" - number 03 + number 3 endseg beginseg name "ice_doukutu_room_4" romalign 0x1000 include "build/assets/scenes/dungeons/ice_doukutu/ice_doukutu_room_4.o" - number 03 + number 3 endseg beginseg name "ice_doukutu_room_5" romalign 0x1000 include "build/assets/scenes/dungeons/ice_doukutu/ice_doukutu_room_5.o" - number 03 + number 3 endseg beginseg name "ice_doukutu_room_6" romalign 0x1000 include "build/assets/scenes/dungeons/ice_doukutu/ice_doukutu_room_6.o" - number 03 + number 3 endseg beginseg name "ice_doukutu_room_7" romalign 0x1000 include "build/assets/scenes/dungeons/ice_doukutu/ice_doukutu_room_7.o" - number 03 + number 3 endseg beginseg name "ice_doukutu_room_8" romalign 0x1000 include "build/assets/scenes/dungeons/ice_doukutu/ice_doukutu_room_8.o" - number 03 + number 3 endseg beginseg name "ice_doukutu_room_9" romalign 0x1000 include "build/assets/scenes/dungeons/ice_doukutu/ice_doukutu_room_9.o" - number 03 + number 3 endseg beginseg name "ice_doukutu_room_10" romalign 0x1000 include "build/assets/scenes/dungeons/ice_doukutu/ice_doukutu_room_10.o" - number 03 + number 3 endseg beginseg name "ice_doukutu_room_11" romalign 0x1000 include "build/assets/scenes/dungeons/ice_doukutu/ice_doukutu_room_11.o" - number 03 + number 3 endseg beginseg name "men_scene" romalign 0x1000 include "build/assets/scenes/dungeons/men/men_scene.o" - number 02 + number 2 endseg beginseg name "men_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/men/men_room_0.o" - number 03 + number 3 endseg beginseg name "men_room_1" romalign 0x1000 include "build/assets/scenes/dungeons/men/men_room_1.o" - number 03 + number 3 endseg beginseg name "men_room_2" romalign 0x1000 include "build/assets/scenes/dungeons/men/men_room_2.o" - number 03 + number 3 endseg beginseg name "men_room_3" romalign 0x1000 include "build/assets/scenes/dungeons/men/men_room_3.o" - number 03 + number 3 endseg beginseg name "men_room_4" romalign 0x1000 include "build/assets/scenes/dungeons/men/men_room_4.o" - number 03 + number 3 endseg beginseg name "men_room_5" romalign 0x1000 include "build/assets/scenes/dungeons/men/men_room_5.o" - number 03 + number 3 endseg beginseg name "men_room_6" romalign 0x1000 include "build/assets/scenes/dungeons/men/men_room_6.o" - number 03 + number 3 endseg beginseg name "men_room_7" romalign 0x1000 include "build/assets/scenes/dungeons/men/men_room_7.o" - number 03 + number 3 endseg beginseg name "men_room_8" romalign 0x1000 include "build/assets/scenes/dungeons/men/men_room_8.o" - number 03 + number 3 endseg beginseg name "men_room_9" romalign 0x1000 include "build/assets/scenes/dungeons/men/men_room_9.o" - number 03 + number 3 endseg beginseg name "men_room_10" romalign 0x1000 include "build/assets/scenes/dungeons/men/men_room_10.o" - number 03 + number 3 endseg beginseg name "ganontika_scene" romalign 0x1000 include "build/assets/scenes/dungeons/ganontika/ganontika_scene.o" - number 02 + number 2 endseg beginseg name "ganontika_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/ganontika/ganontika_room_0.o" - number 03 + number 3 endseg beginseg name "ganontika_room_1" romalign 0x1000 include "build/assets/scenes/dungeons/ganontika/ganontika_room_1.o" - number 03 + number 3 endseg beginseg name "ganontika_room_2" romalign 0x1000 include "build/assets/scenes/dungeons/ganontika/ganontika_room_2.o" - number 03 + number 3 endseg beginseg name "ganontika_room_3" romalign 0x1000 include "build/assets/scenes/dungeons/ganontika/ganontika_room_3.o" - number 03 + number 3 endseg beginseg name "ganontika_room_4" romalign 0x1000 include "build/assets/scenes/dungeons/ganontika/ganontika_room_4.o" - number 03 + number 3 endseg beginseg name "ganontika_room_5" romalign 0x1000 include "build/assets/scenes/dungeons/ganontika/ganontika_room_5.o" - number 03 + number 3 endseg beginseg name "ganontika_room_6" romalign 0x1000 include "build/assets/scenes/dungeons/ganontika/ganontika_room_6.o" - number 03 + number 3 endseg beginseg name "ganontika_room_7" romalign 0x1000 include "build/assets/scenes/dungeons/ganontika/ganontika_room_7.o" - number 03 + number 3 endseg beginseg name "ganontika_room_8" romalign 0x1000 include "build/assets/scenes/dungeons/ganontika/ganontika_room_8.o" - number 03 + number 3 endseg beginseg name "ganontika_room_9" romalign 0x1000 include "build/assets/scenes/dungeons/ganontika/ganontika_room_9.o" - number 03 + number 3 endseg beginseg name "ganontika_room_10" romalign 0x1000 include "build/assets/scenes/dungeons/ganontika/ganontika_room_10.o" - number 03 + number 3 endseg beginseg name "ganontika_room_11" romalign 0x1000 include "build/assets/scenes/dungeons/ganontika/ganontika_room_11.o" - number 03 + number 3 endseg beginseg name "ganontika_room_12" romalign 0x1000 include "build/assets/scenes/dungeons/ganontika/ganontika_room_12.o" - number 03 + number 3 endseg beginseg name "ganontika_room_13" romalign 0x1000 include "build/assets/scenes/dungeons/ganontika/ganontika_room_13.o" - number 03 + number 3 endseg beginseg name "ganontika_room_14" romalign 0x1000 include "build/assets/scenes/dungeons/ganontika/ganontika_room_14.o" - number 03 + number 3 endseg beginseg name "ganontika_room_15" romalign 0x1000 include "build/assets/scenes/dungeons/ganontika/ganontika_room_15.o" - number 03 + number 3 endseg beginseg name "ganontika_room_16" romalign 0x1000 include "build/assets/scenes/dungeons/ganontika/ganontika_room_16.o" - number 03 + number 3 endseg beginseg name "ganontika_room_17" romalign 0x1000 include "build/assets/scenes/dungeons/ganontika/ganontika_room_17.o" - number 03 + number 3 endseg beginseg name "ganontika_room_18" romalign 0x1000 include "build/assets/scenes/dungeons/ganontika/ganontika_room_18.o" - number 03 + number 3 endseg beginseg name "ganontika_room_19" romalign 0x1000 include "build/assets/scenes/dungeons/ganontika/ganontika_room_19.o" - number 03 + number 3 endseg beginseg name "syotes_scene" romalign 0x1000 include "build/assets/scenes/test_levels/syotes/syotes_scene.o" - number 02 + number 2 endseg beginseg name "syotes_room_0" romalign 0x1000 include "build/assets/scenes/test_levels/syotes/syotes_room_0.o" - number 03 + number 3 endseg beginseg name "syotes2_scene" romalign 0x1000 include "build/assets/scenes/test_levels/syotes2/syotes2_scene.o" - number 02 + number 2 endseg beginseg name "syotes2_room_0" romalign 0x1000 include "build/assets/scenes/test_levels/syotes2/syotes2_room_0.o" - number 03 + number 3 endseg beginseg name "depth_test_scene" romalign 0x1000 include "build/assets/scenes/test_levels/depth_test/depth_test_scene.o" - number 02 + number 2 endseg beginseg name "depth_test_room_0" romalign 0x1000 include "build/assets/scenes/test_levels/depth_test/depth_test_room_0.o" - number 03 + number 3 endseg beginseg name "spot00_scene" romalign 0x1000 include "build/assets/scenes/overworld/spot00/spot00_scene.o" - number 02 + number 2 endseg beginseg name "spot00_room_0" romalign 0x1000 include "build/assets/scenes/overworld/spot00/spot00_room_0.o" - number 03 + number 3 endseg beginseg name "spot01_scene" romalign 0x1000 include "build/assets/scenes/overworld/spot01/spot01_scene.o" - number 02 + number 2 endseg beginseg name "spot01_room_0" romalign 0x1000 include "build/assets/scenes/overworld/spot01/spot01_room_0.o" - number 03 + number 3 endseg beginseg name "spot02_scene" romalign 0x1000 include "build/assets/scenes/overworld/spot02/spot02_scene.o" - number 02 + number 2 endseg beginseg name "spot02_room_0" romalign 0x1000 include "build/assets/scenes/overworld/spot02/spot02_room_0.o" - number 03 + number 3 endseg beginseg name "spot02_room_1" romalign 0x1000 include "build/assets/scenes/overworld/spot02/spot02_room_1.o" - number 03 + number 3 endseg beginseg name "spot03_scene" romalign 0x1000 include "build/assets/scenes/overworld/spot03/spot03_scene.o" - number 02 + number 2 endseg beginseg name "spot03_room_0" romalign 0x1000 include "build/assets/scenes/overworld/spot03/spot03_room_0.o" - number 03 + number 3 endseg beginseg name "spot03_room_1" romalign 0x1000 include "build/assets/scenes/overworld/spot03/spot03_room_1.o" - number 03 + number 3 endseg beginseg name "spot04_scene" romalign 0x1000 include "build/assets/scenes/overworld/spot04/spot04_scene.o" - number 02 + number 2 endseg beginseg name "spot04_room_0" romalign 0x1000 include "build/assets/scenes/overworld/spot04/spot04_room_0.o" - number 03 + number 3 endseg beginseg name "spot04_room_1" romalign 0x1000 include "build/assets/scenes/overworld/spot04/spot04_room_1.o" - number 03 + number 3 endseg beginseg name "spot04_room_2" romalign 0x1000 include "build/assets/scenes/overworld/spot04/spot04_room_2.o" - number 03 + number 3 endseg beginseg name "spot05_scene" romalign 0x1000 include "build/assets/scenes/overworld/spot05/spot05_scene.o" - number 02 + number 2 endseg beginseg name "spot05_room_0" romalign 0x1000 include "build/assets/scenes/overworld/spot05/spot05_room_0.o" - number 03 + number 3 endseg beginseg name "spot06_scene" romalign 0x1000 include "build/assets/scenes/overworld/spot06/spot06_scene.o" - number 02 + number 2 endseg beginseg name "spot06_room_0" romalign 0x1000 include "build/assets/scenes/overworld/spot06/spot06_room_0.o" - number 03 + number 3 endseg beginseg name "spot07_scene" romalign 0x1000 include "build/assets/scenes/overworld/spot07/spot07_scene.o" - number 02 + number 2 endseg beginseg name "spot07_room_0" romalign 0x1000 include "build/assets/scenes/overworld/spot07/spot07_room_0.o" - number 03 + number 3 endseg beginseg name "spot07_room_1" romalign 0x1000 include "build/assets/scenes/overworld/spot07/spot07_room_1.o" - number 03 + number 3 endseg beginseg name "spot08_scene" romalign 0x1000 include "build/assets/scenes/overworld/spot08/spot08_scene.o" - number 02 + number 2 endseg beginseg name "spot08_room_0" romalign 0x1000 include "build/assets/scenes/overworld/spot08/spot08_room_0.o" - number 03 + number 3 endseg beginseg name "spot09_scene" romalign 0x1000 include "build/assets/scenes/overworld/spot09/spot09_scene.o" - number 02 + number 2 endseg beginseg name "spot09_room_0" romalign 0x1000 include "build/assets/scenes/overworld/spot09/spot09_room_0.o" - number 03 + number 3 endseg beginseg name "spot10_scene" romalign 0x1000 include "build/assets/scenes/overworld/spot10/spot10_scene.o" - number 02 + number 2 endseg beginseg name "spot10_room_0" romalign 0x1000 include "build/assets/scenes/overworld/spot10/spot10_room_0.o" - number 03 + number 3 endseg beginseg name "spot10_room_1" romalign 0x1000 include "build/assets/scenes/overworld/spot10/spot10_room_1.o" - number 03 + number 3 endseg beginseg name "spot10_room_2" romalign 0x1000 include "build/assets/scenes/overworld/spot10/spot10_room_2.o" - number 03 + number 3 endseg beginseg name "spot10_room_3" romalign 0x1000 include "build/assets/scenes/overworld/spot10/spot10_room_3.o" - number 03 + number 3 endseg beginseg name "spot10_room_4" romalign 0x1000 include "build/assets/scenes/overworld/spot10/spot10_room_4.o" - number 03 + number 3 endseg beginseg name "spot10_room_5" romalign 0x1000 include "build/assets/scenes/overworld/spot10/spot10_room_5.o" - number 03 + number 3 endseg beginseg name "spot10_room_6" romalign 0x1000 include "build/assets/scenes/overworld/spot10/spot10_room_6.o" - number 03 + number 3 endseg beginseg name "spot10_room_7" romalign 0x1000 include "build/assets/scenes/overworld/spot10/spot10_room_7.o" - number 03 + number 3 endseg beginseg name "spot10_room_8" romalign 0x1000 include "build/assets/scenes/overworld/spot10/spot10_room_8.o" - number 03 + number 3 endseg beginseg name "spot10_room_9" romalign 0x1000 include "build/assets/scenes/overworld/spot10/spot10_room_9.o" - number 03 + number 3 endseg beginseg name "spot11_scene" romalign 0x1000 include "build/assets/scenes/overworld/spot11/spot11_scene.o" - number 02 + number 2 endseg beginseg name "spot11_room_0" romalign 0x1000 include "build/assets/scenes/overworld/spot11/spot11_room_0.o" - number 03 + number 3 endseg beginseg name "spot12_scene" romalign 0x1000 include "build/assets/scenes/overworld/spot12/spot12_scene.o" - number 02 + number 2 endseg beginseg name "spot12_room_0" romalign 0x1000 include "build/assets/scenes/overworld/spot12/spot12_room_0.o" - number 03 + number 3 endseg beginseg name "spot12_room_1" romalign 0x1000 include "build/assets/scenes/overworld/spot12/spot12_room_1.o" - number 03 + number 3 endseg beginseg name "spot13_scene" romalign 0x1000 include "build/assets/scenes/overworld/spot13/spot13_scene.o" - number 02 + number 2 endseg beginseg name "spot13_room_0" romalign 0x1000 include "build/assets/scenes/overworld/spot13/spot13_room_0.o" - number 03 + number 3 endseg beginseg name "spot13_room_1" romalign 0x1000 include "build/assets/scenes/overworld/spot13/spot13_room_1.o" - number 03 + number 3 endseg beginseg name "spot15_scene" romalign 0x1000 include "build/assets/scenes/overworld/spot15/spot15_scene.o" - number 02 + number 2 endseg beginseg name "spot15_room_0" romalign 0x1000 include "build/assets/scenes/overworld/spot15/spot15_room_0.o" - number 03 + number 3 endseg beginseg name "spot16_scene" romalign 0x1000 include "build/assets/scenes/overworld/spot16/spot16_scene.o" - number 02 + number 2 endseg beginseg name "spot16_room_0" romalign 0x1000 include "build/assets/scenes/overworld/spot16/spot16_room_0.o" - number 03 + number 3 endseg beginseg name "spot17_scene" romalign 0x1000 include "build/assets/scenes/overworld/spot17/spot17_scene.o" - number 02 + number 2 endseg beginseg name "spot17_room_0" romalign 0x1000 include "build/assets/scenes/overworld/spot17/spot17_room_0.o" - number 03 + number 3 endseg beginseg name "spot17_room_1" romalign 0x1000 include "build/assets/scenes/overworld/spot17/spot17_room_1.o" - number 03 + number 3 endseg beginseg name "spot18_scene" romalign 0x1000 include "build/assets/scenes/overworld/spot18/spot18_scene.o" - number 02 + number 2 endseg beginseg name "spot18_room_0" romalign 0x1000 include "build/assets/scenes/overworld/spot18/spot18_room_0.o" - number 03 + number 3 endseg beginseg name "spot18_room_1" romalign 0x1000 include "build/assets/scenes/overworld/spot18/spot18_room_1.o" - number 03 + number 3 endseg beginseg name "spot18_room_2" romalign 0x1000 include "build/assets/scenes/overworld/spot18/spot18_room_2.o" - number 03 + number 3 endseg beginseg name "spot18_room_3" romalign 0x1000 include "build/assets/scenes/overworld/spot18/spot18_room_3.o" - number 03 + number 3 endseg beginseg name "market_day_scene" romalign 0x1000 include "build/assets/scenes/misc/market_day/market_day_scene.o" - number 02 + number 2 endseg beginseg name "market_day_room_0" romalign 0x1000 include "build/assets/scenes/misc/market_day/market_day_room_0.o" - number 03 + number 3 endseg beginseg name "market_night_scene" romalign 0x1000 include "build/assets/scenes/misc/market_night/market_night_scene.o" - number 02 + number 2 endseg beginseg name "market_night_room_0" romalign 0x1000 include "build/assets/scenes/misc/market_night/market_night_room_0.o" - number 03 + number 3 endseg beginseg name "testroom_scene" romalign 0x1000 include "build/assets/scenes/test_levels/testroom/testroom_scene.o" - number 02 + number 2 endseg beginseg name "testroom_room_0" romalign 0x1000 include "build/assets/scenes/test_levels/testroom/testroom_room_0.o" - number 03 + number 3 endseg beginseg name "testroom_room_1" romalign 0x1000 include "build/assets/scenes/test_levels/testroom/testroom_room_1.o" - number 03 + number 3 endseg beginseg name "testroom_room_2" romalign 0x1000 include "build/assets/scenes/test_levels/testroom/testroom_room_2.o" - number 03 + number 3 endseg beginseg name "testroom_room_3" romalign 0x1000 include "build/assets/scenes/test_levels/testroom/testroom_room_3.o" - number 03 + number 3 endseg beginseg name "testroom_room_4" romalign 0x1000 include "build/assets/scenes/test_levels/testroom/testroom_room_4.o" - number 03 + number 3 endseg beginseg name "kenjyanoma_scene" romalign 0x1000 include "build/assets/scenes/indoors/kenjyanoma/kenjyanoma_scene.o" - number 02 + number 2 endseg beginseg name "kenjyanoma_room_0" romalign 0x1000 include "build/assets/scenes/indoors/kenjyanoma/kenjyanoma_room_0.o" - number 03 + number 3 endseg beginseg name "tokinoma_scene" romalign 0x1000 include "build/assets/scenes/indoors/tokinoma/tokinoma_scene.o" - number 02 + number 2 endseg beginseg name "tokinoma_room_0" romalign 0x1000 include "build/assets/scenes/indoors/tokinoma/tokinoma_room_0.o" - number 03 + number 3 endseg beginseg name "tokinoma_room_1" romalign 0x1000 include "build/assets/scenes/indoors/tokinoma/tokinoma_room_1.o" - number 03 + number 3 endseg beginseg name "sutaru_scene" romalign 0x1000 include "build/assets/scenes/test_levels/sutaru/sutaru_scene.o" - number 02 + number 2 endseg beginseg name "sutaru_room_0" romalign 0x1000 include "build/assets/scenes/test_levels/sutaru/sutaru_room_0.o" - number 03 + number 3 endseg beginseg name "link_home_scene" romalign 0x1000 include "build/assets/scenes/indoors/link_home/link_home_scene.o" - number 02 + number 2 endseg beginseg name "link_home_room_0" romalign 0x1000 include "build/assets/scenes/indoors/link_home/link_home_room_0.o" - number 03 + number 3 endseg beginseg name "kokiri_shop_scene" romalign 0x1000 include "build/assets/scenes/shops/kokiri_shop/kokiri_shop_scene.o" - number 02 + number 2 endseg beginseg name "kokiri_shop_room_0" romalign 0x1000 include "build/assets/scenes/shops/kokiri_shop/kokiri_shop_room_0.o" - number 03 + number 3 endseg beginseg name "kokiri_home_scene" romalign 0x1000 include "build/assets/scenes/indoors/kokiri_home/kokiri_home_scene.o" - number 02 + number 2 endseg beginseg name "kokiri_home_room_0" romalign 0x1000 include "build/assets/scenes/indoors/kokiri_home/kokiri_home_room_0.o" - number 03 + number 3 endseg beginseg name "kakusiana_scene" romalign 0x1000 include "build/assets/scenes/misc/kakusiana/kakusiana_scene.o" - number 02 + number 2 endseg beginseg name "kakusiana_room_0" romalign 0x1000 include "build/assets/scenes/misc/kakusiana/kakusiana_room_0.o" - number 03 + number 3 endseg beginseg name "kakusiana_room_1" romalign 0x1000 include "build/assets/scenes/misc/kakusiana/kakusiana_room_1.o" - number 03 + number 3 endseg beginseg name "kakusiana_room_2" romalign 0x1000 include "build/assets/scenes/misc/kakusiana/kakusiana_room_2.o" - number 03 + number 3 endseg beginseg name "kakusiana_room_3" romalign 0x1000 include "build/assets/scenes/misc/kakusiana/kakusiana_room_3.o" - number 03 + number 3 endseg beginseg name "kakusiana_room_4" romalign 0x1000 include "build/assets/scenes/misc/kakusiana/kakusiana_room_4.o" - number 03 + number 3 endseg beginseg name "kakusiana_room_5" romalign 0x1000 include "build/assets/scenes/misc/kakusiana/kakusiana_room_5.o" - number 03 + number 3 endseg beginseg name "kakusiana_room_6" romalign 0x1000 include "build/assets/scenes/misc/kakusiana/kakusiana_room_6.o" - number 03 + number 3 endseg beginseg name "kakusiana_room_7" romalign 0x1000 include "build/assets/scenes/misc/kakusiana/kakusiana_room_7.o" - number 03 + number 3 endseg beginseg name "kakusiana_room_8" romalign 0x1000 include "build/assets/scenes/misc/kakusiana/kakusiana_room_8.o" - number 03 + number 3 endseg beginseg name "kakusiana_room_9" romalign 0x1000 include "build/assets/scenes/misc/kakusiana/kakusiana_room_9.o" - number 03 + number 3 endseg beginseg name "kakusiana_room_10" romalign 0x1000 include "build/assets/scenes/misc/kakusiana/kakusiana_room_10.o" - number 03 + number 3 endseg beginseg name "kakusiana_room_11" romalign 0x1000 include "build/assets/scenes/misc/kakusiana/kakusiana_room_11.o" - number 03 + number 3 endseg beginseg name "kakusiana_room_12" romalign 0x1000 include "build/assets/scenes/misc/kakusiana/kakusiana_room_12.o" - number 03 + number 3 endseg beginseg name "kakusiana_room_13" romalign 0x1000 include "build/assets/scenes/misc/kakusiana/kakusiana_room_13.o" - number 03 + number 3 endseg beginseg name "entra_scene" romalign 0x1000 include "build/assets/scenes/overworld/entra/entra_scene.o" - number 02 + number 2 endseg beginseg name "entra_room_0" romalign 0x1000 include "build/assets/scenes/overworld/entra/entra_room_0.o" - number 03 + number 3 endseg beginseg name "moribossroom_scene" romalign 0x1000 include "build/assets/scenes/dungeons/moribossroom/moribossroom_scene.o" - number 02 + number 2 endseg beginseg name "moribossroom_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/moribossroom/moribossroom_room_0.o" - number 03 + number 3 endseg beginseg name "moribossroom_room_1" romalign 0x1000 include "build/assets/scenes/dungeons/moribossroom/moribossroom_room_1.o" - number 03 + number 3 endseg beginseg name "syatekijyou_scene" romalign 0x1000 include "build/assets/scenes/indoors/syatekijyou/syatekijyou_scene.o" - number 02 + number 2 endseg beginseg name "syatekijyou_room_0" romalign 0x1000 include "build/assets/scenes/indoors/syatekijyou/syatekijyou_room_0.o" - number 03 + number 3 endseg beginseg name "shop1_scene" romalign 0x1000 include "build/assets/scenes/shops/shop1/shop1_scene.o" - number 02 + number 2 endseg beginseg name "shop1_room_0" romalign 0x1000 include "build/assets/scenes/shops/shop1/shop1_room_0.o" - number 03 + number 3 endseg beginseg name "hairal_niwa_scene" romalign 0x1000 include "build/assets/scenes/indoors/hairal_niwa/hairal_niwa_scene.o" - number 02 + number 2 endseg beginseg name "hairal_niwa_room_0" romalign 0x1000 include "build/assets/scenes/indoors/hairal_niwa/hairal_niwa_room_0.o" - number 03 + number 3 endseg beginseg name "ganon_tou_scene" romalign 0x1000 include "build/assets/scenes/dungeons/ganon_tou/ganon_tou_scene.o" - number 02 + number 2 endseg beginseg name "ganon_tou_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/ganon_tou/ganon_tou_room_0.o" - number 03 + number 3 endseg beginseg name "sasatest_scene" romalign 0x1000 include "build/assets/scenes/test_levels/sasatest/sasatest_scene.o" - number 02 + number 2 endseg beginseg name "sasatest_room_0" romalign 0x1000 include "build/assets/scenes/test_levels/sasatest/sasatest_room_0.o" - number 03 + number 3 endseg beginseg name "market_alley_scene" romalign 0x1000 include "build/assets/scenes/misc/market_alley/market_alley_scene.o" - number 02 + number 2 endseg beginseg name "market_alley_room_0" romalign 0x1000 include "build/assets/scenes/misc/market_alley/market_alley_room_0.o" - number 03 + number 3 endseg beginseg name "spot20_scene" romalign 0x1000 include "build/assets/scenes/overworld/spot20/spot20_scene.o" - number 02 + number 2 endseg beginseg name "spot20_room_0" romalign 0x1000 include "build/assets/scenes/overworld/spot20/spot20_room_0.o" - number 03 + number 3 endseg beginseg name "market_ruins_scene" romalign 0x1000 include "build/assets/scenes/misc/market_ruins/market_ruins_scene.o" - number 02 + number 2 endseg beginseg name "market_ruins_room_0" romalign 0x1000 include "build/assets/scenes/misc/market_ruins/market_ruins_room_0.o" - number 03 + number 3 endseg beginseg name "entra_n_scene" romalign 0x1000 include "build/assets/scenes/misc/entra_n/entra_n_scene.o" - number 02 + number 2 endseg beginseg name "entra_n_room_0" romalign 0x1000 include "build/assets/scenes/misc/entra_n/entra_n_room_0.o" - number 03 + number 3 endseg beginseg name "enrui_scene" romalign 0x1000 include "build/assets/scenes/misc/enrui/enrui_scene.o" - number 02 + number 2 endseg beginseg name "enrui_room_0" romalign 0x1000 include "build/assets/scenes/misc/enrui/enrui_room_0.o" - number 03 + number 3 endseg beginseg name "market_alley_n_scene" romalign 0x1000 include "build/assets/scenes/misc/market_alley_n/market_alley_n_scene.o" - number 02 + number 2 endseg beginseg name "market_alley_n_room_0" romalign 0x1000 include "build/assets/scenes/misc/market_alley_n/market_alley_n_room_0.o" - number 03 + number 3 endseg beginseg name "hiral_demo_scene" romalign 0x1000 include "build/assets/scenes/misc/hiral_demo/hiral_demo_scene.o" - number 02 + number 2 endseg beginseg name "hiral_demo_room_0" romalign 0x1000 include "build/assets/scenes/misc/hiral_demo/hiral_demo_room_0.o" - number 03 + number 3 endseg beginseg name "kokiri_home3_scene" romalign 0x1000 include "build/assets/scenes/indoors/kokiri_home3/kokiri_home3_scene.o" - number 02 + number 2 endseg beginseg name "kokiri_home3_room_0" romalign 0x1000 include "build/assets/scenes/indoors/kokiri_home3/kokiri_home3_room_0.o" - number 03 + number 3 endseg beginseg name "malon_stable_scene" romalign 0x1000 include "build/assets/scenes/indoors/malon_stable/malon_stable_scene.o" - number 02 + number 2 endseg beginseg name "malon_stable_room_0" romalign 0x1000 include "build/assets/scenes/indoors/malon_stable/malon_stable_room_0.o" - number 03 + number 3 endseg beginseg name "kakariko_scene" romalign 0x1000 include "build/assets/scenes/indoors/kakariko/kakariko_scene.o" - number 02 + number 2 endseg beginseg name "kakariko_room_0" romalign 0x1000 include "build/assets/scenes/indoors/kakariko/kakariko_room_0.o" - number 03 + number 3 endseg beginseg name "bdan_boss_scene" romalign 0x1000 include "build/assets/scenes/dungeons/bdan_boss/bdan_boss_scene.o" - number 02 + number 2 endseg beginseg name "bdan_boss_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/bdan_boss/bdan_boss_room_0.o" - number 03 + number 3 endseg beginseg name "bdan_boss_room_1" romalign 0x1000 include "build/assets/scenes/dungeons/bdan_boss/bdan_boss_room_1.o" - number 03 + number 3 endseg beginseg name "FIRE_bs_scene" romalign 0x1000 include "build/assets/scenes/dungeons/FIRE_bs/FIRE_bs_scene.o" - number 02 + number 2 endseg beginseg name "FIRE_bs_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/FIRE_bs/FIRE_bs_room_0.o" - number 03 + number 3 endseg beginseg name "FIRE_bs_room_1" romalign 0x1000 include "build/assets/scenes/dungeons/FIRE_bs/FIRE_bs_room_1.o" - number 03 + number 3 endseg beginseg name "hut_scene" romalign 0x1000 include "build/assets/scenes/indoors/hut/hut_scene.o" - number 02 + number 2 endseg beginseg name "hut_room_0" romalign 0x1000 include "build/assets/scenes/indoors/hut/hut_room_0.o" - number 03 + number 3 endseg beginseg name "daiyousei_izumi_scene" romalign 0x1000 include "build/assets/scenes/indoors/daiyousei_izumi/daiyousei_izumi_scene.o" - number 02 + number 2 endseg beginseg name "daiyousei_izumi_room_0" romalign 0x1000 include "build/assets/scenes/indoors/daiyousei_izumi/daiyousei_izumi_room_0.o" - number 03 + number 3 endseg beginseg name "hakaana_scene" romalign 0x1000 include "build/assets/scenes/misc/hakaana/hakaana_scene.o" - number 02 + number 2 endseg beginseg name "hakaana_room_0" romalign 0x1000 include "build/assets/scenes/misc/hakaana/hakaana_room_0.o" - number 03 + number 3 endseg beginseg name "yousei_izumi_tate_scene" romalign 0x1000 include "build/assets/scenes/indoors/yousei_izumi_tate/yousei_izumi_tate_scene.o" - number 02 + number 2 endseg beginseg name "yousei_izumi_tate_room_0" romalign 0x1000 include "build/assets/scenes/indoors/yousei_izumi_tate/yousei_izumi_tate_room_0.o" - number 03 + number 3 endseg beginseg name "yousei_izumi_yoko_scene" romalign 0x1000 include "build/assets/scenes/indoors/yousei_izumi_yoko/yousei_izumi_yoko_scene.o" - number 02 + number 2 endseg beginseg name "yousei_izumi_yoko_room_0" romalign 0x1000 include "build/assets/scenes/indoors/yousei_izumi_yoko/yousei_izumi_yoko_room_0.o" - number 03 + number 3 endseg beginseg name "golon_scene" romalign 0x1000 include "build/assets/scenes/shops/golon/golon_scene.o" - number 02 + number 2 endseg beginseg name "golon_room_0" romalign 0x1000 include "build/assets/scenes/shops/golon/golon_room_0.o" - number 03 + number 3 endseg beginseg name "zoora_scene" romalign 0x1000 include "build/assets/scenes/shops/zoora/zoora_scene.o" - number 02 + number 2 endseg beginseg name "zoora_room_0" romalign 0x1000 include "build/assets/scenes/shops/zoora/zoora_room_0.o" - number 03 + number 3 endseg beginseg name "drag_scene" romalign 0x1000 include "build/assets/scenes/shops/drag/drag_scene.o" - number 02 + number 2 endseg beginseg name "drag_room_0" romalign 0x1000 include "build/assets/scenes/shops/drag/drag_room_0.o" - number 03 + number 3 endseg beginseg name "alley_shop_scene" romalign 0x1000 include "build/assets/scenes/shops/alley_shop/alley_shop_scene.o" - number 02 + number 2 endseg beginseg name "alley_shop_room_0" romalign 0x1000 include "build/assets/scenes/shops/alley_shop/alley_shop_room_0.o" - number 03 + number 3 endseg beginseg name "night_shop_scene" romalign 0x1000 include "build/assets/scenes/shops/night_shop/night_shop_scene.o" - number 02 + number 2 endseg beginseg name "night_shop_room_0" romalign 0x1000 include "build/assets/scenes/shops/night_shop/night_shop_room_0.o" - number 03 + number 3 endseg beginseg name "impa_scene" romalign 0x1000 include "build/assets/scenes/indoors/impa/impa_scene.o" - number 02 + number 2 endseg beginseg name "impa_room_0" romalign 0x1000 include "build/assets/scenes/indoors/impa/impa_room_0.o" - number 03 + number 3 endseg beginseg name "labo_scene" romalign 0x1000 include "build/assets/scenes/indoors/labo/labo_scene.o" - number 02 + number 2 endseg beginseg name "labo_room_0" romalign 0x1000 include "build/assets/scenes/indoors/labo/labo_room_0.o" - number 03 + number 3 endseg beginseg name "tent_scene" romalign 0x1000 include "build/assets/scenes/indoors/tent/tent_scene.o" - number 02 + number 2 endseg beginseg name "tent_room_0" romalign 0x1000 include "build/assets/scenes/indoors/tent/tent_room_0.o" - number 03 + number 3 endseg beginseg name "nakaniwa_scene" romalign 0x1000 include "build/assets/scenes/indoors/nakaniwa/nakaniwa_scene.o" - number 02 + number 2 endseg beginseg name "nakaniwa_room_0" romalign 0x1000 include "build/assets/scenes/indoors/nakaniwa/nakaniwa_room_0.o" - number 03 + number 3 endseg beginseg name "ddan_boss_scene" romalign 0x1000 include "build/assets/scenes/dungeons/ddan_boss/ddan_boss_scene.o" - number 02 + number 2 endseg beginseg name "ddan_boss_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/ddan_boss/ddan_boss_room_0.o" - number 03 + number 3 endseg beginseg name "ddan_boss_room_1" romalign 0x1000 include "build/assets/scenes/dungeons/ddan_boss/ddan_boss_room_1.o" - number 03 + number 3 endseg beginseg name "ydan_boss_scene" romalign 0x1000 include "build/assets/scenes/dungeons/ydan_boss/ydan_boss_scene.o" - number 02 + number 2 endseg beginseg name "ydan_boss_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/ydan_boss/ydan_boss_room_0.o" - number 03 + number 3 endseg beginseg name "ydan_boss_room_1" romalign 0x1000 include "build/assets/scenes/dungeons/ydan_boss/ydan_boss_room_1.o" - number 03 + number 3 endseg beginseg name "HAKAdan_bs_scene" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan_bs/HAKAdan_bs_scene.o" - number 02 + number 2 endseg beginseg name "HAKAdan_bs_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan_bs/HAKAdan_bs_room_0.o" - number 03 + number 3 endseg beginseg name "HAKAdan_bs_room_1" romalign 0x1000 include "build/assets/scenes/dungeons/HAKAdan_bs/HAKAdan_bs_room_1.o" - number 03 + number 3 endseg beginseg name "MIZUsin_bs_scene" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin_bs/MIZUsin_bs_scene.o" - number 02 + number 2 endseg beginseg name "MIZUsin_bs_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin_bs/MIZUsin_bs_room_0.o" - number 03 + number 3 endseg beginseg name "MIZUsin_bs_room_1" romalign 0x1000 include "build/assets/scenes/dungeons/MIZUsin_bs/MIZUsin_bs_room_1.o" - number 03 + number 3 endseg beginseg name "ganon_scene" romalign 0x1000 include "build/assets/scenes/dungeons/ganon/ganon_scene.o" - number 02 + number 2 endseg beginseg name "ganon_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/ganon/ganon_room_0.o" - number 03 + number 3 endseg beginseg name "ganon_room_1" romalign 0x1000 include "build/assets/scenes/dungeons/ganon/ganon_room_1.o" - number 03 + number 3 endseg beginseg name "ganon_room_2" romalign 0x1000 include "build/assets/scenes/dungeons/ganon/ganon_room_2.o" - number 03 + number 3 endseg beginseg name "ganon_room_3" romalign 0x1000 include "build/assets/scenes/dungeons/ganon/ganon_room_3.o" - number 03 + number 3 endseg beginseg name "ganon_room_4" romalign 0x1000 include "build/assets/scenes/dungeons/ganon/ganon_room_4.o" - number 03 + number 3 endseg beginseg name "ganon_room_5" romalign 0x1000 include "build/assets/scenes/dungeons/ganon/ganon_room_5.o" - number 03 + number 3 endseg beginseg name "ganon_room_6" romalign 0x1000 include "build/assets/scenes/dungeons/ganon/ganon_room_6.o" - number 03 + number 3 endseg beginseg name "ganon_room_7" romalign 0x1000 include "build/assets/scenes/dungeons/ganon/ganon_room_7.o" - number 03 + number 3 endseg beginseg name "ganon_room_8" romalign 0x1000 include "build/assets/scenes/dungeons/ganon/ganon_room_8.o" - number 03 + number 3 endseg beginseg name "ganon_room_9" romalign 0x1000 include "build/assets/scenes/dungeons/ganon/ganon_room_9.o" - number 03 + number 3 endseg beginseg name "ganon_boss_scene" romalign 0x1000 include "build/assets/scenes/dungeons/ganon_boss/ganon_boss_scene.o" - number 02 + number 2 endseg beginseg name "ganon_boss_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/ganon_boss/ganon_boss_room_0.o" - number 03 + number 3 endseg beginseg name "jyasinboss_scene" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinboss/jyasinboss_scene.o" - number 02 + number 2 endseg beginseg name "jyasinboss_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinboss/jyasinboss_room_0.o" - number 03 + number 3 endseg beginseg name "jyasinboss_room_1" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinboss/jyasinboss_room_1.o" - number 03 + number 3 endseg beginseg name "jyasinboss_room_2" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinboss/jyasinboss_room_2.o" - number 03 + number 3 endseg beginseg name "jyasinboss_room_3" romalign 0x1000 include "build/assets/scenes/dungeons/jyasinboss/jyasinboss_room_3.o" - number 03 + number 3 endseg beginseg name "kokiri_home4_scene" romalign 0x1000 include "build/assets/scenes/indoors/kokiri_home4/kokiri_home4_scene.o" - number 02 + number 2 endseg beginseg name "kokiri_home4_room_0" romalign 0x1000 include "build/assets/scenes/indoors/kokiri_home4/kokiri_home4_room_0.o" - number 03 + number 3 endseg beginseg name "kokiri_home5_scene" romalign 0x1000 include "build/assets/scenes/indoors/kokiri_home5/kokiri_home5_scene.o" - number 02 + number 2 endseg beginseg name "kokiri_home5_room_0" romalign 0x1000 include "build/assets/scenes/indoors/kokiri_home5/kokiri_home5_room_0.o" - number 03 + number 3 endseg beginseg name "ganon_final_scene" romalign 0x1000 include "build/assets/scenes/dungeons/ganon_final/ganon_final_scene.o" - number 02 + number 2 endseg beginseg name "ganon_final_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/ganon_final/ganon_final_room_0.o" - number 03 + number 3 endseg beginseg name "kakariko3_scene" romalign 0x1000 include "build/assets/scenes/misc/kakariko3/kakariko3_scene.o" - number 02 + number 2 endseg beginseg name "kakariko3_room_0" romalign 0x1000 include "build/assets/scenes/misc/kakariko3/kakariko3_room_0.o" - number 03 + number 3 endseg beginseg name "hairal_niwa2_scene" romalign 0x1000 include "build/assets/scenes/indoors/hairal_niwa2/hairal_niwa2_scene.o" - number 02 + number 2 endseg beginseg name "hairal_niwa2_room_0" romalign 0x1000 include "build/assets/scenes/indoors/hairal_niwa2/hairal_niwa2_room_0.o" - number 03 + number 3 endseg beginseg name "hakasitarelay_scene" romalign 0x1000 include "build/assets/scenes/indoors/hakasitarelay/hakasitarelay_scene.o" - number 02 + number 2 endseg beginseg name "hakasitarelay_room_0" romalign 0x1000 include "build/assets/scenes/indoors/hakasitarelay/hakasitarelay_room_0.o" - number 03 + number 3 endseg beginseg name "hakasitarelay_room_1" romalign 0x1000 include "build/assets/scenes/indoors/hakasitarelay/hakasitarelay_room_1.o" - number 03 + number 3 endseg beginseg name "hakasitarelay_room_2" romalign 0x1000 include "build/assets/scenes/indoors/hakasitarelay/hakasitarelay_room_2.o" - number 03 + number 3 endseg beginseg name "hakasitarelay_room_3" romalign 0x1000 include "build/assets/scenes/indoors/hakasitarelay/hakasitarelay_room_3.o" - number 03 + number 3 endseg beginseg name "hakasitarelay_room_4" romalign 0x1000 include "build/assets/scenes/indoors/hakasitarelay/hakasitarelay_room_4.o" - number 03 + number 3 endseg beginseg name "hakasitarelay_room_5" romalign 0x1000 include "build/assets/scenes/indoors/hakasitarelay/hakasitarelay_room_5.o" - number 03 + number 3 endseg beginseg name "hakasitarelay_room_6" romalign 0x1000 include "build/assets/scenes/indoors/hakasitarelay/hakasitarelay_room_6.o" - number 03 + number 3 endseg beginseg name "shrine_scene" romalign 0x1000 include "build/assets/scenes/misc/shrine/shrine_scene.o" - number 02 + number 2 endseg beginseg name "shrine_room_0" romalign 0x1000 include "build/assets/scenes/misc/shrine/shrine_room_0.o" - number 03 + number 3 endseg beginseg name "turibori_scene" romalign 0x1000 include "build/assets/scenes/misc/turibori/turibori_scene.o" - number 02 + number 2 endseg beginseg name "turibori_room_0" romalign 0x1000 include "build/assets/scenes/misc/turibori/turibori_room_0.o" - number 03 + number 3 endseg beginseg name "shrine_n_scene" romalign 0x1000 include "build/assets/scenes/misc/shrine_n/shrine_n_scene.o" - number 02 + number 2 endseg beginseg name "shrine_n_room_0" romalign 0x1000 include "build/assets/scenes/misc/shrine_n/shrine_n_room_0.o" - number 03 + number 3 endseg beginseg name "shrine_r_scene" romalign 0x1000 include "build/assets/scenes/misc/shrine_r/shrine_r_scene.o" - number 02 + number 2 endseg beginseg name "shrine_r_room_0" romalign 0x1000 include "build/assets/scenes/misc/shrine_r/shrine_r_room_0.o" - number 03 + number 3 endseg beginseg name "hakaana2_scene" romalign 0x1000 include "build/assets/scenes/misc/hakaana2/hakaana2_scene.o" - number 02 + number 2 endseg beginseg name "hakaana2_room_0" romalign 0x1000 include "build/assets/scenes/misc/hakaana2/hakaana2_room_0.o" - number 03 + number 3 endseg beginseg name "gerudoway_scene" romalign 0x1000 include "build/assets/scenes/dungeons/gerudoway/gerudoway_scene.o" - number 02 + number 2 endseg beginseg name "gerudoway_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/gerudoway/gerudoway_room_0.o" - number 03 + number 3 endseg beginseg name "gerudoway_room_1" romalign 0x1000 include "build/assets/scenes/dungeons/gerudoway/gerudoway_room_1.o" - number 03 + number 3 endseg beginseg name "gerudoway_room_2" romalign 0x1000 include "build/assets/scenes/dungeons/gerudoway/gerudoway_room_2.o" - number 03 + number 3 endseg beginseg name "gerudoway_room_3" romalign 0x1000 include "build/assets/scenes/dungeons/gerudoway/gerudoway_room_3.o" - number 03 + number 3 endseg beginseg name "gerudoway_room_4" romalign 0x1000 include "build/assets/scenes/dungeons/gerudoway/gerudoway_room_4.o" - number 03 + number 3 endseg beginseg name "gerudoway_room_5" romalign 0x1000 include "build/assets/scenes/dungeons/gerudoway/gerudoway_room_5.o" - number 03 + number 3 endseg beginseg name "hairal_niwa_n_scene" romalign 0x1000 include "build/assets/scenes/indoors/hairal_niwa_n/hairal_niwa_n_scene.o" - number 02 + number 2 endseg beginseg name "hairal_niwa_n_room_0" romalign 0x1000 include "build/assets/scenes/indoors/hairal_niwa_n/hairal_niwa_n_room_0.o" - number 03 + number 3 endseg beginseg name "bowling_scene" romalign 0x1000 include "build/assets/scenes/indoors/bowling/bowling_scene.o" - number 02 + number 2 endseg beginseg name "bowling_room_0" romalign 0x1000 include "build/assets/scenes/indoors/bowling/bowling_room_0.o" - number 03 + number 3 endseg beginseg name "hakaana_ouke_scene" romalign 0x1000 include "build/assets/scenes/misc/hakaana_ouke/hakaana_ouke_scene.o" - number 02 + number 2 endseg beginseg name "hakaana_ouke_room_0" romalign 0x1000 include "build/assets/scenes/misc/hakaana_ouke/hakaana_ouke_room_0.o" - number 03 + number 3 endseg beginseg name "hakaana_ouke_room_1" romalign 0x1000 include "build/assets/scenes/misc/hakaana_ouke/hakaana_ouke_room_1.o" - number 03 + number 3 endseg beginseg name "hakaana_ouke_room_2" romalign 0x1000 include "build/assets/scenes/misc/hakaana_ouke/hakaana_ouke_room_2.o" - number 03 + number 3 endseg beginseg name "hylia_labo_scene" romalign 0x1000 include "build/assets/scenes/indoors/hylia_labo/hylia_labo_scene.o" - number 02 + number 2 endseg beginseg name "hylia_labo_room_0" romalign 0x1000 include "build/assets/scenes/indoors/hylia_labo/hylia_labo_room_0.o" - number 03 + number 3 endseg beginseg name "souko_scene" romalign 0x1000 include "build/assets/scenes/overworld/souko/souko_scene.o" - number 02 + number 2 endseg beginseg name "souko_room_0" romalign 0x1000 include "build/assets/scenes/overworld/souko/souko_room_0.o" - number 03 + number 3 endseg beginseg name "souko_room_1" romalign 0x1000 include "build/assets/scenes/overworld/souko/souko_room_1.o" - number 03 + number 3 endseg beginseg name "souko_room_2" romalign 0x1000 include "build/assets/scenes/overworld/souko/souko_room_2.o" - number 03 + number 3 endseg beginseg name "miharigoya_scene" romalign 0x1000 include "build/assets/scenes/indoors/miharigoya/miharigoya_scene.o" - number 02 + number 2 endseg beginseg name "miharigoya_room_0" romalign 0x1000 include "build/assets/scenes/indoors/miharigoya/miharigoya_room_0.o" - number 03 + number 3 endseg beginseg name "mahouya_scene" romalign 0x1000 include "build/assets/scenes/indoors/mahouya/mahouya_scene.o" - number 02 + number 2 endseg beginseg name "mahouya_room_0" romalign 0x1000 include "build/assets/scenes/indoors/mahouya/mahouya_room_0.o" - number 03 + number 3 endseg beginseg name "takaraya_scene" romalign 0x1000 include "build/assets/scenes/indoors/takaraya/takaraya_scene.o" - number 02 + number 2 endseg beginseg name "takaraya_room_0" romalign 0x1000 include "build/assets/scenes/indoors/takaraya/takaraya_room_0.o" - number 03 + number 3 endseg beginseg name "takaraya_room_1" romalign 0x1000 include "build/assets/scenes/indoors/takaraya/takaraya_room_1.o" - number 03 + number 3 endseg beginseg name "takaraya_room_2" romalign 0x1000 include "build/assets/scenes/indoors/takaraya/takaraya_room_2.o" - number 03 + number 3 endseg beginseg name "takaraya_room_3" romalign 0x1000 include "build/assets/scenes/indoors/takaraya/takaraya_room_3.o" - number 03 + number 3 endseg beginseg name "takaraya_room_4" romalign 0x1000 include "build/assets/scenes/indoors/takaraya/takaraya_room_4.o" - number 03 + number 3 endseg beginseg name "takaraya_room_5" romalign 0x1000 include "build/assets/scenes/indoors/takaraya/takaraya_room_5.o" - number 03 + number 3 endseg beginseg name "takaraya_room_6" romalign 0x1000 include "build/assets/scenes/indoors/takaraya/takaraya_room_6.o" - number 03 + number 3 endseg beginseg name "ganon_sonogo_scene" romalign 0x1000 include "build/assets/scenes/dungeons/ganon_sonogo/ganon_sonogo_scene.o" - number 02 + number 2 endseg beginseg name "ganon_sonogo_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/ganon_sonogo/ganon_sonogo_room_0.o" - number 03 + number 3 endseg beginseg name "ganon_sonogo_room_1" romalign 0x1000 include "build/assets/scenes/dungeons/ganon_sonogo/ganon_sonogo_room_1.o" - number 03 + number 3 endseg beginseg name "ganon_sonogo_room_2" romalign 0x1000 include "build/assets/scenes/dungeons/ganon_sonogo/ganon_sonogo_room_2.o" - number 03 + number 3 endseg beginseg name "ganon_sonogo_room_3" romalign 0x1000 include "build/assets/scenes/dungeons/ganon_sonogo/ganon_sonogo_room_3.o" - number 03 + number 3 endseg beginseg name "ganon_sonogo_room_4" romalign 0x1000 include "build/assets/scenes/dungeons/ganon_sonogo/ganon_sonogo_room_4.o" - number 03 + number 3 endseg beginseg name "ganon_demo_scene" romalign 0x1000 include "build/assets/scenes/dungeons/ganon_demo/ganon_demo_scene.o" - number 02 + number 2 endseg beginseg name "ganon_demo_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/ganon_demo/ganon_demo_room_0.o" - number 03 + number 3 endseg beginseg name "besitu_scene" romalign 0x1000 include "build/assets/scenes/test_levels/besitu/besitu_scene.o" - number 02 + number 2 endseg beginseg name "besitu_room_0" romalign 0x1000 include "build/assets/scenes/test_levels/besitu/besitu_room_0.o" - number 03 + number 3 endseg beginseg name "face_shop_scene" romalign 0x1000 include "build/assets/scenes/shops/face_shop/face_shop_scene.o" - number 02 + number 2 endseg beginseg name "face_shop_room_0" romalign 0x1000 include "build/assets/scenes/shops/face_shop/face_shop_room_0.o" - number 03 + number 3 endseg beginseg name "kinsuta_scene" romalign 0x1000 include "build/assets/scenes/misc/kinsuta/kinsuta_scene.o" - number 02 + number 2 endseg beginseg name "kinsuta_room_0" romalign 0x1000 include "build/assets/scenes/misc/kinsuta/kinsuta_room_0.o" - number 03 + number 3 endseg beginseg name "ganontikasonogo_scene" romalign 0x1000 include "build/assets/scenes/dungeons/ganontikasonogo/ganontikasonogo_scene.o" - number 02 + number 2 endseg beginseg name "ganontikasonogo_room_0" romalign 0x1000 include "build/assets/scenes/dungeons/ganontikasonogo/ganontikasonogo_room_0.o" - number 03 + number 3 endseg beginseg name "ganontikasonogo_room_1" romalign 0x1000 include "build/assets/scenes/dungeons/ganontikasonogo/ganontikasonogo_room_1.o" - number 03 + number 3 endseg beginseg name "test01_scene" romalign 0x1000 include "build/assets/scenes/test_levels/test01/test01_scene.o" - number 02 + number 2 endseg beginseg name "test01_room_0" romalign 0x1000 include "build/assets/scenes/test_levels/test01/test01_room_0.o" - number 03 + number 3 endseg beginseg diff --git a/tools/Makefile b/tools/Makefile index f8147317c2..6289929501 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,14 +1,14 @@ CC := gcc CFLAGS := -Wall -Wextra -pedantic -std=c99 -g -O2 PROGRAMS := yaz0 makeromfs elf2rom mkldscript vtxdis -ZAP2 := ZAP2/ZAP2.out +ZAPD := ZAPD/ZAPD.out all: $(PROGRAMS) - cd ZAP2 && $(MAKE) + cd ZAPD && $(MAKE) clean: $(RM) $(PROGRAMS) - $(RM) ZAP2/ZAP2.out + $(RM) ZAPD/ZAPD.out # Need to clean the above line later... mkldscript_SOURCES := mkldscript.c util.c @@ -17,8 +17,8 @@ yaz0_SOURCES := yaz0tool.c yaz0.c util.c makeromfs_SOURCES := makeromfs.c n64chksum.c util.c vtxdis_SOURCES := vtxdis.c -#$(ZAP2): -# cd ZAP2 && $(MAKE) +#$(ZAPD): +# cd ZAPD && $(MAKE) define COMPILE = $(1): $($1_SOURCES) diff --git a/tools/ZAP2 b/tools/ZAP2 deleted file mode 160000 index 73dcb0371a..0000000000 --- a/tools/ZAP2 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 73dcb0371a4d47acdc5151119f8af9596a803587 diff --git a/tools/ZAPD/.gitignore b/tools/ZAPD/.gitignore new file mode 100644 index 0000000000..749e6a89b5 --- /dev/null +++ b/tools/ZAPD/.gitignore @@ -0,0 +1,335 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ +**/Properties/launchSettings.json + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +*.out +*.o +*.d +.vscode/ diff --git a/tools/ZAPD/.gitrepo b/tools/ZAPD/.gitrepo new file mode 100644 index 0000000000..aba7c73a4b --- /dev/null +++ b/tools/ZAPD/.gitrepo @@ -0,0 +1,12 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://github.com/zeldaret/ZAPD.git + branch = master + commit = cd4a8760b64474a2603c2d164ab7fb7bcd88385c + parent = 9b82d8ffae16a4b6c5a7ff86019eae84ce4638fc + method = merge + cmdver = 0.4.3 diff --git a/tools/ZAPD/LICENSE b/tools/ZAPD/LICENSE new file mode 100644 index 0000000000..90b734bde8 --- /dev/null +++ b/tools/ZAPD/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Zelda Reverse Engineering Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/tools/ZAPD/Makefile b/tools/ZAPD/Makefile new file mode 100644 index 0000000000..123fa26031 --- /dev/null +++ b/tools/ZAPD/Makefile @@ -0,0 +1,25 @@ +CC := g++ + +ifneq (, $(shell which ccache)) +CC := ccache $(CC) +endif + +CFLAGS := -g -std=c++17 -I ZAPD -I ZAPD/sqlite -O2 -rdynamic + +SRC_DIRS := ZAPD ZAPD/ZRoom ZAPD/ZRoom/Commands ZAPD/Overlays ZAPD/HighLevel ZAPD/OpenFBX + +CPP_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.cpp)) +O_FILES := $(CPP_FILES:.cpp=.o) + +all: ZAPD.out + +clean: + rm -f $(O_FILES) ZAPD.out + +rebuild: clean all + +%.o: %.cpp + $(CC) $(CFLAGS) -c $< -o $@ + +ZAPD.out: $(O_FILES) + $(CC) $(CFLAGS) $(O_FILES) -o $@ -lstdc++fs diff --git a/tools/ZAPD/SymbolMap_OoTMqDbg.txt b/tools/ZAPD/SymbolMap_OoTMqDbg.txt new file mode 100644 index 0000000000..015e7e88a3 --- /dev/null +++ b/tools/ZAPD/SymbolMap_OoTMqDbg.txt @@ -0,0 +1 @@ +8012DB20 gMtxClear \ No newline at end of file diff --git a/tools/ZAPD/ZAPD.sln b/tools/ZAPD/ZAPD.sln new file mode 100644 index 0000000000..4280808b49 --- /dev/null +++ b/tools/ZAPD/ZAPD.sln @@ -0,0 +1,46 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30320.27 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZAPD", "ZAPD\ZAPD.vcxproj", "{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + MinSizeRel|x64 = MinSizeRel|x64 + MinSizeRel|x86 = MinSizeRel|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + RelWithDebInfo|x64 = RelWithDebInfo|x64 + RelWithDebInfo|x86 = RelWithDebInfo|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Debug|x64.ActiveCfg = Debug|x64 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Debug|x64.Build.0 = Debug|x64 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Debug|x86.ActiveCfg = Debug|Win32 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Debug|x86.Build.0 = Debug|Win32 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.MinSizeRel|x64.ActiveCfg = Release|x64 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.MinSizeRel|x64.Build.0 = Release|x64 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.MinSizeRel|x86.ActiveCfg = Release|Win32 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.MinSizeRel|x86.Build.0 = Release|Win32 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Release|x64.ActiveCfg = Release|x64 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Release|x64.Build.0 = Release|x64 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Release|x86.ActiveCfg = Release|Win32 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Release|x86.Build.0 = Release|Win32 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.RelWithDebInfo|x64.ActiveCfg = Release|x64 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.RelWithDebInfo|x64.Build.0 = Release|x64 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.RelWithDebInfo|x86.ActiveCfg = Release|Win32 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.RelWithDebInfo|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2E1CC72-7A50-3249-AFD5-DFF6FE25CDCA} + EndGlobalSection + GlobalSection(Performance) = preSolution + HasPerformanceSessions = true + EndGlobalSection +EndGlobal diff --git a/tools/ZAPD/ZAPD/BitConverter.h b/tools/ZAPD/ZAPD/BitConverter.h new file mode 100644 index 0000000000..2625296ff0 --- /dev/null +++ b/tools/ZAPD/ZAPD/BitConverter.h @@ -0,0 +1,43 @@ +#pragma once + +#include +#include + +class BitConverter +{ +public: + static inline int16_t ToInt16BE(uint8_t* data, int offset) + { + return (data[offset + 0] << 8) + data[offset + 1]; + } + + static inline int16_t ToInt16BE(std::vector data, int offset) + { + return (data[offset + 0] << 8) + data[offset + 1]; + } + + static inline int32_t ToInt32BE(std::uint8_t* data, int offset) + { + return (data[offset + 0] << 24) + (data[offset + 1] << 16) + (data[offset + 2] << 8) + data[offset + 3]; + } + + static inline int32_t ToInt32BE(std::vector data, int offset) + { + return (data[offset + 0] << 24) + (data[offset + 1] << 16) + (data[offset + 2] << 8) + data[offset + 3]; + } + + static inline uint64_t ToInt64BE(uint8_t* data, int offset) + { + return ((uint64_t)data[offset + 0] << 56) + ((uint64_t)data[offset + 1] << 48) + ((uint64_t)data[offset + 2] << 40) + ((uint64_t)data[offset + 3] << 32) + ((uint64_t)data[offset + 4] << 24) + ((uint64_t)data[offset + 5] << 16) + ((uint64_t)data[offset + 6] << 8) + ((uint64_t)data[offset + 7]); + } + + static inline uint64_t ToInt64BE(std::vector data, int offset) + { + return ((uint64_t)data[offset + 0] << 56) + ((uint64_t)data[offset + 1] << 48) + ((uint64_t)data[offset + 2] << 40) + ((uint64_t)data[offset + 3] << 32) + ((uint64_t)data[offset + 4] << 24) + ((uint64_t)data[offset + 5] << 16) + ((uint64_t)data[offset + 6] << 8) + ((uint64_t)data[offset + 7]); + } + + static inline float ToFloatBE(std::vector data, int offset) + { + return (float)(data[offset + 0] << 24) + (data[offset + 1] << 16) + (data[offset + 2] << 8) + data[offset + 3]; + } +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/Directory.h b/tools/ZAPD/ZAPD/Directory.h new file mode 100644 index 0000000000..ea2ec72f65 --- /dev/null +++ b/tools/ZAPD/ZAPD/Directory.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include + +#if defined(_MSC_VER) || defined(__clang__) +#include +namespace fs = std::filesystem; +#else +#include +namespace fs = std::experimental::filesystem; +#endif + +class Directory +{ +public: + static std::string GetCurrentDirectory() + { + return fs::current_path().u8string(); + } + + static bool Exists(std::string path) + { + return fs::exists(fs::path(path)); + } + + static void CreateDirectory(std::string path) + { + fs::create_directory(path); + } +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/File.h b/tools/ZAPD/ZAPD/File.h new file mode 100644 index 0000000000..e16ee8ce6b --- /dev/null +++ b/tools/ZAPD/ZAPD/File.h @@ -0,0 +1,60 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include "StringHelper.h" + +class File +{ +public: + static bool Exists(std::string filePath) + { + std::ifstream file(filePath, std::ios::in | std::ios::binary | std::ios::ate); + return file.good(); + } + + static std::vector ReadAllBytes(std::string filePath) + { + std::ifstream file(filePath, std::ios::in | std::ios::binary | std::ios::ate); + int fileSize = (int)file.tellg(); + file.seekg(0); + char* data = new char[fileSize]; + file.read(data, fileSize); + return std::vector(data, data + fileSize); + }; + + static std::string ReadAllText(std::string filePath) + { + std::ifstream file(filePath, std::ios::in | std::ios::binary | std::ios::ate); + int fileSize = (int)file.tellg(); + file.seekg(0); + char* data = new char[fileSize+1]; + memset(data, 0, fileSize + 1); + file.read(data, fileSize); + return std::string((const char*)data); + }; + + static std::vector ReadAllLines(std::string filePath) + { + std::string text = ReadAllText(filePath); + std::vector lines = StringHelper::Split(text, "\n"); + + return lines; + }; + + static void WriteAllBytes(std::string filePath, std::vector data) + { + std::ofstream file(filePath, std::ios::binary); + file.write((char*)data.data(), data.size()); + }; + + static void WriteAllText(std::string filePath, std::string text) + { + std::ofstream file(filePath, std::ios::out); + file.write(text.c_str(), text.size()); + } +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/Globals.cpp b/tools/ZAPD/ZAPD/Globals.cpp new file mode 100644 index 0000000000..02f540b2b0 --- /dev/null +++ b/tools/ZAPD/ZAPD/Globals.cpp @@ -0,0 +1,119 @@ +#include "Globals.h" +#include "File.h" +#include "tinyxml2.h" +#include + +using namespace tinyxml2; +using namespace std; + +Globals* Globals::Instance; + +Globals::Globals() +{ + Instance = this; + + files = std::vector(); + segments = std::vector(); + symbolMap = std::map (); + segmentRefs = map(); + segmentRefFiles = map(); + genSourceFile = true; + testMode = false; + debugMessages = false; + profile = false; + includeFilePrefix = false; + useExternalResources = true; + lastScene = nullptr; +} + +string Globals::FindSymbolSegRef(int segNumber, uint32_t symbolAddress) +{ + if (segmentRefs.find(segNumber) != segmentRefs.end()) + { + if (segmentRefFiles.find(segNumber) == segmentRefFiles.end()) + { + XMLDocument doc; + string filePath = segmentRefs[segNumber]; + XMLError eResult = doc.LoadFile(filePath.c_str()); + + if (eResult != tinyxml2::XML_SUCCESS) + return "ERROR"; + + XMLNode* root = doc.FirstChild(); + + if (root == nullptr) + return "ERROR"; + + //vector files = vector(); + + for (XMLElement* child = root->FirstChildElement(); child != NULL; child = child->NextSiblingElement()) + { + if (string(child->Name()) == "File") + { + ZFile* file = new ZFile(fileMode, child, "", "", true); + file->GeneratePlaceholderDeclarations(); + segmentRefFiles[segNumber] = file; + break; + } + } + } + + return segmentRefFiles[segNumber]->GetDeclarationName(symbolAddress, "ERROR"); + } + + return "ERROR"; +} + +void Globals::ReadConfigFile(string configFilePath) +{ + XMLDocument doc; + XMLError eResult = doc.LoadFile(configFilePath.c_str()); + + if (eResult != tinyxml2::XML_SUCCESS) + return; + + XMLNode* root = doc.FirstChild(); + + if (root == nullptr) + return; + + for (XMLElement* child = root->FirstChildElement(); child != NULL; child = child->NextSiblingElement()) + { + if (string(child->Name()) == "SymbolMap") + { + string fileName = string(child->Attribute("File")); + GenSymbolMap(fileName); + } + else if (string(child->Name()) == "Segment") + { + string fileName = string(child->Attribute("File")); + int segNumber = child->IntAttribute("Number"); + segmentRefs[segNumber] = fileName; + } + } +} + +void Globals::GenSymbolMap(string symbolMapPath) +{ + auto symbolLines = File::ReadAllLines(symbolMapPath); + + for (std::string symbolLine : symbolLines) + { + auto split = StringHelper::Split(symbolLine, " "); + uint32_t addr = strtoul(split[0].c_str(), NULL, 16); + std::string symbolName = split[1]; + + symbolMap[addr] = symbolName; + } +} + +void Globals::AddSegment(int segment) +{ + if (std::find(segments.begin(), segments.end(), segment) == segments.end()) + segments.push_back(segment); +} + +bool Globals::HasSegment(int segment) +{ + return std::find(segments.begin(), segments.end(), segment) != segments.end(); +} diff --git a/tools/ZAPD/ZAPD/Globals.h b/tools/ZAPD/ZAPD/Globals.h new file mode 100644 index 0000000000..e5615eab51 --- /dev/null +++ b/tools/ZAPD/ZAPD/Globals.h @@ -0,0 +1,52 @@ +#pragma once + +#include +#include +#include "ZFile.h" +#include "ZTexture.h" +#include "ZRoom/ZRoom.h" + +class Globals +{ +public: + static Globals* Instance; + + bool genSourceFile; // Used for extraction + bool useExternalResources; + bool testMode; // Enables certain experimental features + bool debugMessages; // Enables certain printfs + bool profile; // Measure performance of certain operations + bool includeFilePrefix; // Include the file prefix in symbols + ZFileMode fileMode; + std::string baseRomPath, inputPath, outputPath, cfgPath; + TextureType texType; + + std::vector files; + std::vector segments; + std::map segmentRefs; + std::map segmentRefFiles; + ZRoom* lastScene; + std::map symbolMap; + + Globals(); + std::string FindSymbolSegRef(int segNumber, uint32_t symbolAddress); + void ReadConfigFile(std::string configFilePath); + void GenSymbolMap(std::string symbolMapPath); + void AddSegment(int segment); + bool HasSegment(int segment); +}; + +/* + * Note: In being able to track references across files, there are a few major files that make use of segments... + * Segment 1: nintendo_rogo_static/title_static + * Segment 2: parameter_static + * Segment 4: gameplay_keep + * Segment 5: gameplay_field_keep, gameplay_dangeon_keep + * Segment 7: link_animetion + * Segment 8: icon_item_static + * Segment 9: icon_item_24_static + * Segment 12: icon_item_field_static, icon_item_dungeon_static + * Segment 13: icon_item_nes_static + * + * I'm thinking a config file could be usable, but I'll have to experiment... + */ \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/HighLevel/HLAnimation.h b/tools/ZAPD/ZAPD/HighLevel/HLAnimation.h new file mode 100644 index 0000000000..dfc4532462 --- /dev/null +++ b/tools/ZAPD/ZAPD/HighLevel/HLAnimation.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +/* + * The high level format for animations. + */ + +class HLAnimation +{ +public: + +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/HighLevel/HLAnimationIntermediette.cpp b/tools/ZAPD/ZAPD/HighLevel/HLAnimationIntermediette.cpp new file mode 100644 index 0000000000..1b64af1357 --- /dev/null +++ b/tools/ZAPD/ZAPD/HighLevel/HLAnimationIntermediette.cpp @@ -0,0 +1,125 @@ +#include "HLAnimationIntermediette.h" + +using namespace std; +using namespace tinyxml2; + +HLAnimationIntermediette::HLAnimationIntermediette() +{ + limit = 0; + limbCount = 0; + frameCount = 0; + rotationValues = vector(); + rotationIndices = vector(); +} + +HLAnimationIntermediette::~HLAnimationIntermediette() +{ + +} + +HLAnimationIntermediette* HLAnimationIntermediette::FromXML(std::string xmlPath) +{ + HLAnimationIntermediette* anim = new HLAnimationIntermediette(); + XMLDocument doc; + + doc.LoadFile(xmlPath.c_str()); + + XMLElement* root = doc.RootElement(); + + anim->limit = root->IntAttribute("Limit"); + anim->limbCount = root->IntAttribute("LimbCount"); + anim->frameCount = root->IntAttribute("FrameCount"); + + for (XMLElement* child = root->FirstChildElement(); child != NULL; child = child->NextSiblingElement()) + { + if (string(child->Name()) == "RotationValues") + { + for (XMLElement* child2 = child->FirstChildElement(); child2 != NULL; child2 = child2->NextSiblingElement()) + { + string value = child2->GetText(); + anim->rotationValues.push_back(atoi(value.c_str())); + } + } + else if (string(child->Name()) == "RotationIndices") + { + for (XMLElement* child2 = child->FirstChildElement(); child2 != NULL; child2 = child2->NextSiblingElement()) + anim->rotationIndices.push_back(RotationIndex(child2->IntAttribute("X"), child2->IntAttribute("Y"), child2->IntAttribute("Z"))); + } + } + + return anim; +} + +HLAnimationIntermediette* HLAnimationIntermediette::FromZAnimation(ZAnimation* zAnim) +{ + HLAnimationIntermediette* anim = new HLAnimationIntermediette(); + + /*anim->limit = zAnim->limit; + anim->frameCount = zAnim->frameCount; + + for (uint16_t item : zAnim->rotationValues) + anim->rotationValues.push_back(item); + + for (RotationIndex item : zAnim->rotationIndices) + anim->rotationIndices.push_back(item);*/ + + return anim; +} + +ZAnimation* HLAnimationIntermediette::ToZAnimation() +{ + ZAnimation* zAnim = new ZAnimation(); + + /*zAnim->limit = limit; + zAnim->frameCount = frameCount; + + for (uint16_t item : rotationValues) + zAnim->rotationValues.push_back(item); + + for (RotationIndex item : rotationIndices) + zAnim->rotationIndices.push_back(item);*/ + + return zAnim; +} + +string HLAnimationIntermediette::OutputXML() +{ + string output = ""; + XMLDocument doc; + + XMLElement* root = doc.NewElement("HLAnimationIntermediette"); + root->SetAttribute("Limit", limit); + root->SetAttribute("LimbCount", limbCount); + root->SetAttribute("FrameCount", frameCount); + + doc.InsertFirstChild(root); + + XMLElement* rotValues = doc.NewElement("RotationValues"); + + for (int i = 0; i < rotationValues.size(); i++) + { + XMLElement* rotValue = doc.NewElement("Value"); + rotValue->SetText(rotationValues[i]); + rotValues->InsertEndChild(rotValue); + } + + root->InsertEndChild(rotValues); + + XMLElement* rotIndices = doc.NewElement("RotationIndices"); + + for (int i = 0; i < rotationIndices.size(); i++) + { + XMLElement* rotIndex = doc.NewElement("Value"); + rotIndex->SetAttribute("X", rotationIndices[i].x); + rotIndex->SetAttribute("Y", rotationIndices[i].y); + rotIndex->SetAttribute("Z", rotationIndices[i].z); + rotIndices->InsertEndChild(rotIndex); + } + + root->InsertEndChild(rotIndices); + + XMLPrinter printer; + + doc.Accept(&printer); + return printer.CStr(); +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/HighLevel/HLAnimationIntermediette.h b/tools/ZAPD/ZAPD/HighLevel/HLAnimationIntermediette.h new file mode 100644 index 0000000000..6f97105ae7 --- /dev/null +++ b/tools/ZAPD/ZAPD/HighLevel/HLAnimationIntermediette.h @@ -0,0 +1,32 @@ +#pragma once + +#include +#include "../ZAnimation.h" +#include "../tinyxml2.h" +#include "HLFileIntermediette.h" + +/* + * An intermediette format for animations. Going to use XML. + * Goes from FBX->XML->C + * Note: At the moment this is a very direct representation of the output format. + * Optimally we can determine where the keyframes are and remove redundant information. + */ + +class HLAnimationIntermediette +{ +public: + int16_t frameCount; + int16_t limit; + int16_t limbCount; + std::vector rotationValues; + std::vector rotationIndices; + + HLAnimationIntermediette(); + ~HLAnimationIntermediette(); + + std::string OutputXML(); + ZAnimation* ToZAnimation(); + + static HLAnimationIntermediette* FromXML(std::string xmlPath); + static HLAnimationIntermediette* FromZAnimation(ZAnimation* zAnim); +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/HighLevel/HLFileIntermediette.h b/tools/ZAPD/ZAPD/HighLevel/HLFileIntermediette.h new file mode 100644 index 0000000000..bd18f1e146 --- /dev/null +++ b/tools/ZAPD/ZAPD/HighLevel/HLFileIntermediette.h @@ -0,0 +1,6 @@ +#pragma once + +class HLFileIntermediette +{ + +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/HighLevel/HLModelIntermediette.cpp b/tools/ZAPD/ZAPD/HighLevel/HLModelIntermediette.cpp new file mode 100644 index 0000000000..ee8461093e --- /dev/null +++ b/tools/ZAPD/ZAPD/HighLevel/HLModelIntermediette.cpp @@ -0,0 +1,1152 @@ +#include "HLModelIntermediette.h" +#include "../ZDisplayList.h" +#include "../StringHelper.h" +#include "../Globals.h" +#include "../Path.h" +#include "../File.h" + +#ifdef USE_ASSIMP +#include "../assimp/Importer.hpp" +#include "../assimp/Exporter.hpp" +#include "../assimp/scene.h" +#include "../assimp/postprocess.h" +#endif + +using namespace std; +using namespace tinyxml2; + +HLModelIntermediette::HLModelIntermediette() +{ + blocks = vector(); + startIndex = 0; + meshStartIndex = 0; + hasSkeleton = false; +} + +HLModelIntermediette::~HLModelIntermediette() +{ +} + +HLModelIntermediette* HLModelIntermediette::FromXML(tinyxml2::XMLElement* root) +{ + HLModelIntermediette* model = new HLModelIntermediette(); + + for (XMLElement* child = root->FirstChildElement(); child != NULL; child = child->NextSiblingElement()) + { + string childName = child->Name(); + HLIntermediette* block = nullptr; + + if (childName == "Mesh") + block = new HLMeshIntermediette(); + else if (childName == "Limb") + block = new HLLimbIntermediette(); + else if (childName == "Vertices") + block = new HLVerticesIntermediette(); + else if (childName == "Texture") + block = new HLTextureIntermediette(); + else if (childName == "Material") + block = new HLMaterialIntermediette(); + + if (block != nullptr) + { + block->parent = model; + block->InitFromXML(child); + model->blocks.push_back(block); + } + } + + return model; +} + +void HLModelIntermediette::FromZDisplayList(HLModelIntermediette* model, ZDisplayList* zDisplayList) +{ + //HLModelIntermediette* model = new HLModelIntermediette(); + HLLimbIntermediette* limb = new HLLimbIntermediette(); + limb->name = zDisplayList->GetName(); + + // Go through verts + vector finalVerts = vector(); + + uint32_t vStart = -1; + + for (pair> pair : zDisplayList->vertices) + { + if (vStart == -1) // TODO: Find a better way to do this + vStart = pair.first; + + for (Vertex v : pair.second) + finalVerts.push_back(v); + } + + HLVerticesIntermediette* vertIntr = new HLVerticesIntermediette(); + vertIntr->vertices = finalVerts; + vertIntr->name = StringHelper::Sprintf("%s_verts", zDisplayList->GetName().c_str()); + model->blocks.push_back(vertIntr); + + // Go through textures + for (pair pair : zDisplayList->textures) + { + HLTextureIntermediette* texIntr = new HLTextureIntermediette(); + texIntr->tex = pair.second; + texIntr->name = texIntr->tex->GetName(); + + model->blocks.push_back(texIntr); + } + + // Analyze display lists to determine components + HLDisplayListIntermediette* dList = new HLDisplayListIntermediette(); + dList->address = zDisplayList->GetRawDataIndex(); + int startIndex = 0; + + // Go through the display lists and setup commands + int meshCnt = 0; + + HLMeshIntermediette* mesh = new HLMeshIntermediette(); + mesh->name = StringHelper::Sprintf("%s_%i", zDisplayList->GetName().c_str(), meshCnt); + + int matCnt = 0; + HLMaterialIntermediette* lastMat = new HLMaterialIntermediette(); + lastMat->name = StringHelper::Sprintf("Material_%i", matCnt); + + uint8_t lastClrR = 0, lastClrG = 0, lastClrB = 0, lastClrA = 0, lastClrM = 0, lastClrL = 0; + + startIndex = 0; + + for (int i = startIndex; i < zDisplayList->instructions.size(); i++) + { + uint64_t data = zDisplayList->instructions[i]; + F3DZEXOpcode opcode = (F3DZEXOpcode)(data >> 56); + + if (opcode == F3DZEXOpcode::G_SETOTHERMODE_L) + { + int ss = (data & 0x0000FF0000000000) >> 40; + int nn = (data & 0x000000FF00000000) >> 32; + int dd = (data & 0xFFFFFFFF); + + int sft = 32 - (nn + 1) - ss; + + if (sft == 3) + { + int mode1 = (dd & 0xCCCC0000) >> 0; + int mode2 = (dd & 0x33330000) >> 0; + + } + } + else if (opcode == F3DZEXOpcode::G_SETPRIMCOLOR) + { + int mm = (data & 0x0000FF0000000000) >> 40; + int ff = (data & 0x000000FF00000000) >> 32; + int rr = (data & 0x00000000FF000000) >> 24; + int gg = (data & 0x0000000000FF0000) >> 16; + int bb = (data & 0x000000000000FF00) >> 8; + int aa = (data & 0x00000000000000FF) >> 0; + + lastClrR = rr; + lastClrG = gg; + lastClrB = bb; + lastClrA = aa; + lastClrL = ff; + lastClrM = mm; + + lastMat->clrR = rr; + lastMat->clrG = gg; + lastMat->clrB = bb; + lastMat->clrA = aa; + lastMat->clrL = ff; + lastMat->clrM = mm; + } + else if (opcode == F3DZEXOpcode::G_SETTILE && (F3DZEXOpcode)(zDisplayList->instructions[i - 1] >> 56) != F3DZEXOpcode::G_RDPPIPESYNC) + { + int fff = (data & 0b0000000011100000000000000000000000000000000000000000000000000000) >> 53; + int ii = (data & 0b0000000000011000000000000000000000000000000000000000000000000000) >> 51; + int nnnnnnnnn = (data & 0b0000000000000011111111100000000000000000000000000000000000000000) >> 41; + int mmmmmmmmm = (data & 0b0000000000000000000000011111111100000000000000000000000000000000) >> 32; + int ttt = (data & 0b0000000000000000000000000000000000000111000000000000000000000000) >> 24; + int pppp = (data & 0b0000000000000000000000000000000000000000111100000000000000000000) >> 20; + int cc = (data & 0b0000000000000000000000000000000000000000000011000000000000000000) >> 18; + int aaaa = (data & 0b0000000000000000000000000000000000000000000000111100000000000000) >> 14; + int ssss = (data & 0b0000000000000000000000000000000000000000000000000011110000000000) >> 10; + int dd = (data & 0b0000000000000000000000000000000000000000000000000000001100000000) >> 8; + int bbbb = (data & 0b0000000000000000000000000000000000000000000000000000000011110000) >> 4; + int uuuu = (data & 0b0000000000000000000000000000000000000000000000000000000000001111); + + lastMat->cmtH = (HLMaterialCmt)cc; + lastMat->cmtV = (HLMaterialCmt)dd; + + matCnt++; + + if (matCnt > 1) + { + model->blocks.push_back(lastMat); + limb->commands.push_back(new HLLimbCommand(mesh->name, lastMat->name)); + lastMat = new HLMaterialIntermediette(); + lastMat->name = StringHelper::Sprintf("Material_%i", matCnt); + + lastMat->clrR = lastClrR; + lastMat->clrG = lastClrG; + lastMat->clrB = lastClrB; + lastMat->clrA = lastClrA; + lastMat->clrL = lastClrL; + lastMat->clrM = lastClrM; + + // Bit of a hack here... + int32_t lastData = (int32_t)(zDisplayList->instructions[i - 1]); + string texName = zDisplayList->textures[lastData & 0x00FFFFFF]->GetName(); + lastMat->textureName = texName; + + // -------------------------- + model->blocks.push_back(mesh); + + meshCnt++; + + mesh = new HLMeshIntermediette(); + mesh->name = StringHelper::Sprintf("%s_%i", zDisplayList->GetName().c_str(), meshCnt); + } + } + else if (opcode == F3DZEXOpcode::G_SETTIMG) + { + int32_t texAddress = data & 0x00FFFFFF; + + string texName = zDisplayList->textures[texAddress]->GetName(); + lastMat->textureName = texName; + } + else if (opcode == F3DZEXOpcode::G_VTX) + { + int nn = (data & 0x000FF00000000000ULL) >> 44; + int aa = (data & 0x000000FF00000000ULL) >> 32; + int startIndex = ((aa >> 1) - nn); + uint32_t vtxAddr = data & 0x00FFFFFF; + uint32_t diff = vtxAddr - vStart; + + startIndex += diff / 16; + + mesh->commands.push_back(new HLMeshCmdLoadVertices(nn, startIndex)); + } + else if (opcode == F3DZEXOpcode::G_TRI1) + { + int aa = ((data & 0x00FF000000000000ULL) >> 48) / 2; + int bb = ((data & 0x0000FF0000000000ULL) >> 40) / 2; + int cc = ((data & 0x000000FF00000000ULL) >> 32) / 2; + + mesh->commands.push_back(new HLMeshCmdTriangle1(aa, bb, cc, 0)); + } + else if (opcode == F3DZEXOpcode::G_TRI2) + { + int aa = ((data & 0x00FF000000000000ULL) >> 48) / 2; + int bb = ((data & 0x0000FF0000000000ULL) >> 40) / 2; + int cc = ((data & 0x000000FF00000000ULL) >> 32) / 2; + int dd = ((data & 0x00000000FF0000ULL) >> 16) / 2; + int ee = ((data & 0x0000000000FF00ULL) >> 8) / 2; + int ff = ((data & 0x000000000000FFULL) >> 0) / 2; + + mesh->commands.push_back(new HLMeshCmdTriangle2(aa, bb, cc, 0, dd, ee, ff, 0)); + } + + int bp = 0; + } + + limb->commands.push_back(new HLLimbCommand(mesh->name, lastMat->name)); + model->blocks.push_back(lastMat); + model->blocks.push_back(mesh); + model->blocks.push_back(limb); + + //return model; +} + +void HLModelIntermediette::FromZSkeleton(HLModelIntermediette* model, ZSkeleton* zSkeleton) +{ + model->hasSkeleton = true; + + for (int i = 0; i < zSkeleton->limbs.size(); i++) + { + ZLimbStandard* limb = zSkeleton->limbs[i]; + + for (int j = 0; j < model->blocks.size(); j++) + { + } + } +} + +string HLModelIntermediette::ToOBJFile() +{ + string output = ""; + + for (HLIntermediette* block : blocks) + { + block->parent = this; + string code = block->OutputOBJ(); + + output += code; + + if (code != "") + output += "\n"; + } + + return output; +} + +string HLModelIntermediette::ToFBXFile() +{ +#ifdef USE_ASSIMP + Assimp::Exporter exporter; + aiScene* newScene = new aiScene(); + newScene->mMeshes = new aiMesh*[128]; + newScene->mRootNode = new aiNode(); + newScene->mRootNode->mName = "RootNode"; + + std::vector vertices; + + for (HLIntermediette* block : blocks) + { + block->parent = this; + block->OutputAssimp(newScene, &vertices); + } + + newScene->mRootNode->mNumChildren += newScene->mNumMeshes; + newScene->mRootNode->mChildren = new aiNode*[newScene->mRootNode->mNumChildren]; + + for (int i = 0; i < newScene->mNumMeshes; i++) + { + aiNode* child = new aiNode(); + child->mName = StringHelper::Sprintf("OBJ_%i", i); + child->mNumMeshes = 1; + child->mMeshes = new unsigned int[1]; + child->mMeshes[0] = i; + newScene->mRootNode->mChildren[i] = child; + } + + newScene->mNumMaterials = 1; + newScene->mMaterials = new aiMaterial*[1]; + newScene->mMaterials[0] = new aiMaterial(); + + exporter.Export(newScene, "fbx", "__export.fbx"); +#endif + + return ""; +} + +string HLModelIntermediette::OutputCode() +{ + string output = ""; + + for (HLIntermediette* block : blocks) + { + string code = block->OutputCode(); + + output += code; + + if (code != "") + output += "\n"; + } + + return output; +} + +std::string HLModelIntermediette::OutputXML() +{ + string output = ""; + XMLDocument doc; + + XMLElement* root = doc.NewElement("HLModelIntermediette"); + + for (HLIntermediette* block : blocks) + block->OutputXML(&doc, root); + + doc.InsertEndChild(root); + + XMLPrinter printer; + + doc.Accept(&printer); + return printer.CStr(); +} + + +template +inline T* HLModelIntermediette::FindByName(string name) +{ + for (HLIntermediette* block : blocks) + { + if (typeid(*block) == typeid(T)) + { + if (block->name == name) + return (T*)block; + } + } + + return nullptr; +} + +template +inline T* HLModelIntermediette::FindByType() +{ + for (HLIntermediette* block : blocks) + { + if (typeid(*block) == typeid(T)) + return (T*)block; + } + + return nullptr; +} + +HLIntermediette::HLIntermediette() +{ + name = ""; + parent = nullptr; +} + +HLIntermediette::~HLIntermediette() +{ +} + +void HLIntermediette::InitFromXML(XMLElement* xmlElement) +{ + name = xmlElement->Attribute("Name"); +} + +string HLIntermediette::OutputCode() +{ + return ""; +} + +string HLIntermediette::OutputOBJ() +{ + return ""; +} + +void HLIntermediette::OutputAssimp(aiScene* scene, std::vector* verts) +{ + +} + +void HLIntermediette::OutputXML(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* root) +{ + +} + +void HLMeshCommand::InitFromXML(XMLElement* xmlElement) +{ + +} + +string HLMeshCommand::OutputCode(HLModelIntermediette* parent) +{ + return ""; +} + +std::string HLMeshCommand::OutputOBJ(HLModelIntermediette* parent) +{ + return ""; +} + +void HLMeshCommand::OutputAssimp(HLModelIntermediette* parent, aiScene* scene, aiMesh* mesh) +{ +} + +void HLMeshCommand::OutputXML(tinyxml2::XMLElement* parent) +{ +} + + +HLVerticesIntermediette::HLVerticesIntermediette() : HLIntermediette() +{ + vertices = vector(); +} + +void HLVerticesIntermediette::InitFromXML(XMLElement* verticesElement) +{ + name = verticesElement->Attribute("Name"); + + for (XMLElement* child = verticesElement->FirstChildElement(); child != NULL; child = child->NextSiblingElement()) + vertices.push_back(Vertex(child->IntAttribute("X"), child->IntAttribute("Y"), child->IntAttribute("Z"), child->IntAttribute("Flags"), + child->IntAttribute("S"), child->IntAttribute("T"), + child->IntAttribute("R"), child->IntAttribute("G"), child->IntAttribute("B"), child->IntAttribute("A"))); +} + +void HLVerticesIntermediette::InitFromVertices(vector dispListVertices) +{ + for (Vertex v : dispListVertices) + vertices.push_back(v); +} + +string HLVerticesIntermediette::OutputCode(HLModelIntermediette* parent) +{ + string output = ""; + + output += StringHelper::Sprintf("Vtx %s_verts[] = \n{\n", name.c_str()); + + for (Vertex v : vertices) + { + output += StringHelper::Sprintf("\t{ %i, %i, %i, %i, %i, %i, %i, %i, %i, %i },\n", + v.x, v.y, v.z, v.flag, v.s, v.t, v.r, v.g, v.b, v.a); + } + + output += StringHelper::Sprintf("};\n"); + + return output; +} + +std::string HLVerticesIntermediette::OutputOBJ() +{ + string output = ""; + + for (Vertex v : vertices) + { + output += StringHelper::Sprintf("v %f %f %f %i %i %i %i\n", (float)v.x * 0.1f, (float)v.y * 0.1f, (float)v.z * 0.1f, v.r, v.g, v.b, v.a); + //output += StringHelper::Sprintf("v %f %f %f\n", (float)v.x * 0.1f, (float)v.y * 0.1f, (float)v.z * 0.1f); + } + + //for (Vertex v : vertices) + //output += StringHelper::Sprintf("vt %i %i\n", v.s, v.t); + + return output; +} + +void HLVerticesIntermediette::OutputAssimp(aiScene* scene, std::vector* verts) +{ + //aiVector3D* verts = new aiVector3D[vertices.size()]; + //aiVector3D* normals = new aiVector3D[vertices.size()]; + + verts->clear(); + + for (int i = 0; i < vertices.size(); i++) + { + verts->push_back(aiVector3D(vertices[i].x, vertices[i].y, vertices[i].z)); + //normals[i] = aiVector3D(vertices[i].x, vertices[i].y, vertices[i].z); + } + + //mesh->mVertices = verts; + //mesh->mNormals = normals; + //mesh->mNumVertices += vertices.size(); +} + +void HLVerticesIntermediette::OutputXML(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* root) +{ + XMLElement* element = doc->NewElement("Vertices"); + + element->SetAttribute("Name", name.c_str()); + + for (Vertex v : vertices) + { + XMLElement* vElem = doc->NewElement("Vertex"); + vElem->SetAttribute("X", v.x); + vElem->SetAttribute("Y", v.y); + vElem->SetAttribute("Z", v.z); + vElem->SetAttribute("Flag", v.flag); + vElem->SetAttribute("S", v.s); + vElem->SetAttribute("T", v.t); + vElem->SetAttribute("R", v.r); + vElem->SetAttribute("G", v.g); + vElem->SetAttribute("B", v.b); + vElem->SetAttribute("A", v.a); + + element->InsertEndChild(vElem); + } + + root->InsertEndChild(element); +} + +HLMeshCmdGeoSettings::HLMeshCmdGeoSettings() +{ + on = ""; + off = ""; +} + +void HLMeshCmdGeoSettings::InitFromXML(tinyxml2::XMLElement* xmlElement) +{ + on = xmlElement->Attribute("On"); + off = xmlElement->Attribute("Off"); +} + +string HLMeshCmdGeoSettings::OutputCode(HLModelIntermediette* parent) +{ + string output = ""; + + if (off != "") + output += StringHelper::Sprintf("gsSPClearGeometryMode(G_TEXTURE_ENABLE | %s),\n", off.c_str()); + + if (on != "") + output += StringHelper::Sprintf("gsSPSetGeometryMode(G_TEXTURE_ENABLE | %s),", on.c_str()); + + return output; +} + +HLMeshCmdTriangle1::HLMeshCmdTriangle1() +{ + v0 = 0; + v1 = 0; + v2 = 0; + flag = 0; +} + +HLMeshCmdTriangle1::HLMeshCmdTriangle1(int32_t nV0, int32_t nV1, int32_t nV2, int32_t nFlag) +{ + v0 = nV0; + v1 = nV1; + v2 = nV2; + flag = nFlag; +} + +void HLMeshCmdTriangle1::InitFromXML(tinyxml2::XMLElement* xmlElement) +{ + v0 = xmlElement->IntAttribute("v0"); + v1 = xmlElement->IntAttribute("v1"); + v2 = xmlElement->IntAttribute("v2"); + flag = xmlElement->IntAttribute("flag"); +} + +string HLMeshCmdTriangle1::OutputCode(HLModelIntermediette* parent) +{ + return StringHelper::Sprintf("gsSP1Triangle(%i, %i, %i, %i),", v0, v1, v2, flag); +} + +void HLMeshCmdTriangle1::OutputAssimp(HLModelIntermediette* parent, aiScene* scene, aiMesh* mesh) +{ + aiFace* face = new aiFace(); + face->mNumIndices = 3; + face->mIndices = new unsigned int[3]; + face->mIndices[0] = parent->startIndex + v0; + face->mIndices[1] = parent->startIndex + v1; + face->mIndices[2] = parent->startIndex + v2; + + mesh->mFaces[mesh->mNumFaces++] = face[0]; +} + +void HLMeshCmdTriangle1::OutputXML(tinyxml2::XMLElement* parent) +{ + XMLElement* elem = parent->GetDocument()->NewElement("Triangle1"); + + elem->SetAttribute("V0", v0); + elem->SetAttribute("V1", v1); + elem->SetAttribute("V2", v2); + elem->SetAttribute("Flag", flag); + + parent->InsertEndChild(elem); +} + +HLMeshCmdTriangle2::HLMeshCmdTriangle2() +{ + v0 = 0; + v1 = 0; + v2 = 0; + flag0 = 0; + v10 = 0; + v11 = 0; + v12 = 0; + flag1 = 0; +} + +HLMeshCmdTriangle2::HLMeshCmdTriangle2(int32_t nV0, int32_t nV1, int32_t nV2, int32_t nFlag0, int32_t nV10, int32_t nV11, int32_t nV12, int32_t nFlag1) +{ + v0 = nV0; + v1 = nV1; + v2 = nV2; + flag0 = nFlag0; + v10 = nV10; + v11 = nV11; + v12 = nV12; + flag1 = nFlag1; +} + +void HLMeshCmdTriangle2::InitFromXML(tinyxml2::XMLElement* xmlElement) +{ + v0 = xmlElement->IntAttribute("V0"); + v1 = xmlElement->IntAttribute("V1"); + v2 = xmlElement->IntAttribute("V2"); + flag0 = xmlElement->IntAttribute("Flag0"); + v10 = xmlElement->IntAttribute("V10"); + v11 = xmlElement->IntAttribute("V11"); + v12 = xmlElement->IntAttribute("V12"); + flag1 = xmlElement->IntAttribute("Flag1"); +} + +string HLMeshCmdTriangle2::OutputCode(HLModelIntermediette* parent) +{ + return StringHelper::Sprintf("gsSP2Triangles(%i, %i, %i, %i, %i, %i, %i, %i),", v0, v1, v2, flag0, v10, v11, v12, flag1); +} + +std::string HLMeshCmdTriangle2::OutputOBJ(HLModelIntermediette* parent) +{ + HLVerticesIntermediette* verts = parent->FindByName(""); + string output = ""; + + int startIndex = parent->startIndex; + + output += StringHelper::Sprintf("f %i %i %i\n", startIndex+v0+1, startIndex + v1+1, startIndex + v2+1); + output += StringHelper::Sprintf("f %i %i %i\n", startIndex + v10+1, startIndex + v11+1, startIndex + v12+1); + + return output; +} + +void HLMeshCmdTriangle2::OutputAssimp(HLModelIntermediette* parent, aiScene* scene, aiMesh* mesh) +{ + { + aiFace* face = new aiFace(); + face->mNumIndices = 3; + face->mIndices = new unsigned int[3]; + face->mIndices[0] = parent->startIndex + v0; + face->mIndices[1] = parent->startIndex + v1; + face->mIndices[2] = parent->startIndex + v2; + + mesh->mFaces[mesh->mNumFaces++] = face[0]; + } + + { + aiFace* face = new aiFace(); + face->mNumIndices = 3; + face->mIndices = new unsigned int[3]; + face->mIndices[0] = parent->startIndex + v10; + face->mIndices[1] = parent->startIndex + v11; + face->mIndices[2] = parent->startIndex + v12; + + mesh->mFaces[mesh->mNumFaces++] = face[0]; + } +} + +void HLMeshCmdTriangle2::OutputXML(tinyxml2::XMLElement* parent) +{ + XMLElement* elem = parent->GetDocument()->NewElement("Triangle2"); + + elem->SetAttribute("V0", v0); + elem->SetAttribute("V1", v1); + elem->SetAttribute("V2", v2); + elem->SetAttribute("Flag0", flag0); + elem->SetAttribute("V10", v10); + elem->SetAttribute("V11", v11); + elem->SetAttribute("V12", v12); + elem->SetAttribute("Flag1", flag1); + + parent->InsertEndChild(elem); +} + +HLMeshCmdLoadVertices::HLMeshCmdLoadVertices() : HLMeshCommand() +{ + numVerts = 0; + startIndex = 0; +} + +HLMeshCmdLoadVertices::HLMeshCmdLoadVertices(uint8_t nNumVerts, uint8_t nStartIndex) +{ + numVerts = nNumVerts; + startIndex = nStartIndex; +} + +void HLMeshCmdLoadVertices::OutputXML(tinyxml2::XMLElement* parent) +{ + XMLElement* elem = parent->GetDocument()->NewElement("LoadVertices"); + + elem->SetAttribute("StartIndex", startIndex); + elem->SetAttribute("NumVerts", numVerts); + + parent->InsertEndChild(elem); +} + +void HLMeshCmdLoadVertices::InitFromXML(tinyxml2::XMLElement* xmlElement) +{ + numVerts = xmlElement->IntAttribute("NumVerts", 0); + startIndex = xmlElement->IntAttribute("StartIndex", 0); +} + +std::string HLMeshCmdLoadVertices::OutputOBJ(HLModelIntermediette* parent) +{ + parent->startIndex = startIndex; + return ""; +} + +void HLMeshCmdLoadVertices::OutputAssimp(HLModelIntermediette* parent, aiScene* scene, aiMesh* mesh) +{ + parent->startIndex = startIndex; +} + +string HLMeshCmdLoadVertices::OutputCode(HLModelIntermediette* parent) +{ + HLVerticesIntermediette* verts = parent->FindByType(); + return StringHelper::Sprintf("gsSPVertex(&%s[%i], %i, %i),", verts->name.c_str(), startIndex, numVerts, 0); +} + +HLMaterialIntermediette::HLMaterialIntermediette() +{ + textureName = ""; + //repeatH = false; + //repeatV = false; + clrR = 0; + clrG = 0; + clrB = 0; + clrA = 0; + clrM = 0; + clrL = 0; + //clampH = false; + //clampV = false; + //mirrorH = false; + //mirrorV = false; + cmtH = HLMaterialCmt::Wrap; + cmtV = HLMaterialCmt::Wrap; +} + +void HLMaterialIntermediette::InitFromXML(tinyxml2::XMLElement* xmlElement) +{ + name = xmlElement->Attribute("Name"); + textureName = xmlElement->Attribute("TextureName"); + //repeatH = xmlElement->BoolAttribute("RepeatH"); + //repeatV = xmlElement->BoolAttribute("RepeatV"); + //clampH = xmlElement->BoolAttribute("ClampH"); + //clampV = xmlElement->BoolAttribute("ClampV"); + //mirrorH = xmlElement->BoolAttribute("MirrorH"); + //mirrorV = xmlElement->BoolAttribute("MirrorV"); + clrR = xmlElement->IntAttribute("ClrR"); + clrG = xmlElement->IntAttribute("ClrG"); + clrB = xmlElement->IntAttribute("ClrB"); + clrA = xmlElement->IntAttribute("ClrA"); + clrM = xmlElement->IntAttribute("ClrM"); + clrL = xmlElement->IntAttribute("ClrL"); +} + +string HLMaterialIntermediette::OutputCode() +{ + return ""; +} + +void HLMaterialIntermediette::OutputXML(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* parent) +{ + XMLElement* elem = parent->GetDocument()->NewElement("Material"); + + elem->SetAttribute("Name", name.c_str()); + elem->SetAttribute("TextureName", textureName.c_str()); + elem->SetAttribute("ClrR", clrR); + elem->SetAttribute("ClrG", clrG); + elem->SetAttribute("ClrB", clrB); + elem->SetAttribute("ClrA", clrA); + elem->SetAttribute("ClrL", clrL); + elem->SetAttribute("ClrM", clrM); + elem->SetAttribute("CmtH", (int)cmtH); + elem->SetAttribute("CmtV", (int)cmtV); + + parent->InsertEndChild(elem); +} + +HLDisplayListIntermediette::HLDisplayListIntermediette() +{ + commands = vector(); +} + +string HLDisplayListIntermediette::OutputCode() +{ + return std::string(); +} + +void HLDisplayListIntermediette::InitFromXML(tinyxml2::XMLElement* xmlElement) +{ + for (XMLElement* child = xmlElement->FirstChildElement(); child != NULL; child = child->NextSiblingElement()) + { + string name = child->Name(); + + HLDisplayListCommand* cmd = nullptr; + + if (name == "DrawMesh") + cmd = new HLDisplayListCmdDrawMesh(); + else if (name == "PipeSync") + cmd = new HLDisplayListCmdPipeSync(); + + if (cmd != nullptr) + { + cmd->InitFromXML(child); + commands.push_back(cmd); + } + } +} + +void HLDisplayListCommand::InitFromXML(tinyxml2::XMLElement* xmlElement) +{ +} + +std::string HLDisplayListCommand::OutputCode() +{ + return ""; +} + +void HLDisplayListCmdDrawMesh::InitFromXML(tinyxml2::XMLElement* xmlElement) +{ + meshName = xmlElement->Attribute("Mesh"); + materialName = xmlElement->Attribute("Material"); + +} + +std::string HLDisplayListCmdDrawMesh::OutputCode() +{ + return ""; +} + +HLTextureIntermediette::HLTextureIntermediette() +{ + tex = nullptr; +} + +void HLTextureIntermediette::InitFromXML(tinyxml2::XMLElement* xmlElement) +{ + name = xmlElement->Attribute("Name"); + + fileName = xmlElement->Attribute("TextureName"); + //string format = xmlElement->Attribute("Format"); + string format = "rgb5a1"; // TEST + + //tex = HLTexture::FromPNG(fileName, (HLTextureType)ZTexture::GetTextureTypeFromString(format)); + tex = ZTexture::FromPNG(Path::GetDirectoryName(Globals::Instance->inputPath) + "/" + fileName, ZTexture::GetTextureTypeFromString(format)); +} + +std::string HLTextureIntermediette::OutputCode() +{ + return StringHelper::Sprintf("#include <../%s/%s.inc.c>", Globals::Instance->outputPath.c_str(), name.c_str()); +} + +void HLTextureIntermediette::OutputXML(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* root) +{ + XMLElement* element = doc->NewElement("Texture"); + + element->SetAttribute("Name", name.c_str()); + element->SetAttribute("TextureName", (name + "." + tex->GetExternalExtension() + ".png").c_str()); + tex->Save(Globals::Instance->outputPath); + + root->InsertEndChild(element); +} + +void HLDisplayListCmdPipeSync::InitFromXML(tinyxml2::XMLElement* xmlElement) +{ +} + +std::string HLDisplayListCmdPipeSync::OutputCode() +{ + return "gsDPPipeSync(),"; +} + +HLMeshCmdCull::HLMeshCmdCull() : HLMeshCommand() +{ + indexStart = 0; + indexEnd = 0; +} + +void HLMeshCmdCull::InitFromXML(tinyxml2::XMLElement* xmlElement) +{ + indexStart = xmlElement->IntAttribute("IndexStart", 0); + indexEnd = xmlElement->IntAttribute("IndexEnd", 0); +} + +std::string HLMeshCmdCull::OutputCode(HLModelIntermediette* parent) +{ + return StringHelper::Sprintf("gsSPCullDisplayList(%i, %i),", indexStart, indexEnd); +} + +HLMeshIntermediette::HLMeshIntermediette() : HLIntermediette() +{ + commands = vector(); +} + +void HLMeshIntermediette::InitFromXML(tinyxml2::XMLElement* xmlElement) +{ + name = xmlElement->Attribute("Name"); + + for (XMLElement* child = xmlElement->FirstChildElement(); child != NULL; child = child->NextSiblingElement()) + { + string name = child->Name(); + + HLMeshCommand* cmd = nullptr; + + if (name == "Triangle1") + cmd = new HLMeshCmdTriangle1(); + else if (name == "Triangle2") + cmd = new HLMeshCmdTriangle2(); + else if (name == "LoadVertices") + cmd = new HLMeshCmdLoadVertices(); + else if (name == "GeoSettings") + cmd = new HLMeshCmdGeoSettings(); + else if (name == "Cull") + cmd = new HLMeshCmdCull(); + + if (cmd != nullptr) + { + cmd->InitFromXML(child); + commands.push_back(cmd); + } + } +} + +string HLMeshIntermediette::OutputCode(string materialName) +{ + string output = ""; + + HLMaterialIntermediette* mat = parent->FindByName(materialName); + HLTextureIntermediette* tex = parent->FindByName(mat->textureName); + + output += StringHelper::Sprintf("\tgsDPPipeSync(),\n"); + output += StringHelper::Sprintf("\tgsDPSetPrimColor(%i, %i, %i, %i, %i, %i),\n", mat->clrL, mat->clrM, mat->clrR, mat->clrG, mat->clrB, mat->clrA); + output += StringHelper::Sprintf("\tgsDPPipeSync(),\n"); + output += StringHelper::Sprintf("\tgsSPTexture(65535, 65535, 0, 0, G_ON),\n"); + + output += StringHelper::Sprintf("\tgsDPLoadMultiBlock(%s, 0, 0, %s, %s, %i, %i, 0, 0, 0, 5, 5, 0, 0),\n", mat->textureName.c_str(), + tex->tex->GetIMFmtFromType().c_str(), tex->tex->GetIMSizFromType().c_str(), tex->tex->GetWidth(), tex->tex->GetHeight()); + + + for (HLMeshCommand* cmd : commands) + output += "\t" + cmd->OutputCode(parent) + "\n"; + + return output; +} + +string HLMeshIntermediette::OutputOBJ() +{ + string output = ""; + + output += StringHelper::Sprintf("o %s\n", name.c_str()); + + for (HLMeshCommand* cmd : commands) + output += cmd->OutputOBJ(parent); + + return output; +} + +void HLMeshIntermediette::OutputAssimp(aiScene* scene, std::vector* verts) +{ + aiMesh* mesh = new aiMesh(); + mesh->mVertices = new aiVector3D[8192]; // TODO: Replace these hardcoded counts with the actual count + mesh->mNormals = new aiVector3D[8192]; + mesh->mFaces = new aiFace[8192]; + mesh->mPrimitiveTypes = 8; + mesh->mName = name; + + for (HLMeshCommand* cmd : commands) + { + cmd->OutputAssimp(parent, scene, mesh); + } + + scene->mMeshes[scene->mNumMeshes++] = mesh; +} + +void HLMeshIntermediette::OutputXML(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* root) +{ + XMLElement* element = doc->NewElement("Mesh"); + + element->SetAttribute("Name", name.c_str()); + + for (HLMeshCommand* cmd : commands) + { + cmd->OutputXML(element); + } + + root->InsertEndChild(element); +} + +HLLimbIntermediette::HLLimbIntermediette() +{ + commands = vector(); +} + +void HLLimbIntermediette::InitFromXML(tinyxml2::XMLElement* xmlElement) +{ + name = xmlElement->Attribute("Name"); + + for (XMLElement* child = xmlElement->FirstChildElement(); child != NULL; child = child->NextSiblingElement()) + { + string name = child->Name(); + + HLLimbCommand* cmd = nullptr; + + if (name == "DrawMesh") + cmd = new HLLimbCommand(); + + if (cmd != nullptr) + { + cmd->InitFromXML(child); + commands.push_back(cmd); + } + } +} + +std::string HLLimbIntermediette::OutputCode() +{ + string output = ""; + + output += StringHelper::Sprintf("Gfx %s[] = \n{\n", name.c_str()); + + for (HLLimbCommand* cmd : commands) + output += cmd->OutputCode(parent); + + output += StringHelper::Sprintf("\tgsSPEndDisplayList(),\n"); + output += StringHelper::Sprintf("};\n"); + + return output; +} + +void HLLimbIntermediette::OutputXML(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* root) +{ + XMLElement* element = doc->NewElement("Limb"); + + element->SetAttribute("Name", name.c_str()); + + for (HLLimbCommand* cmd : commands) + cmd->OutputXML(element); + + root->InsertEndChild(element); +} + +HLLimbCommand::HLLimbCommand() +{ + meshName = ""; + materialName = ""; +} + +HLLimbCommand::HLLimbCommand(std::string nMeshName, std::string nMaterialName) +{ + meshName = nMeshName; + materialName = nMaterialName; +} + +void HLLimbCommand::InitFromXML(tinyxml2::XMLElement* xmlElement) +{ + meshName = xmlElement->Attribute("Mesh"); + materialName = xmlElement->Attribute("Material"); +} + +void HLLimbCommand::OutputXML(tinyxml2::XMLElement* parent) +{ + XMLElement* elem = parent->GetDocument()->NewElement("DrawMesh"); + + elem->SetAttribute("Mesh", meshName.c_str()); + elem->SetAttribute("Material", materialName.c_str()); + + parent->InsertEndChild(elem); +} + +std::string HLLimbCommand::OutputCode(HLModelIntermediette* parent) +{ + string output = ""; + + // Time to generate the display list... + HLMeshIntermediette* mesh = parent->FindByName(meshName); + HLMaterialIntermediette* mat = parent->FindByName(materialName); + HLTextureIntermediette* tex = parent->FindByName(mat->textureName); + + output += mesh->OutputCode(materialName); + + return output; +} + +HLTerminator::HLTerminator() +{ +} + +HLTerminator::~HLTerminator() +{ +} + +void HLTerminator::OutputAssimp(aiScene* scene, std::vector* verts) +{ + for (int i = parent->meshStartIndex; i < scene->mNumMeshes; i++) + { + scene->mMeshes[i]->mNumVertices = verts->size(); + + for (int j = 0; j < verts->size(); j++) + scene->mMeshes[i]->mVertices[j] = verts[0][j]; + + parent->meshStartIndex++; + } + + verts->clear(); +} diff --git a/tools/ZAPD/ZAPD/HighLevel/HLModelIntermediette.h b/tools/ZAPD/ZAPD/HighLevel/HLModelIntermediette.h new file mode 100644 index 0000000000..14aab026bb --- /dev/null +++ b/tools/ZAPD/ZAPD/HighLevel/HLModelIntermediette.h @@ -0,0 +1,282 @@ +#pragma once + +#include +#include +#include +#include "HLTexture.h" +#include "HLFileIntermediette.h" +#include "../ZDisplayList.h" +#include "../ZSkeleton.h" +#include "../tinyxml2.h" +#include "../assimp/scene.h" + +/* + * An intermediette format for models. Goes from FBX<-->Intermediette<-->Display List C Code. + */ + +class HLModelIntermediette; + +class HLIntermediette +{ +public: + std::string name; + HLModelIntermediette* parent; + + HLIntermediette(); + ~HLIntermediette(); + + virtual std::string OutputCode(); + virtual std::string OutputOBJ(); + virtual void OutputAssimp(aiScene* scene, std::vector* verts); + virtual void OutputXML(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* root); + virtual void InitFromXML(tinyxml2::XMLElement* xmlElement); +}; + +class HLModelIntermediette : public HLFileIntermediette +{ +public: + std::vector blocks; + + bool hasSkeleton; + + bool startsWithPipeSync; + bool startsWithClearGeometryMode; + bool lerpBeforeTextureBlock; + + int startIndex; + int meshStartIndex; + + HLModelIntermediette(); + ~HLModelIntermediette(); + + static HLModelIntermediette* FromXML(tinyxml2::XMLElement* root); + static void FromZDisplayList(HLModelIntermediette* model, ZDisplayList* zDisplayList); + static void FromZSkeleton(HLModelIntermediette* model, ZSkeleton* zSkeleton); + std::string ToOBJFile(); + std::string ToFBXFile(); + + std::string OutputCode(); + std::string OutputXML(); + + template + T* FindByName(std::string name); + + template + T* FindByType(); +}; + +class HLTextureIntermediette : public HLIntermediette +{ +public: + ZTexture* tex; + std::string fileName; + + HLTextureIntermediette(); + + virtual void InitFromXML(tinyxml2::XMLElement* xmlElement); + virtual std::string OutputCode(); + virtual void OutputXML(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* root); +}; + +class HLTerminator : public HLIntermediette +{ +public: + HLTerminator(); + ~HLTerminator(); + + virtual void OutputAssimp(aiScene* scene, std::vector* verts); +}; + +enum class HLMaterialCmt +{ + Wrap, + Mirror, + Clamp +}; + +class HLMaterialIntermediette : public HLIntermediette +{ +public: + std::string textureName; + //int32_t repeatH, repeatV; + uint8_t clrR, clrG, clrB, clrA, clrM, clrL; + //bool clampH, clampV; + //bool mirrorH, mirrorV; + HLMaterialCmt cmtH, cmtV; + + // TODO: Remember to add lerp params here... + + HLMaterialIntermediette(); + + virtual std::string OutputCode(); + virtual void OutputXML(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* parent); + virtual void InitFromXML(tinyxml2::XMLElement* xmlElement); +}; + +class HLMeshCommand +{ +public: + virtual void InitFromXML(tinyxml2::XMLElement* xmlElement); + virtual std::string OutputCode(HLModelIntermediette* parent); + virtual std::string OutputOBJ(HLModelIntermediette* parent); + virtual void OutputAssimp(HLModelIntermediette* parent, aiScene* scene, aiMesh* mesh); + + virtual void OutputXML(tinyxml2::XMLElement* parent); +}; + +class HLVerticesIntermediette : public HLIntermediette +{ +public: + std::vector vertices; + + HLVerticesIntermediette(); + + virtual void InitFromXML(tinyxml2::XMLElement* verticesElement); + void InitFromVertices(std::vector dispListVertices); + virtual std::string OutputCode(HLModelIntermediette* parent); + virtual std::string OutputOBJ(); + virtual void OutputAssimp(aiScene* scene, std::vector* verts); + virtual void OutputXML(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* root); +}; + +class HLMeshCmdTriangle1 : public HLMeshCommand +{ +public: + int32_t v0, v1, v2, flag; + + HLMeshCmdTriangle1(); + HLMeshCmdTriangle1(int32_t nV0, int32_t nV1, int32_t nV2, int32_t nFlag); + + virtual void InitFromXML(tinyxml2::XMLElement* xmlElement); + virtual std::string OutputCode(HLModelIntermediette* parent); + virtual void OutputAssimp(HLModelIntermediette* parent, aiScene* scene, aiMesh* mesh); + virtual void OutputXML(tinyxml2::XMLElement* parent); +}; + +class HLMeshCmdTriangle2 : public HLMeshCommand +{ +public: + int32_t v0, v1, v2, flag0, v10, v11, v12, flag1; + + HLMeshCmdTriangle2(); + HLMeshCmdTriangle2(int32_t nV0, int32_t nV1, int32_t nV2, int32_t nFlag0, int32_t nV10, int32_t nV11, int32_t nV12, int32_t nFlag1); + + virtual void InitFromXML(tinyxml2::XMLElement* xmlElement); + virtual std::string OutputCode(HLModelIntermediette* parent); + virtual std::string OutputOBJ(HLModelIntermediette* parent); + virtual void OutputAssimp(HLModelIntermediette* parent, aiScene* scene, aiMesh* mesh); + virtual void OutputXML(tinyxml2::XMLElement* parent); +}; + +class HLMeshCmdLoadVertices : public HLMeshCommand +{ +public: + uint8_t numVerts; + uint8_t startIndex; + + HLMeshCmdLoadVertices(); + HLMeshCmdLoadVertices(uint8_t nNumVerts, uint8_t nStartIndex); + + virtual void OutputXML(tinyxml2::XMLElement* parent); + virtual void InitFromXML(tinyxml2::XMLElement* xmlElement); + virtual std::string OutputOBJ(HLModelIntermediette* parent); + virtual void OutputAssimp(HLModelIntermediette* parent, aiScene* scene, aiMesh* mesh); + virtual std::string OutputCode(HLModelIntermediette* parent); +}; + +class HLMeshCmdCull : public HLMeshCommand +{ +public: + uint8_t indexStart; + uint8_t indexEnd; + + HLMeshCmdCull(); + + virtual void InitFromXML(tinyxml2::XMLElement* xmlElement); + virtual std::string OutputCode(HLModelIntermediette* parent); +}; + +class HLMeshCmdGeoSettings : public HLMeshCommand +{ +public: + std::string on, off; + + HLMeshCmdGeoSettings(); + + virtual void InitFromXML(tinyxml2::XMLElement* xmlElement); + virtual std::string OutputCode(HLModelIntermediette* parent); +}; + +class HLMeshIntermediette : public HLIntermediette +{ +public: + std::vector commands; + + HLMeshIntermediette(); + + void InitFromXML(tinyxml2::XMLElement* xmlElement); + std::string OutputCode(std::string materialName); + virtual std::string OutputOBJ(); + virtual void OutputAssimp(aiScene* scene, std::vector* verts); + virtual void OutputXML(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* root); +}; + +class HLDisplayListCommand +{ +public: + virtual void InitFromXML(tinyxml2::XMLElement* xmlElement); + virtual std::string OutputCode(); +}; + +class HLDisplayListCmdDrawMesh : public HLDisplayListCommand +{ +public: + std::string meshName, materialName; + + virtual void InitFromXML(tinyxml2::XMLElement* xmlElement); + virtual std::string OutputCode(); +}; + +class HLDisplayListCmdPipeSync : public HLDisplayListCommand +{ +public: + virtual void InitFromXML(tinyxml2::XMLElement* xmlElement); + virtual std::string OutputCode(); +}; + +class HLDisplayListIntermediette : public HLIntermediette +{ +public: + std::vector commands; + int address; + + HLDisplayListIntermediette(); + + virtual std::string OutputCode(); + virtual void InitFromXML(tinyxml2::XMLElement* xmlElement); +}; + +class HLLimbCommand +{ +public: + std::string meshName, materialName; + + HLLimbCommand(); + HLLimbCommand(std::string nMeshName, std::string nMaterialName); + + virtual void InitFromXML(tinyxml2::XMLElement* xmlElement); + virtual void OutputXML(tinyxml2::XMLElement* parent); + virtual std::string OutputCode(HLModelIntermediette* parent); +}; + +class HLLimbIntermediette : public HLIntermediette +{ +public: + std::vector commands; + + HLLimbIntermediette(); + + void InitFromXML(tinyxml2::XMLElement* xmlElement); + std::string OutputCode(); + virtual void OutputXML(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* root); +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/HighLevel/HLTexture.cpp b/tools/ZAPD/ZAPD/HighLevel/HLTexture.cpp new file mode 100644 index 0000000000..fc81c286ac --- /dev/null +++ b/tools/ZAPD/ZAPD/HighLevel/HLTexture.cpp @@ -0,0 +1,15 @@ +#include "HLTexture.h" +#include "../StringHelper.h" +#include "../stb_image.h" + +using namespace std; + +HLTexture* HLTexture::FromPNG(std::string pngFilePath, HLTextureType texType) +{ + int comp; + HLTexture* tex = new HLTexture(); + tex->type = texType; + tex->bmpRgba = (uint8_t*)stbi_load((pngFilePath).c_str(), (int*)&tex->width, (int*)&tex->height, &comp, STBI_rgb_alpha); + + return tex; +} diff --git a/tools/ZAPD/ZAPD/HighLevel/HLTexture.h b/tools/ZAPD/ZAPD/HighLevel/HLTexture.h new file mode 100644 index 0000000000..c8c187b80a --- /dev/null +++ b/tools/ZAPD/ZAPD/HighLevel/HLTexture.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include +#include + +// TODO: This was duplicated from ZTexture. It's probably going to be modified to differentiate from ZTexture but if not, we're going to need to have the two share an enum. +enum class HLTextureType +{ + RGBA32bpp, + RGBA16bpp, + Palette4bpp, + Palette8bpp, + Grayscale4bpp, + Grayscale8bpp, + GrayscaleAlpha4bpp, + GrayscaleAlpha8bpp, + GrayscaleAlpha16bpp, + Error +}; + + +class HLTexture +{ +public: + static HLTexture* FromPNG(std::string pngFilePath, HLTextureType texType); + + HLTextureType type; + uint32_t width, height; + uint8_t* bmpRgba; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/Libs/assimp-vc142-mt.dll b/tools/ZAPD/ZAPD/Libs/assimp-vc142-mt.dll new file mode 100644 index 0000000000..bf7a2f862f Binary files /dev/null and b/tools/ZAPD/ZAPD/Libs/assimp-vc142-mt.dll differ diff --git a/tools/ZAPD/ZAPD/Libs/assimp-vc142-mt.lib b/tools/ZAPD/ZAPD/Libs/assimp-vc142-mt.lib new file mode 100644 index 0000000000..88e0a99f02 Binary files /dev/null and b/tools/ZAPD/ZAPD/Libs/assimp-vc142-mt.lib differ diff --git a/tools/ZAPD/ZAPD/Main.cpp b/tools/ZAPD/ZAPD/Main.cpp new file mode 100644 index 0000000000..f583edd58b --- /dev/null +++ b/tools/ZAPD/ZAPD/Main.cpp @@ -0,0 +1,332 @@ +#include "ZFile.h" +#include "ZTexture.h" +#include "ZBlob.h" +#include "ZAnimation.h" +#include "HighLevel/HLModelIntermediette.h" +#include "HighLevel/HLAnimationIntermediette.h" +#include "Overlays/ZOverlay.h" +#include "Path.h" +#include "File.h" +#include "Globals.h" + +#if !defined(_MSC_VER) && !defined(__CYGWIN__) +#include +#include +#include +#endif + +#include +#include "tinyxml2.h" + +using namespace tinyxml2; +using namespace std; + +bool Parse(string xmlFilePath, string basePath, string outPath, ZFileMode fileMode); + +void BuildAssetTexture(string pngFilePath, TextureType texType, string outPath); +void BuildAssetBlob(string blobFilePath, string outPath); +void BuildAssetModelIntermediette(string mdlPath, string outPath); +void BuildAssetAnimationIntermediette(string animPath, string outPath); + +int NewMain(int argc, char* argv[]); + +#if !defined(_MSC_VER) && !defined(__CYGWIN__) +void ErrorHandler(int sig) +{ + void* array[4096]; + char** symbols; + size_t size; + size = backtrace(array, 4096); + symbols = backtrace_symbols(array, 4096); + + for (int i = 1; i < size; i++) + { + size_t len = strlen(symbols[i]); + cout << symbols[i] << "\n"; + } + + //cout << "Error: signal " << sig << ":\n"; + backtrace_symbols_fd(array, size, STDERR_FILENO); + exit(1); +} +#endif + +int main(int argc, char* argv[]) +{ + Globals* g = new Globals(); + return NewMain(argc, argv); +} + +int NewMain(int argc, char* argv[]) +{ + // Syntax: ZAPD.exe [mode (b/btex/bovl/e)] (Arbritrary Number of Arguments) + printf("ZAPD: Zelda Asset Processor For Decomp\n"); + + if (argc < 2) + { + printf("ZAPD.exe [mode (b/btex/bovl/bsf/bblb/bmdlintr/bamnintr/e)] ...\n"); + return 1; + } + + // Parse File Mode + string buildMode = argv[1]; + ZFileMode fileMode = ZFileMode::Invalid; + + if (buildMode == "b") + fileMode = ZFileMode::Build; + else if (buildMode == "btex") + fileMode = ZFileMode::BuildTexture; + else if (buildMode == "bovl") + fileMode = ZFileMode::BuildOverlay; + else if (buildMode == "bsf") + fileMode = ZFileMode::BuildSourceFile; + else if (buildMode == "bblb") + fileMode = ZFileMode::BuildBlob; + else if (buildMode == "bmdlintr") + fileMode = ZFileMode::BuildModelIntermediette; + else if (buildMode == "bamnintr") + fileMode = ZFileMode::BuildAnimationIntermediette; + else if (buildMode == "e") + fileMode = ZFileMode::Extract; + + if (fileMode == ZFileMode::Invalid) + { + printf("Error: Invalid file mode '%s'\n", buildMode.c_str()); + return 1; + } + + // Parse other "commands" + for (int i = 2; i < argc; i++) + { + string arg = argv[i]; + + if (arg == "-o" || arg == "--outputpath") // Set output path + { + Globals::Instance->outputPath = argv[i + 1]; + i++; + } + else if (arg == "-i" || arg == "--inputpath") // Set input path + { + Globals::Instance->inputPath = argv[i + 1]; + i++; + } + else if (arg == "-b" || arg == "--baserompath") // Set baserom path + { + Globals::Instance->baseRomPath = argv[i + 1]; + i++; + } + else if (arg == "-gsf") // Generate source file during extraction + { + Globals::Instance->genSourceFile = string(argv[i + 1]) == "1"; + i++; + } + else if (arg == "-ifp") // Include file prefix in generated symbols + { + Globals::Instance->includeFilePrefix = string(argv[i + 1]) == "1"; + i++; + } + else if (arg == "-tm") // Test Mode + { + Globals::Instance->testMode = string(argv[i + 1]) == "1"; + i++; + } + else if (arg == "-dm") // Debug Messages + { + Globals::Instance->debugMessages = string(argv[i + 1]) == "1"; + i++; + } + else if (arg == "-profile") // Profile + { + Globals::Instance->profile = string(argv[i + 1]) == "1"; + i++; + } + else if (arg == "-uer") // Split resources into their individual components (enabled by default) + { + Globals::Instance->useExternalResources = string(argv[i + 1]) == "1"; + i++; + } + else if (arg == "-tt") // Set texture type + { + Globals::Instance->texType = ZTexture::GetTextureTypeFromString(argv[i + 1]); + i++; + } + else if (arg == "-cfg") // Set cfg path + { + Globals::Instance->cfgPath = argv[i + 1]; + i++; + } + else if (arg == "-sm") // Set symbol map path + { + Globals::Instance->GenSymbolMap(argv[i + 1]); + i++; + } + else if (arg == "-rconf") // Read Config File + { + Globals::Instance->ReadConfigFile(argv[i + 1]); + i++; + } + else if (arg == "-al") // Set actor list + { + i++; + } + else if (arg == "-ol") // Set object list + { + i++; + } + else if (arg == "-eh") // Enable Error Handler + { +#if !defined(_MSC_VER) && !defined(__CYGWIN__) + signal(SIGSEGV, ErrorHandler); +#endif + } + } + + if (fileMode == ZFileMode::Build || fileMode == ZFileMode::Extract || fileMode == ZFileMode::BuildSourceFile) + { + Parse(Globals::Instance->inputPath, Globals::Instance->baseRomPath, Globals::Instance->outputPath, fileMode); + } + else if (fileMode == ZFileMode::BuildTexture) + { + TextureType texType = Globals::Instance->texType; + string pngFilePath = Globals::Instance->inputPath; + string outFilePath = Globals::Instance->outputPath; + + BuildAssetTexture(pngFilePath, texType, outFilePath); + } + else if (fileMode == ZFileMode::BuildBlob) + { + string blobFilePath = Globals::Instance->inputPath; + string outFilePath = Globals::Instance->outputPath; + + BuildAssetBlob(blobFilePath, outFilePath); + } + else if (fileMode == ZFileMode::BuildModelIntermediette) + { + BuildAssetModelIntermediette(Globals::Instance->inputPath, Globals::Instance->outputPath); + } + else if (fileMode == ZFileMode::BuildAnimationIntermediette) + { + BuildAssetAnimationIntermediette(Globals::Instance->inputPath, Globals::Instance->outputPath); + } + else if (fileMode == ZFileMode::BuildOverlay) + { + ZOverlay* overlay = ZOverlay::FromBuild(Path::GetDirectoryName(Globals::Instance->inputPath), Path::GetDirectoryName(Globals::Instance->cfgPath)); + + if (overlay) + File::WriteAllText(Globals::Instance->outputPath, overlay->GetSourceOutputCode("")); + } + + return 0; +} + +bool Parse(string xmlFilePath, string basePath, string outPath, ZFileMode fileMode) +{ + XMLDocument doc; + XMLError eResult = doc.LoadFile(xmlFilePath.c_str()); + + if (eResult != tinyxml2::XML_SUCCESS) + return false; + + XMLNode* root = doc.FirstChild(); + + if (root == nullptr) + return false; + + //vector files = vector(); + + for (XMLElement* child = root->FirstChildElement(); child != NULL; child = child->NextSiblingElement()) + { + if (string(child->Name()) == "File") + { + ZFile* file = new ZFile(fileMode, child, basePath, outPath, false); + Globals::Instance->files.push_back(file); + } + } + + for (ZFile* file : Globals::Instance->files) + { + if (fileMode == ZFileMode::Build) + file->BuildResources(); + else if (fileMode == ZFileMode::BuildSourceFile) + file->BuildSourceFile(outPath); + else + file->ExtractResources(outPath); + } + + XMLElement* element = root->FirstChildElement("File"); + + if (element == nullptr) + return false; + + return true; +} + +void BuildAssetTexture(string pngFilePath, TextureType texType, string outPath) +{ + vector split = StringHelper::Split(outPath, "/"); + string name = StringHelper::Split(split[split.size() - 1], ".")[0]; + ZTexture* tex = ZTexture::FromPNG(pngFilePath, texType); + string cfgPath = StringHelper::Split(pngFilePath, ".")[0] + ".cfg"; + + if (File::Exists(cfgPath)) + name = File::ReadAllText(cfgPath); + + //string src = StringHelper::Sprintf("u64 %s[] = \n{\n", name.c_str()) + tex->GetSourceOutputCode(name) + "};\n"; + string src = tex->GetSourceOutputCode(name); + + File::WriteAllText(outPath, src); + + delete tex; +} + +void BuildAssetBlob(string blobFilePath, string outPath) +{ + vector split = StringHelper::Split(outPath, "/"); + ZBlob* blob = ZBlob::FromFile(blobFilePath); + string name = StringHelper::Split(split[split.size() - 1], ".")[0]; + + //string src = StringHelper::Sprintf("u8 %s[] = \n{\n", name.c_str()) + blob->GetSourceOutputCode(name) + "};\n"; + string src = blob->GetSourceOutputCode(name); + + File::WriteAllText(outPath, src); + + delete blob; +} + +void BuildAssetModelIntermediette(string mdlPath, string outPath) +{ + XMLDocument doc; + XMLError eResult = doc.LoadFile(mdlPath.c_str()); + + vector split = StringHelper::Split(outPath, "/"); + HLModelIntermediette* mdl = HLModelIntermediette::FromXML(doc.RootElement()); + string output = mdl->OutputCode(); + + File::WriteAllText(outPath, output); + + delete mdl; +} + +void BuildAssetAnimationIntermediette(string animPath, string outPath) +{ + vector split = StringHelper::Split(outPath, "/"); + ZFile* file = new ZFile("", split[split.size() - 2]); + HLAnimationIntermediette* anim = HLAnimationIntermediette::FromXML(animPath); + ZAnimation* zAnim = anim->ToZAnimation(); + zAnim->SetName(Path::GetFileNameWithoutExtension(split[split.size() - 1])); + zAnim->parent = file; + //zAnim->rotationIndicesSeg = 1; + //zAnim->rotationValuesSeg = 2; + + zAnim->GetSourceOutputCode(split[split.size() - 2]); + string output = ""; + + output += file->declarations[2]->text + "\n"; + output += file->declarations[1]->text + "\n"; + output += file->declarations[0]->text + "\n"; + + File::WriteAllText(outPath, output); + + delete zAnim; + delete file; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/Overlays/ZOverlay.cpp b/tools/ZAPD/ZAPD/Overlays/ZOverlay.cpp new file mode 100644 index 0000000000..69a6b2d5af --- /dev/null +++ b/tools/ZAPD/ZAPD/Overlays/ZOverlay.cpp @@ -0,0 +1,231 @@ +#include "ZOverlay.h" +#include "../File.h" +#include "../Path.h" +#include "../Directory.h" +#include "../StringHelper.h" + +using namespace std; +using namespace ELFIO; + +ZOverlay::ZOverlay() +{ + name = ""; + entries = vector(); +} + +ZOverlay::ZOverlay(string nName) : ZOverlay() +{ + name = nName; +} + +ZOverlay::~ZOverlay() +{ + for (auto entry: entries) + if (entry) + delete entry; + entries.clear(); +} + +ZOverlay* ZOverlay::FromBuild(string buildPath, string cfgFolderPath) +{ + string cfgText = File::ReadAllText(cfgFolderPath + "/overlay.cfg"); + vector cfgLines = StringHelper::Split(cfgText, "\n"); + + ZOverlay* ovl = new ZOverlay(StringHelper::Strip(cfgLines[0], "\r")); + + vector relSections = {".rel.text", ".rel.data" , ".rel.rodata"}; + vector sections = {".text", ".data" , ".rodata"}; + + int sectionOffs[5] = {0}; + vector textRelocs; + vector dataRelocs; + vector rodataRelocs; + + + // get the elf files + vector readers; + for (int i = 1; i < cfgLines.size(); i++) + { + string elfPath = buildPath + "/" + cfgLines[i].substr(0, cfgLines[i].size()-2) + ".o"; + elfio* reader = new elfio(); + + if (!reader->load(elfPath)) + { + // not all files were compiled + for (auto r: readers) + delete r; + readers.clear(); + + delete ovl; + return nullptr; + } + + readers.push_back(reader); + } + + for (auto curReader : readers) + { + Elf_Half sec_num = curReader->sections.size(); + for(int i = 0; i < sec_num; i++) + { + section* pSec = curReader->sections[i]; + + if (pSec->get_type() == SHT_REL && std::find(relSections.begin(), relSections.end(), pSec->get_name()) != relSections.end()) + { + SectionType sectionType = GetSectionTypeFromStr(pSec->get_name()); + + if (sectionType == SectionType::ERROR) + printf("WARNING: One of the section types returned ERROR\n"); + + relocation_section_accessor relocs(*curReader, pSec); + for (Elf_Xword j = 0; j < relocs.get_entries_num(); j++) + { + Elf64_Addr offset; + Elf_Word symbol; + Elf_Word type; + { + Elf_Sxword addend; + relocs.get_entry(j, offset, symbol, type, addend); + } + + string curSymName; + Elf_Half curSymShndx = SHN_UNDEF; + { + symbol_section_accessor symbols(*curReader, curReader->sections[(Elf_Half)pSec->get_link()]); + Elf64_Addr value; + Elf_Xword size; + unsigned char bind; + unsigned char type; + unsigned char other; + symbols.get_symbol(symbol, curSymName, value, size, bind, type, curSymShndx, other); + } + + + // check symbols outside the elf but within the overlay + if (curSymShndx == SHN_UNDEF) + { + for (auto reader : readers) + { + if (curSymShndx != SHN_UNDEF) + break; + + if (reader == curReader) + continue; + + auto sectionData = reader->sections[(Elf_Half)pSec->get_link()]; + + if (sectionData == nullptr) + continue; + + symbol_section_accessor symbols(*reader, sectionData); + + for (Elf_Xword symIdx = 0; symIdx < symbols.get_symbols_num(); symIdx++) + { + Elf_Half shndx = SHN_UNDEF; + Elf64_Addr value; + string name; + Elf_Xword size; + unsigned char bind; + unsigned char type; + unsigned char other; + + symbols.get_symbol(symIdx, name, value, size, bind, type, shndx, other); + + if (name == curSymName) + { + curSymShndx = shndx; + break; + } + } + } + } + + if (curSymShndx != SHN_UNDEF) + { + RelocationType typeConverted = (RelocationType)type; + offset += sectionOffs[sectionType]; + + RelocationEntry* reloc = new RelocationEntry(sectionType, typeConverted, offset); + + // this is to keep the correct reloc entry order + if (sectionType == SectionType::Text) + textRelocs.push_back(reloc); + if (sectionType == SectionType::Data) + dataRelocs.push_back(reloc); + if (sectionType == SectionType::RoData) + rodataRelocs.push_back(reloc); + } + } + } + } + + // increase section offsets + for (int i = 0; i < sec_num; i++) + { + section* pSec = curReader->sections[i]; + if (pSec->get_type() == SHT_PROGBITS && std::find(sections.begin(), sections.end(), pSec->get_name()) != sections.end()) + { + SectionType sectionType = GetSectionTypeFromStr(pSec->get_name()); + sectionOffs[sectionType] += pSec->get_size(); + } + } + } + + for (auto reloc : textRelocs) + ovl->entries.push_back(reloc); + for (auto reloc : dataRelocs) + ovl->entries.push_back(reloc); + for (auto reloc : rodataRelocs) + ovl->entries.push_back(reloc); + + for (auto r: readers) + delete r; + readers.clear(); + + return ovl; +} + +string ZOverlay::GetSourceOutputCode(std::string prefix) +{ + string output = ""; + + output += ".section .ovl\n"; + + output += StringHelper::Sprintf(".word _%sSegmentTextSize\n", name.c_str()); + output += StringHelper::Sprintf(".word _%sSegmentDataSize\n", name.c_str()); + output += StringHelper::Sprintf(".word _%sSegmentRoDataSize\n", name.c_str()); + output += StringHelper::Sprintf(".word _%sSegmentBssSize\n", name.c_str()); + + output += StringHelper::Sprintf(".word %i\n", entries.size()); + + for (int i = 0; i < entries.size(); i++) + { + RelocationEntry* reloc = entries[i]; + output += StringHelper::Sprintf(".word 0x%08X\n", reloc->CalcRelocationWord()); + } + + int offset = ((int)entries.size() * 4) + 20; + + while (offset % 16 != 12) + { + output += ".word 0\n"; + offset += 4; + } + + output += StringHelper::Sprintf(".word 0x%08X\n", offset + 4); + return output; +} + +SectionType ZOverlay::GetSectionTypeFromStr(string sectionName) +{ + if (sectionName == ".rel.text" || sectionName == ".text") + return SectionType::Text; + else if (sectionName == ".rel.data" || sectionName == ".data") + return SectionType::Data; + else if (sectionName == ".rel.rodata" || sectionName == ".rodata" || sectionName == ".rodata.str1.4" || sectionName == ".rodata.cst4") + return SectionType::RoData; + else if (sectionName == ".rel.bss" || sectionName == ".bss") + return SectionType::Bss; + + return SectionType::ERROR; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/Overlays/ZOverlay.h b/tools/ZAPD/ZAPD/Overlays/ZOverlay.h new file mode 100644 index 0000000000..e76d902af2 --- /dev/null +++ b/tools/ZAPD/ZAPD/Overlays/ZOverlay.h @@ -0,0 +1,67 @@ +#pragma once + +#include "../ZResource.h" +#include "../tinyxml2.h" +#include + +enum SectionType +{ + Text = 1, + Data = 2, + RoData = 3, + Bss = 4, + ERROR = 255 +}; + +enum RelocationType +{ + R_MIPS_32 = 2, + R_MIPS_26 = 4, + R_MIPS_HI16 = 5, + R_MIPS_LO16 = 6, +}; + +class RelocationEntry +{ +public: + SectionType sectionType; + RelocationType relocationType; + int32_t offset; + + RelocationEntry(SectionType nSecType, RelocationType nRelType, int32_t nOffset) + { + sectionType = nSecType; + relocationType = nRelType; + offset = nOffset; + } + + uint32_t CalcRelocationWord() + { + uint32_t relocationWord = 0; + + relocationWord |= sectionType << 30; + relocationWord |= relocationType << 24; + relocationWord |= offset; + + return relocationWord; + } +}; + +class ZOverlay : public ZResource +{ +public: + std::string name; + + ZOverlay(std::string nName); + ~ZOverlay(); + static ZOverlay* FromBuild(std::string buildPath, std::string cfgFolderPath); + std::string GetSourceOutputCode(std::string prefix); + +private: + std::vector entries; + + ZOverlay(); + + static SectionType GetSectionTypeFromStr(std::string sectionName); + //static std::string GetOverlayNameFromElf(ELFIO::elfio& reader); +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/Path.h b/tools/ZAPD/ZAPD/Path.h new file mode 100644 index 0000000000..0f15c6f347 --- /dev/null +++ b/tools/ZAPD/ZAPD/Path.h @@ -0,0 +1,47 @@ +#pragma once + +#include +#include +#include "StringHelper.h" + +#if defined(_MSC_VER) || defined(__clang__) +#include +namespace fs = std::filesystem; +#else +#include +namespace fs = std::experimental::filesystem; +#endif + +class Path +{ +public: + static std::string GetFileNameWithoutExtension(std::string input) + { + std::vector split = StringHelper::Split(input, "/"); + return split[split.size() - 1].substr(0, input.find_last_of(".")); + }; + + static std::string GetFileNameExtension(std::string input) + { + return input.substr(input.find_last_of("."), input.length()); + }; + + static std::string GetPath(std::string input) + { + std::vector split = StringHelper::Split(input, "/"); + std::string output = ""; + + for (std::string str : split) + { + if (str.find_last_of(".") == std::string::npos) + output += str + "/"; + } + + return output; + }; + + static std::string GetDirectoryName(std::string path) + { + return fs::path(path).parent_path().u8string(); + }; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/StringHelper.h b/tools/ZAPD/ZAPD/StringHelper.h new file mode 100644 index 0000000000..f2cc95a17d --- /dev/null +++ b/tools/ZAPD/ZAPD/StringHelper.h @@ -0,0 +1,75 @@ +#pragma once + +#include +#include +#include +#include + +class StringHelper +{ +public: + static std::vector Split(std::string s, std::string delimiter) + { + std::vector result; + + size_t pos = 0; + std::string token; + + while ((pos = s.find(delimiter)) != std::string::npos) + { + token = s.substr(0, pos); + result.push_back(token); + s.erase(0, pos + delimiter.length()); + } + + if (s.length() != 0) + result.push_back(s); + + return result; + } + + static std::string Strip(std::string s, std::string delimiter) + { + size_t pos = 0; + std::string token; + + while ((pos = s.find(delimiter)) != std::string::npos) + { + token = s.substr(0, pos); + s.erase(pos, pos + delimiter.length()); + } + + return s; + } + + static bool StartsWith(std::string s, std::string input) + { + return s.rfind(input, 0) == 0; + } + + static bool Contains(std::string s, std::string input) + { + return s.find(input) != std::string::npos; + } + + static bool EndsWith(std::string s, std::string input) + { + int inputLen = strlen(input.c_str()); + return s.rfind(input) == (s.size() - inputLen); + } + + static std::string Sprintf(const char* format, ...) + { + char buffer[32768]; + //char buffer[2048]; + std::string output = ""; + va_list va; + + va_start(va, format); + vsprintf(buffer, format, va); + va_end(va); + + output = buffer; + return output; + } +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/Vec3s.h b/tools/ZAPD/ZAPD/Vec3s.h new file mode 100644 index 0000000000..589b660b05 --- /dev/null +++ b/tools/ZAPD/ZAPD/Vec3s.h @@ -0,0 +1,10 @@ +#pragma once + +#include + +struct Vec3s +{ + int16_t x, y, z; + + Vec3s(int16_t nX, int16_t nY, int16_t nZ) { x = nX; y = nY; z = nZ; }; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZAPD.vcxproj b/tools/ZAPD/ZAPD/ZAPD.vcxproj new file mode 100644 index 0000000000..c7edd1bc8f --- /dev/null +++ b/tools/ZAPD/ZAPD/ZAPD.vcxproj @@ -0,0 +1,269 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36} + ZAPD + 10.0 + ZAPD + + + + Application + true + v142 + MultiByte + + + Application + false + v142 + true + MultiByte + + + Application + true + v142 + MultiByte + + + Application + false + v142 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + $(ProjectDir)sqlite;$(ProjectDir);$(IncludePath) + $(ProjectDir)Libs;$(LibraryPath) + + + $(IncludePath) + + + + Level3 + Disabled + true + true + stdcpp17 + + + true + + + + + Level3 + Disabled + true + true + stdcpp17 + _CRT_SECURE_NO_WARNINGS;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;USE_ASSIMP;%(PreprocessorDefinitions) + EnableFastChecks + + + true + assimp-vc142-mt.lib;%(AdditionalDependencies) + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + stdcpplatest + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + Document + + + + + \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZAPD.vcxproj.filters b/tools/ZAPD/ZAPD/ZAPD.vcxproj.filters new file mode 100644 index 0000000000..095a9a20cd --- /dev/null +++ b/tools/ZAPD/ZAPD/ZAPD.vcxproj.filters @@ -0,0 +1,424 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {c5d86b0a-fff0-47cf-83af-807dd8267ad1} + + + {02148456-5068-4613-8478-f10addc58e70} + + + {bcab3136-95ba-4839-833c-43d78ad6e335} + + + {dc06ed84-f6fe-4277-80f3-d62bd5cdbb98} + + + {6049c045-bc38-4221-b29e-ca6d4d8af4aa} + + + {490e3a08-047b-48d3-ab53-3a860a3b92aa} + + + {26c06845-8e8e-4b79-ad18-07c4f9c0f801} + + + {d45c420d-2378-47ac-92c5-80db9475c195} + + + {03cc56a2-e0e8-4167-80a0-98fb900a959a} + + + {73db0879-6df8-4f6a-8cc2-a1f836e9e796} + + + {9464ff21-96af-4b7d-a57b-f62bd9b7389a} + + + {e9865c34-fd69-413c-8cce-3f51331c3503} + + + {0f9980bb-ae46-4891-a39e-275bf255f010} + + + {11dbd8e6-d97a-42a5-b40c-e1350389544d} + + + {be9a5be0-ec6a-4200-8e39-bb58c7da7aa8} + + + + + Source Files + + + Source Files\Z64\ZRoom + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Libraries + + + Source Files\Z64 + + + Source Files\Z64 + + + Source Files\Z64 + + + Source Files\Z64 + + + Source Files\Z64 + + + Source Files\Z64 + + + Source Files\Z64 + + + Source Files\Z64 + + + Source Files\HighLevel + + + Source Files\HighLevel + + + Source Files\HighLevel + + + Source Files\Z64 + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64 + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files\Z64\ZRoom + + + Header Files\Z64\ZRoom + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Libraries\elfio + + + Header Files\Libraries\elfio + + + Header Files\Libraries\elfio + + + Header Files\Libraries\elfio + + + Header Files\Libraries\elfio + + + Header Files\Libraries\elfio + + + Header Files\Libraries\elfio + + + Header Files\Libraries\elfio + + + Header Files\Libraries\elfio + + + Header Files\Libraries\elfio + + + Header Files\Libraries\elfio + + + Header Files\Libraries\elfio + + + Header Files + + + Header Files + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom + + + Header Files\Z64\ZRoom + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files + + + Header Files\OpenFBX + + + Header Files\OpenFBX + + + Header Files\Libraries + + + Header Files\Libraries + + + Header Files\Libraries + + + Header Files\Libraries + + + Header Files\Libraries + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files\HighLevel + + + Header Files\HighLevel + + + Header Files\HighLevel + + + Header Files\HighLevel + + + Header Files\Z64 + + + Header Files\HighLevel + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Libraries + + + Header Files\Z64 + + + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZAnimation.cpp b/tools/ZAPD/ZAPD/ZAnimation.cpp new file mode 100644 index 0000000000..91bd7ee44c --- /dev/null +++ b/tools/ZAPD/ZAPD/ZAnimation.cpp @@ -0,0 +1,184 @@ +#include "ZAnimation.h" +#include "ZFile.h" +#include "BitConverter.h" +#include "StringHelper.h" +#include "File.h" +#include "HighLevel/HLAnimationIntermediette.h" +#include "Globals.h" + +using namespace std; + +ZAnimation::ZAnimation() : ZResource() +{ + frameCount = 0; +} + +void ZAnimation::ParseRawData() +{ + uint8_t* data = rawData.data(); + + // Read the header + frameCount = BitConverter::ToInt16BE(data, rawDataIndex + 0); +} + +void ZAnimation::Save(string outFolder) +{ + if (Globals::Instance->testMode) + { + HLAnimationIntermediette* anim = HLAnimationIntermediette::FromZAnimation(this); + string xml = anim->OutputXML(); + File::WriteAllText(outFolder + "/" + name + ".anmi", xml); + + delete anim; + } +} + +void ZAnimation::ParseXML(tinyxml2::XMLElement* reader) +{ + ZResource::ParseXML(reader); + + name = reader->Attribute("Name"); +} + +string ZAnimation::GetSourceOutputCode(string prefix) +{ + return ""; +} + +ZNormalAnimation::ZNormalAnimation() : ZAnimation() +{ + rotationValues = vector(); + rotationIndices = vector(); + limit = 0; +} + +std::string ZNormalAnimation::GetSourceOutputCode(std::string prefix) +{ + if (parent != nullptr) + { + string defaultPrefix = name.c_str(); + defaultPrefix.replace(0, 1, "s"); // replace g prefix with s for local variables + + string headerStr = StringHelper::Sprintf("{ %i }, %sFrameData, %sJointIndices, %i", + frameCount, defaultPrefix.c_str(), defaultPrefix.c_str(), limit); + parent->declarations[rawDataIndex] = new Declaration(DeclarationAlignment::None, 16, "AnimationHeader", StringHelper::Sprintf("%s", name.c_str()), false, headerStr); + + string indicesStr = ""; + string valuesStr = " "; + const int lineLength = 14; + const int offset = 0; + + for (int i = 0; i < rotationValues.size(); i++) + { + valuesStr += StringHelper::Sprintf("0x%04X, ", rotationValues[i]); + + if ((i - offset + 1) % lineLength == 0) + valuesStr += "\n "; + } + + for (int i = 0; i < rotationIndices.size(); i++) + { + indicesStr += StringHelper::Sprintf(" { 0x%04X, 0x%04X, 0x%04X },", rotationIndices[i].x, rotationIndices[i].y, rotationIndices[i].z); + + if (i != (rotationIndices.size() - 1)) + indicesStr += "\n"; + } + + parent->AddDeclarationArray(rotationValuesSeg, DeclarationAlignment::Align16, (int)rotationValues.size() * 2, "static s16", + StringHelper::Sprintf("%sFrameData", defaultPrefix.c_str()), rotationValues.size(), valuesStr); + + parent->AddDeclarationArray(rotationIndicesSeg, DeclarationAlignment::Align16, (int)rotationIndices.size() * 6, "static JointIndex", + StringHelper::Sprintf("%sJointIndices", defaultPrefix.c_str()), rotationIndices.size(), indicesStr); + } + + return ""; +} + +int ZNormalAnimation::GetRawDataSize() +{ + return 16; +} + +ZNormalAnimation* ZNormalAnimation::ExtractFromXML(tinyxml2::XMLElement* reader, std::vector nRawData, int rawDataIndex, std::string nRelPath) +{ + ZNormalAnimation* anim = new ZNormalAnimation(); + anim->rawData = nRawData; + anim->rawDataIndex = rawDataIndex; + anim->ParseXML(reader); + anim->ParseRawData(); + + return anim; +} + +void ZNormalAnimation::ParseRawData() +{ + ZAnimation::ParseRawData(); + + uint8_t* data = rawData.data(); + + rotationValuesSeg = BitConverter::ToInt32BE(data, rawDataIndex + 4) & 0x00FFFFFF; + rotationIndicesSeg = BitConverter::ToInt32BE(data, rawDataIndex + 8) & 0x00FFFFFF; + limit = BitConverter::ToInt16BE(data, rawDataIndex + 12); + + uint32_t currentPtr = rotationValuesSeg; + + // Read the Rotation Values + for (int i = 0; i < ((rotationIndicesSeg - rotationValuesSeg) / 2); i++) + { + rotationValues.push_back(BitConverter::ToInt16BE(data, currentPtr)); + currentPtr += 2; + } + + currentPtr = rotationIndicesSeg; + + // Read the Rotation Indices + for (int i = 0; i < ((rawDataIndex - rotationIndicesSeg) / 6); i++) + { + rotationIndices.push_back(RotationIndex(BitConverter::ToInt16BE(data, currentPtr), BitConverter::ToInt16BE(data, currentPtr + 2), BitConverter::ToInt16BE(data, currentPtr + 4))); + currentPtr += 6; + } +} + +ZLinkAnimation::ZLinkAnimation() : ZAnimation() +{ + segmentAddress = 0; +} + +std::string ZLinkAnimation::GetSourceOutputCode(std::string prefix) +{ + if (parent != nullptr) + { + string segSymbol = segmentAddress == 0 ? "NULL" : parent->GetDeclarationName(segmentAddress, StringHelper::Sprintf("%sSeg%06X", name.c_str(), segmentAddress)); + string headerStr = StringHelper::Sprintf("{ %i }, 0x%08X", + frameCount, segmentAddress); + parent->declarations[rawDataIndex] = new Declaration(DeclarationAlignment::None, 16, "LinkAnimationHeader", StringHelper::Sprintf("%s", name.c_str()), false, headerStr); + } + + return ""; +} + +int ZLinkAnimation::GetRawDataSize() +{ + return 8; +} + +ZLinkAnimation* ZLinkAnimation::ExtractFromXML(tinyxml2::XMLElement* reader, std::vector nRawData, int rawDataIndex, std::string nRelPath) +{ + ZLinkAnimation* anim = new ZLinkAnimation(); + anim->rawData = nRawData; + anim->rawDataIndex = rawDataIndex; + anim->ParseXML(reader); + anim->ParseRawData(); + + return anim; +} + +void ZLinkAnimation::ParseRawData() +{ + ZAnimation::ParseRawData(); + + uint8_t* data = rawData.data(); + + //segmentAddress = SEG2FILESPACE(BitConverter::ToInt32BE(data, rawDataIndex + 4)); + segmentAddress = (BitConverter::ToInt32BE(data, rawDataIndex + 4)); +} diff --git a/tools/ZAPD/ZAPD/ZAnimation.h b/tools/ZAPD/ZAPD/ZAnimation.h new file mode 100644 index 0000000000..db5847ffb3 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZAnimation.h @@ -0,0 +1,68 @@ +#pragma once + +#include +#include +#include +#include "ZResource.h" +#include "Vec3s.h" +#include "tinyxml2.h" + +struct RotationIndex +{ + //uint16_t transX, transY, transZ; + uint16_t x, y, z; + + RotationIndex(uint16_t nX, uint16_t nY, uint16_t nZ) { x = nX; y = nY; z = nZ; }; +}; + +class ZAnimation : public ZResource +{ +public: + + int16_t frameCount; + + ZAnimation(); + + std::string GetSourceOutputCode(std::string prefix); +protected: + + virtual void ParseRawData(); + void Save(std::string outFolder); + void ParseXML(tinyxml2::XMLElement* reader); +}; + +class ZNormalAnimation : public ZAnimation +{ +public: + std::vector rotationValues; + std::vector rotationIndices; + uint32_t rotationValuesSeg; + uint32_t rotationIndicesSeg; + int16_t limit; + + ZNormalAnimation(); + + std::string GetSourceOutputCode(std::string prefix); + virtual int GetRawDataSize(); + + static ZNormalAnimation* ExtractFromXML(tinyxml2::XMLElement* reader, std::vector nRawData, int rawDataIndex, std::string nRelPath); + +protected: + virtual void ParseRawData(); +}; + +class ZLinkAnimation : public ZAnimation +{ +public: + uint32_t segmentAddress; + + ZLinkAnimation(); + + std::string GetSourceOutputCode(std::string prefix); + virtual int GetRawDataSize(); + + static ZLinkAnimation* ExtractFromXML(tinyxml2::XMLElement* reader, std::vector nRawData, int rawDataIndex, std::string nRelPath); + +protected: + virtual void ParseRawData(); +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZBlob.cpp b/tools/ZAPD/ZAPD/ZBlob.cpp new file mode 100644 index 0000000000..eee80987d3 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZBlob.cpp @@ -0,0 +1,104 @@ +#include "ZBlob.h" +#include "File.h" +#include "ZFile.h" +#include "BitConverter.h" +#include "Path.h" +#include "StringHelper.h" + +using namespace tinyxml2; +using namespace std; + +ZBlob::ZBlob() : ZResource() +{ + +} + +ZBlob::ZBlob(std::vector nRawData, int nRawDataIndex, int size, std::string nName) : ZBlob() +{ + rawDataIndex = nRawDataIndex; + rawData = vector(nRawData.data() + rawDataIndex, nRawData.data() + rawDataIndex + size); + name = nName; +} + +ZBlob* ZBlob::ExtractFromXML(XMLElement* reader, vector nRawData, int nRawDataIndex, string nRelPath) +{ + ZBlob* blob = new ZBlob(); + + blob->rawDataIndex = nRawDataIndex; + + blob->ParseXML(reader); + int size = strtol(reader->Attribute("Size"), NULL, 16); + blob->rawData = vector(nRawData.data() + blob->rawDataIndex, nRawData.data() + blob->rawDataIndex + size); + blob->relativePath = nRelPath; + + return blob; +} + +ZBlob* ZBlob::BuildFromXML(XMLElement* reader, string inFolder, bool readFile) +{ + ZBlob* blob = new ZBlob(); + + blob->ParseXML(reader); + + if (readFile) + blob->rawData = File::ReadAllBytes(inFolder + "/" + blob->name + ".bin"); + + return blob; +} + +ZBlob* ZBlob::FromFile(string filePath) +{ + int comp; + ZBlob* blob = new ZBlob(); + blob->name = StringHelper::Split(Path::GetFileNameWithoutExtension(filePath), ".")[0]; + blob->rawData = File::ReadAllBytes(filePath); + + return blob; +} + +string ZBlob::GetSourceOutputCode(std::string prefix) +{ + sourceOutput = ""; + //sourceOutput += StringHelper::Sprintf("u8 %s_%s[] = \n{\n", prefix.c_str(), name.c_str()); + + for (int i = 0; i < rawData.size(); i += 1) + { + if (i % 16 == 0) + sourceOutput += "\t"; + + sourceOutput += StringHelper::Sprintf("0x%02X, ", rawData[i]); + + if (i % 16 == 15) + sourceOutput += "\n"; + } + + //sourceOutput += "};\n"; + + return sourceOutput; +} + +string ZBlob::GetSourceOutputHeader(std::string prefix) +{ + return StringHelper::Sprintf("extern u8 %s[];\n", name.c_str()); +} + +void ZBlob::Save(string outFolder) +{ + //printf("NAME = %s\n", name.c_str()); + File::WriteAllBytes(outFolder + "/" + name + ".bin", rawData); +} + +bool ZBlob::IsExternalResource() +{ + return true; +} + +string ZBlob::GetExternalExtension() +{ + return "bin"; +} + +ZResourceType ZBlob::GetResourceType() +{ + return ZResourceType::Blob; +} diff --git a/tools/ZAPD/ZAPD/ZBlob.h b/tools/ZAPD/ZAPD/ZBlob.h new file mode 100644 index 0000000000..c7ba16c978 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZBlob.h @@ -0,0 +1,23 @@ +#pragma once + +#include "ZResource.h" +#include "tinyxml2.h" + +class ZBlob : public ZResource +{ +public: + ZBlob(std::vector nRawData, int rawDataIndex, int size, std::string nName); + + static ZBlob* ExtractFromXML(tinyxml2::XMLElement* reader, std::vector nRawData, int rawDataIndex, std::string nRelPath); + static ZBlob* BuildFromXML(tinyxml2::XMLElement* reader, std::string inFolder, bool readFile); + static ZBlob* FromFile(std::string filePath); + std::string GetSourceOutputCode(std::string prefix); + std::string GetSourceOutputHeader(std::string prefix); + void Save(std::string outFolder); + bool IsExternalResource(); + std::string GetExternalExtension(); + ZResourceType GetResourceType(); + +private: + ZBlob(); +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZCollision.cpp b/tools/ZAPD/ZAPD/ZCollision.cpp new file mode 100644 index 0000000000..2247c9c05f --- /dev/null +++ b/tools/ZAPD/ZAPD/ZCollision.cpp @@ -0,0 +1,275 @@ +#include "ZCollision.h" +#include "BitConverter.h" +#include "StringHelper.h" +#include +#include + +using namespace std; + +ZCollisionHeader::ZCollisionHeader() +{ + +} + +ZCollisionHeader::ZCollisionHeader(ZFile* parent, std::string prefix, std::vector rawData, int rawDataIndex) +{ + uint8_t* data = rawData.data(); + + absMinX = BitConverter::ToInt16BE(data, rawDataIndex + 0); + absMinY = BitConverter::ToInt16BE(data, rawDataIndex + 2); + absMinZ = BitConverter::ToInt16BE(data, rawDataIndex + 4); + + absMaxX = BitConverter::ToInt16BE(data, rawDataIndex + 6); + absMaxY = BitConverter::ToInt16BE(data, rawDataIndex + 8); + absMaxZ = BitConverter::ToInt16BE(data, rawDataIndex + 10); + + numVerts = BitConverter::ToInt16BE(data, rawDataIndex + 12); + vtxSegmentOffset = BitConverter::ToInt32BE(data, rawDataIndex + 16) & 0x00FFFFFF; + + numPolygons = BitConverter::ToInt16BE(data, rawDataIndex + 20); + polySegmentOffset = BitConverter::ToInt32BE(data, rawDataIndex + 24) & 0x00FFFFFF; + polyTypeDefSegmentOffset = BitConverter::ToInt32BE(data, rawDataIndex + 28) & 0x00FFFFFF; + camDataSegmentOffset = BitConverter::ToInt32BE(data, rawDataIndex + 32) & 0x00FFFFFF; + + numWaterBoxes = BitConverter::ToInt16BE(data, rawDataIndex + 36); + waterBoxSegmentOffset = BitConverter::ToInt32BE(data, rawDataIndex + 40) & 0x00FFFFFF; + + // HOTSPOT + for (int i = 0; i < numVerts; i++) + vertices.push_back(new VertexEntry(rawData, vtxSegmentOffset + (i * 6))); + + // HOTSPOT + for (int i = 0; i < numPolygons; i++) + polygons.push_back(new PolygonEntry(rawData, polySegmentOffset + (i * 16))); + + int highestPolyType = 0; + + for (PolygonEntry* poly : polygons) + { + if (poly->type > highestPolyType) + highestPolyType = poly->type; + } + + //if (highestPolyType > 0) + { + for (int i = 0; i < highestPolyType + 1; i++) + polygonTypes.push_back(BitConverter::ToInt64BE(data, polyTypeDefSegmentOffset + (i * 8))); + } + //else + //{ + //int polyTypesSize = abs(polyTypeDefSegmentOffset - camDataSegmentOffset) / 8; + + //for (int i = 0; i < polyTypesSize; i++) + //polygonTypes.push_back(BitConverter::ToInt64BE(data, polyTypeDefSegmentOffset + (i * 8))); + //} + + if (camDataSegmentOffset != 0) + camData = new CameraDataList(parent, prefix, rawData, camDataSegmentOffset, polyTypeDefSegmentOffset, polygonTypes.size()); + + for (int i = 0; i < numWaterBoxes; i++) + waterBoxes.push_back(new WaterBoxHeader(rawData, waterBoxSegmentOffset + (i * 16))); + + string declaration = ""; + char line[2048]; + + if (waterBoxes.size() > 0) + { + for (int i = 0; i < waterBoxes.size(); i++) + { + sprintf(line, "\t{ %i, %i, %i, %i, %i, 0x%08X },\n", waterBoxes[i]->xMin, waterBoxes[i]->ySurface, waterBoxes[i]->zMin, waterBoxes[i]->xLength, waterBoxes[i]->zLength, waterBoxes[i]->properties); + declaration += line; + } + } + + if (waterBoxSegmentOffset != 0) + parent->declarations[waterBoxSegmentOffset] = new Declaration(DeclarationAlignment::None, 16 * waterBoxes.size(), "WaterBox", + StringHelper::Sprintf("%s_waterBoxes_%08X", prefix.c_str(), waterBoxSegmentOffset), true, declaration); + + if (polygons.size() > 0) + { + declaration = ""; + + for (int i = 0; i < polygons.size(); i++) + { + sprintf(line, "\t{ 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X }, // 0x%08X\n", + (uint16_t)polygons[i]->type, (uint16_t)polygons[i]->vtxA, (uint16_t)polygons[i]->vtxB, (uint16_t)polygons[i]->vtxC, + (uint16_t)polygons[i]->a, (uint16_t)polygons[i]->b, (uint16_t)polygons[i]->c, (uint16_t)polygons[i]->d, polySegmentOffset + (i * 16)); + declaration += line; + } + + if (polySegmentOffset != 0) { + parent->declarations[polySegmentOffset] = new Declaration(DeclarationAlignment::None, polygons.size() * 16, "RoomPoly", // TODO: Change this to CollisionPoly once the struct has been updated + StringHelper::Sprintf("%s_polygons_%08X", prefix.c_str(), polySegmentOffset), true, declaration); + } + } + + declaration = ""; + for (int i = 0; i < polygonTypes.size(); i++) + { + sprintf(line, "\t 0x%08lX, 0x%08lX, \n", polygonTypes[i] >> 32, polygonTypes[i] & 0xFFFFFFFF); + declaration += line; + } + + if (polyTypeDefSegmentOffset != 0) + parent->declarations[polyTypeDefSegmentOffset] = new Declaration(DeclarationAlignment::None, polygonTypes.size() * 8, + "u32", StringHelper::Sprintf("%s_polygonTypes_%08X", prefix.c_str(), polyTypeDefSegmentOffset), true, declaration); + + declaration = ""; + + if (vertices.size() > 0) + { + declaration = ""; + + for (int i = 0; i < vertices.size(); i++) + { + + sprintf(line, "{ %i, %i, %i }, // 0x%08X\n", vertices[i]->x, vertices[i]->y, vertices[i]->z, vtxSegmentOffset + (i * 6)); + declaration += line; + } + + if (vtxSegmentOffset != 0) + parent->declarations[vtxSegmentOffset] = new Declaration(DeclarationAlignment::None, vertices.size() * 6, + "Vec3s", StringHelper::Sprintf("%s_vtx_%08X", prefix.c_str(), vtxSegmentOffset), true, declaration); + + declaration = ""; + } + + declaration = ""; + char waterBoxStr[2048]; + + if (waterBoxSegmentOffset != 0) + sprintf(waterBoxStr, "%s_waterBoxes_%08X", prefix.c_str(), waterBoxSegmentOffset); + else + sprintf(waterBoxStr, "0"); + + declaration += StringHelper::Sprintf("%i, %i, %i, %i, %i, %i, %i, %s_vtx_%08X, %i, %s_polygons_%08X, %s_polygonTypes_%08X, &%s_camDataList_%08X, %i, %s", + absMinX, absMinY, absMinZ, + absMaxX, absMaxY, absMaxZ, + numVerts, prefix.c_str(), vtxSegmentOffset, numPolygons, + prefix.c_str(), polySegmentOffset, prefix.c_str(), polyTypeDefSegmentOffset, + prefix.c_str(), camDataSegmentOffset, numWaterBoxes, waterBoxStr); + + + /*parent->AddDeclaration(rawDataIndex, DeclarationAlignment::None, DeclarationPadding::Pad16, 44, "CollisionHeader", + StringHelper::Sprintf("%s_collisionHeader_%08X", prefix.c_str(), rawDataIndex), declaration);*/ + + parent->AddDeclaration(rawDataIndex, DeclarationAlignment::None, DeclarationPadding::Pad16, 44, "CollisionHeader", + StringHelper::Sprintf("%s", prefix.c_str(), rawDataIndex), declaration); +} + +ZCollisionHeader* ZCollisionHeader::ExtractFromXML(tinyxml2::XMLElement* reader, vector nRawData, int rawDataIndex) +{ + ZCollisionHeader* col = new ZCollisionHeader(); + + + + return col; +} + +PolygonEntry::PolygonEntry(std::vector rawData, int rawDataIndex) +{ + uint8_t* data = rawData.data(); + + type = BitConverter::ToInt16BE(data, rawDataIndex + 0); + vtxA = BitConverter::ToInt16BE(data, rawDataIndex + 2); + vtxB = BitConverter::ToInt16BE(data, rawDataIndex + 4); + vtxC = BitConverter::ToInt16BE(data, rawDataIndex + 6); + a = BitConverter::ToInt16BE(data, rawDataIndex + 8); + b = BitConverter::ToInt16BE(data, rawDataIndex + 10); + c = BitConverter::ToInt16BE(data, rawDataIndex + 12); + d = BitConverter::ToInt16BE(data, rawDataIndex + 14); +} + +VertexEntry::VertexEntry(std::vector rawData, int rawDataIndex) +{ + uint8_t* data = rawData.data(); + + x = BitConverter::ToInt16BE(data, rawDataIndex + 0); + y = BitConverter::ToInt16BE(data, rawDataIndex + 2); + z = BitConverter::ToInt16BE(data, rawDataIndex + 4); +} + +WaterBoxHeader::WaterBoxHeader(std::vector rawData, int rawDataIndex) +{ + uint8_t* data = rawData.data(); + + xMin = BitConverter::ToInt16BE(data, rawDataIndex + 0); + ySurface = BitConverter::ToInt16BE(data, rawDataIndex + 2); + zMin = BitConverter::ToInt16BE(data, rawDataIndex + 4); + xLength = BitConverter::ToInt16BE(data, rawDataIndex + 6); + zLength = BitConverter::ToInt16BE(data, rawDataIndex + 8); + properties = BitConverter::ToInt32BE(data, rawDataIndex + 12); +} + +CameraDataList::CameraDataList(ZFile* parent, std::string prefix, std::vector rawData, int rawDataIndex, int polyTypeDefSegmentOffset, int polygonTypesCnt) +{ + string declaration = ""; + + // Parse CameraDataEntries + int numElements = abs(polyTypeDefSegmentOffset - (rawDataIndex)) / 8; + //int numElements = polygonTypesCnt; + uint32_t cameraPosDataSeg = rawDataIndex; + for (int i = 0; i < numElements; i++) + { + CameraDataEntry* entry = new CameraDataEntry(); + + entry->cameraSType = BitConverter::ToInt16BE(rawData, rawDataIndex + (entries.size() * 8) + 0); + entry->numData = BitConverter::ToInt16BE(rawData, rawDataIndex + (entries.size() * 8) + 2); + entry->cameraPosDataSeg = BitConverter::ToInt32BE(rawData, rawDataIndex + (entries.size() * 8) + 4); + + if (entry->cameraPosDataSeg != 0 && GETSEGNUM(entry->cameraPosDataSeg) != 2) + { + cameraPosDataSeg = rawDataIndex + (entries.size() * 8); + break; + } + + if (entry->cameraPosDataSeg != 0 && cameraPosDataSeg > (entry->cameraPosDataSeg & 0xFFFFFF)) + cameraPosDataSeg = (entry->cameraPosDataSeg & 0xFFFFFF); + + entries.push_back(entry); + } + + //setting cameraPosDataAddr to rawDataIndex give a pos list length of 0 + uint32_t cameraPosDataOffset = cameraPosDataSeg & 0xFFFFFF; + for (int i = 0; i < entries.size(); i++) + { + char camSegLine[2048]; + + if (entries[i]->cameraPosDataSeg != 0) + { + int index = ((entries[i]->cameraPosDataSeg & 0x00FFFFFF) - cameraPosDataOffset) / 0x6; + sprintf(camSegLine, "&%s_camPosData_%08X[%i]", prefix.c_str(), cameraPosDataOffset, index); + } + else + sprintf(camSegLine, "0x%08X", entries[i]->cameraPosDataSeg); + + declaration += StringHelper::Sprintf("\t{ 0x%04X, %i, %s }, // 0x%08X\n", entries[i]->cameraSType, entries[i]->numData, camSegLine, rawDataIndex + (i * 8)); + } + + parent->AddDeclarationArray(rawDataIndex, DeclarationAlignment::None, entries.size() * 8, "CamData", StringHelper::Sprintf("%s_camDataList_%08X", prefix.c_str(), rawDataIndex), entries.size(), declaration); + + int numDataTotal = abs(rawDataIndex - (int)cameraPosDataOffset) / 0x6; + + if (numDataTotal > 0) + { + declaration = ""; + for (int i = 0; i < numDataTotal; i++) + { + CameraPositionData* data = new CameraPositionData(rawData, cameraPosDataOffset + (i * 6)); + cameraPositionData.push_back(data); + + declaration += StringHelper::Sprintf("\t{ %6i, %6i, %6i }, // 0x%08X\n", data->x, data->y, data->z, cameraPosDataSeg + (i * 0x6));; + } + + int cameraPosDataIndex = cameraPosDataSeg & 0x00FFFFFF; + int entrySize = numDataTotal * 0x6; + parent->AddDeclarationArray(cameraPosDataIndex, DeclarationAlignment::None, entrySize, "Vec3s", StringHelper::Sprintf("%s_camPosData_%08X", prefix.c_str(), cameraPosDataIndex), numDataTotal, declaration); + } +} + +CameraPositionData::CameraPositionData(std::vector rawData, int rawDataIndex) +{ + x = BitConverter::ToInt16BE(rawData, rawDataIndex + 0); + y = BitConverter::ToInt16BE(rawData, rawDataIndex + 2); + z = BitConverter::ToInt16BE(rawData, rawDataIndex + 4); +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZCollision.h b/tools/ZAPD/ZAPD/ZCollision.h new file mode 100644 index 0000000000..b397b1e6d4 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZCollision.h @@ -0,0 +1,90 @@ +#pragma once + +#include "ZResource.h" +#include "ZFile.h" +#include "ZRoom/ZRoom.h" + +class PolygonEntry +{ +public: + int16_t type; + int16_t vtxA, vtxB, vtxC; + int16_t a, b, c, d; + + PolygonEntry(std::vector rawData, int rawDataIndex); +}; + +class VertexEntry +{ +public: + int16_t x, y, z; + + VertexEntry(std::vector rawData, int rawDataIndex); +}; + +class WaterBoxHeader +{ +public: + int16_t xMin; + int16_t ySurface; + int16_t zMin; + int16_t xLength; + int16_t zLength; + int16_t pad; + int32_t properties; + + WaterBoxHeader(std::vector rawData, int rawDataIndex); +}; + +class CameraPositionData +{ +public: + int16_t x, y, z; + + CameraPositionData(std::vector rawData, int rawDataIndex); +}; + +class CameraDataEntry +{ +public: + int16_t cameraSType; + int16_t numData; + int32_t cameraPosDataSeg; +}; + +class CameraDataList +{ +public: + std::vector entries; + std::vector cameraPositionData; + + CameraDataList(ZFile* parent, std::string prefix, std::vector rawData, int rawDataIndex, int polyTypeDefSegmentOffset, int polygonTypesCnt); +}; + +class ZCollisionHeader : public ZResource +{ +public: + int16_t absMinX, absMinY, absMinZ; + int16_t absMaxX, absMaxY, absMaxZ; + int16_t numVerts; + int32_t vtxSegmentOffset; + int16_t numPolygons; + int32_t polySegmentOffset; + int32_t polyTypeDefSegmentOffset; + int32_t camDataSegmentOffset; + + int32_t numWaterBoxes; + int32_t waterBoxSegmentOffset; + + std::vector vertices; + std::vector polygons; + std::vector polygonTypes; + std::vector waterBoxes; + CameraDataList* camData; + + ZCollisionHeader(); + //ZCollisionHeader(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + ZCollisionHeader(ZFile* parent, std::string prefix, std::vector rawData, int rawDataIndex); + + static ZCollisionHeader* ExtractFromXML(tinyxml2::XMLElement* reader, std::vector nRawData, int rawDataIndex); +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZCutscene.cpp b/tools/ZAPD/ZAPD/ZCutscene.cpp new file mode 100644 index 0000000000..3130771f6f --- /dev/null +++ b/tools/ZAPD/ZAPD/ZCutscene.cpp @@ -0,0 +1,901 @@ +#include "ZCutscene.h" +#include "BitConverter.h" +#include "StringHelper.h" + +using namespace std; + +ZCutscene::ZCutscene(std::vector nRawData, int rawDataIndex, int rawDataSize) +{ + rawData = nRawData; + segmentOffset = rawDataIndex; + + numCommands = BitConverter::ToInt32BE(rawData, rawDataIndex + 0); + commands = vector(); + + endFrame = BitConverter::ToInt32BE(rawData, rawDataIndex + 4); + uint32_t currentPtr = rawDataIndex + 8; + + for (int i = 0; i < numCommands; i++) + { + int id = BitConverter::ToInt32BE(rawData, currentPtr); + + if (id == -1) + break; + + CutsceneCommands cmdID = (CutsceneCommands)GetCommandFromID(id); + currentPtr += 4; + + int numEntries = 1; + + /*if (cmdID != CutsceneCommands::SetCameraPos && cmdID != CutsceneCommands::SetCameraFocus && cmdID != CutsceneCommands::SetCameraFocusLink && cmdID != CutsceneCommands::SetCameraPosLink) + { + numEntries = BitConverter::ToInt32BE(rawData, currentPtr); + currentPtr += 4; + }*/ + + for (int j = 0; j < numEntries; j++) + { + CutsceneCommand* cmd = nullptr; + + switch (cmdID) + { + case CutsceneCommands::SetCameraPos: cmd = new CutsceneCommandSetCameraPos(rawData, currentPtr); break; + case CutsceneCommands::SetCameraFocus: cmd = new CutsceneCommandSetCameraPos(rawData, currentPtr); break; + case CutsceneCommands::SpecialAction: cmd = new CutsceneCommandSpecialAction(rawData, currentPtr); break; + case CutsceneCommands::SetLighting: cmd = new CutsceneCommandEnvLighting(rawData, currentPtr); break; + case CutsceneCommands::SetCameraPosLink: cmd = new CutsceneCommandSetCameraPos(rawData, currentPtr); break; + case CutsceneCommands::SetCameraFocusLink: cmd = new CutsceneCommandSetCameraPos(rawData, currentPtr); break; + case CutsceneCommands::Textbox: cmd = new CutsceneCommandTextbox(rawData, currentPtr); break; + case CutsceneCommands::Cmd09: cmd = new CutsceneCommandUnknown9(rawData, currentPtr); break; + case CutsceneCommands::Unknown: cmd = new CutsceneCommandUnknown(rawData, currentPtr); break; + case CutsceneCommands::SetActorAction0: + case CutsceneCommands::SetActorAction1: + case CutsceneCommands::SetActorAction2: + case CutsceneCommands::SetActorAction3: + case CutsceneCommands::SetActorAction4: + case CutsceneCommands::SetActorAction5: + case CutsceneCommands::SetActorAction6: + case CutsceneCommands::SetActorAction7: + case CutsceneCommands::SetActorAction8: + case CutsceneCommands::SetActorAction9: + case CutsceneCommands::SetActorAction10: cmd = new CutsceneCommandActorAction(rawData, currentPtr); break; + case CutsceneCommands::SetSceneTransFX: cmd = new CutsceneCommandSceneTransFX(rawData, currentPtr); break; + case CutsceneCommands::Nop: cmd = new CutsceneCommandNop(rawData, currentPtr); break; + case CutsceneCommands::PlayBGM: cmd = new CutsceneCommandPlayBGM(rawData, currentPtr); break; + case CutsceneCommands::StopBGM: cmd = new CutsceneCommandStopBGM(rawData, currentPtr); break; + case CutsceneCommands::FadeBGM: cmd = new CutsceneCommandFadeBGM(rawData, currentPtr); break; + case CutsceneCommands::SetTime: cmd = new CutsceneCommandDayTime(rawData, currentPtr); break; + case CutsceneCommands::Terminator: cmd = new CutsceneCommandTerminator(rawData, currentPtr); break; + case CutsceneCommands::End: cmd = new CutsceneCommandEnd(rawData, currentPtr); break; + } + + cmd->commandIndex = i; + cmd->commandID = (uint32_t)id; + currentPtr += (uint32_t)cmd->GetCommandSize(); + + commands.push_back(cmd); + } + } +} + +string ZCutscene::GetSourceOutputCode(string prefix) +{ + string output = ""; + int size = 0; + int32_t curPtr = 0; + + //output += StringHelper::Sprintf("// SIZE = 0x%04X\n", GetRawDataSize()); + output += StringHelper::Sprintf("\tCS_BEGIN_CUTSCENE(%i, %i),\n", commands.size(), endFrame); + + for (int i = 0; i < commands.size(); i++) + { + CutsceneCommand* cmd = commands[i]; + output += "\t" + cmd->GenerateSourceCode(prefix, curPtr); + curPtr += (uint32_t)cmd->GetCommandSize(); + size += (int)cmd->GetCommandSize(); + } + + output += StringHelper::Sprintf("\tCS_END(),\n", commands.size(), endFrame); + + return output; +} + +int ZCutscene::GetRawDataSize() +{ + int size = 0; + + // Beginning + size += 8; + + for (int i = 0; i < commands.size(); i++) + { + CutsceneCommand* cmd = commands[i]; + size += (int)cmd->GetCommandSize(); + size += 4; + } + + // End + size += 8; + + return size; +} + +CutsceneCommands ZCutscene::GetCommandFromID(int id) +{ + switch (id) + { + case 0x0003: return CutsceneCommands::SpecialAction; + case 0x0004: return CutsceneCommands::SetLighting; + case 0x0056: return CutsceneCommands::PlayBGM; + case 0x0057: return CutsceneCommands::StopBGM; + case 0x007C: return CutsceneCommands::FadeBGM; + case 0x0009: return CutsceneCommands::Cmd09; + case 0x0013: return CutsceneCommands::Textbox; + case 0x008C: return CutsceneCommands::SetTime; + case 0x0001: return CutsceneCommands::SetCameraPos; + case 0x0002: return CutsceneCommands::SetCameraFocus; + case 0x0005: return CutsceneCommands::SetCameraPosLink; + case 0x0006: return CutsceneCommands::SetCameraFocusLink; + case 0x0007: return CutsceneCommands::Cmd07; + case 0x0008: return CutsceneCommands::Cmd08; + case 0x03E8: return CutsceneCommands::Terminator; + case 0xFFFF: return CutsceneCommands::End; + case 0x002D: return CutsceneCommands::SetSceneTransFX; + case 10: return CutsceneCommands::SetActorAction0; + case 15: case 17: case 18: case 23: case 34: case 39: case 46: case 76: case 85: case 93: case 105: case 107: case 110: case 119: case 123: case 138: case 139: case 144: return CutsceneCommands::SetActorAction1; + case 14: case 16: case 24: case 35: case 40: case 48: case 64: case 68: case 70: case 78: case 80: case 94: case 116: case 118: case 120: case 125: case 131: case 141: return CutsceneCommands::SetActorAction2; + case 25: case 36: case 41: case 50: case 67: case 69: case 72: case 81: case 106: case 117: case 121: case 126: case 132: return CutsceneCommands::SetActorAction3; + case 29: case 37: case 42: case 51: case 53: case 63: case 65: case 66: case 75: case 82: case 108: case 127: case 133: return CutsceneCommands::SetActorAction4; + case 30: case 38: case 43: case 47: case 54: case 79: case 83: case 128: case 135: return CutsceneCommands::SetActorAction5; + case 44: case 55: case 77: case 84: case 90: case 129: case 136: return CutsceneCommands::SetActorAction6; + case 31: case 52: case 57: case 58: case 88: case 115: case 130: case 137: return CutsceneCommands::SetActorAction7; + case 49: case 60: case 89: case 111: case 114: case 134: case 142: return CutsceneCommands::SetActorAction8; + case 62: return CutsceneCommands::SetActorAction9; + case 143: return CutsceneCommands::SetActorAction10; + case 0x0B: case 0x0D: case 0x1A: case 0x1B: case 0x1C: case 0x20: case 0x21: case 0x3B: case 0x3D: case 0x47: case 0x49: case 0x6D: case 0x15: case 0x16: case 0x70: case 0x71: case 0x4A: return CutsceneCommands::Unknown; + } + + printf("WARNING: Could not identify cutscene command ID 0x%04X\n", id); + + return CutsceneCommands::Error; +} + +CutsceneCommand::CutsceneCommand(vector rawData, int rawDataIndex) +{ + +} + +string CutsceneCommand::GetCName(string prefix) +{ + return "SCmdCutsceneData"; +} + +string CutsceneCommand::GenerateSourceCode(string roomName, int baseAddress) +{ + return StringHelper::Sprintf("%s %sCutsceneData%04XCmd%02X = { 0x%02X,", GetCName(roomName).c_str(), roomName.c_str(), baseAddress, commandIndex, commandID); +} + +size_t CutsceneCommand::GetCommandSize() +{ + return 4; +} + +CutsceneCameraPoint::CutsceneCameraPoint(vector rawData, int rawDataIndex) +{ + uint8_t* data = rawData.data(); + + continueFlag = data[rawDataIndex + 0]; + cameraRoll = data[rawDataIndex + 1]; + nextPointFrame = BitConverter::ToInt16BE(data, rawDataIndex + 2); + viewAngle = BitConverter::ToInt32BE(data, rawDataIndex + 4); + + posX = BitConverter::ToInt16BE(data, rawDataIndex + 8); + posY = BitConverter::ToInt16BE(data, rawDataIndex + 10); + posZ = BitConverter::ToInt16BE(data, rawDataIndex + 12); + + unused = BitConverter::ToInt16BE(data, rawDataIndex + 14); +} + +CutsceneCommandSetCameraPos::CutsceneCommandSetCameraPos(vector rawData, int rawDataIndex) : CutsceneCommand(rawData, rawDataIndex) +{ + uint8_t* data = rawData.data(); + + base = (uint16_t)BitConverter::ToInt16BE(data, rawDataIndex + 0); + startFrame = (uint16_t)BitConverter::ToInt16BE(data, rawDataIndex + 2); + endFrame = (uint16_t)BitConverter::ToInt16BE(data, rawDataIndex + 4); + unused = (uint16_t)BitConverter::ToInt16BE(data, rawDataIndex + 6); + + entries = vector(); + + bool shouldContinue = true; + + uint32_t currentPtr = rawDataIndex + 8; + + while (shouldContinue) + { + CutsceneCameraPoint* camPoint = new CutsceneCameraPoint(rawData, currentPtr); + entries.push_back(camPoint); + + if (camPoint->continueFlag == -1) + shouldContinue = false; + + currentPtr += 16; + } +} + +// TODO +string CutsceneCommandSetCameraPos::GetCName(string prefix) +{ + return ""; +} + +string CutsceneCommandSetCameraPos::GenerateSourceCode(string roomName, int baseAddress) +{ + string result = ""; + + string listStr = ""; + string posStr = ""; + + if (commandID == (int)CutsceneCommands::SetCameraFocus) + { + listStr = "CS_CAM_FOCUS_POINT_LIST"; + posStr = "CS_CAM_FOCUS_POINT"; + } + else if (commandID == (int)CutsceneCommands::SetCameraFocusLink) + { + listStr = "CS_CAM_FOCUS_POINT_PLAYER_LIST"; + posStr = "CS_CAM_FOCUS_POINT_PLAYER"; + } + else if (commandID == (int)CutsceneCommands::SetCameraPosLink) + { + listStr = "CS_CAM_POS_PLAYER_LIST"; + posStr = "CS_CAM_POS_PLAYER"; + } + else + { + listStr = "CS_CAM_POS_LIST"; + posStr = "CS_CAM_POS"; + } + + result += StringHelper::Sprintf("%s(%i, %i),\n", listStr.c_str(), startFrame, endFrame); + + for (int i = 0; i < entries.size(); i++) + { + result += StringHelper::Sprintf("\t\t%s(%i, %i, %i, 0x%06X, %i, %i, %i, %i),\n", posStr.c_str(), entries[i]->continueFlag, entries[i]->cameraRoll, entries[i]->nextPointFrame, + *(uint32_t*)&entries[i]->viewAngle, entries[i]->posX, entries[i]->posY, entries[i]->posZ, entries[i]->unused); + } + + return result; +} + +size_t CutsceneCommandSetCameraPos::GetCommandSize() +{ + return 8 + (entries.size() * 16); +} + +MusicFadeEntry::MusicFadeEntry(vector rawData, int rawDataIndex) +{ + base = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 0); + startFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 2); + endFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 4); + unknown0 = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 6); + unknown1 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 8); + unknown2 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 12); + unknown3 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 16); + unknown4 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 20); + unknown5 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 24); + unknown6 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 28); + unknown7 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 32); + unknown8 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 36); + unknown9 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 40); + unknown10 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 44); +} + +CutsceneCommandFadeBGM::CutsceneCommandFadeBGM(vector rawData, int rawDataIndex) : CutsceneCommand(rawData, rawDataIndex) +{ + int numEntries = BitConverter::ToInt32BE(rawData, rawDataIndex + 0); + + rawDataIndex += 4; + + for (int i = 0; i < numEntries; i++) + { + entries.push_back(new MusicFadeEntry(rawData, rawDataIndex)); + rawDataIndex += 0x30; + } +} + +string CutsceneCommandFadeBGM::GetCName(string prefix) +{ + return "CsCmdMusicFade"; +} + +string CutsceneCommandFadeBGM::GenerateSourceCode(string roomName, int baseAddress) +{ + string result = ""; + + result += StringHelper::Sprintf("CS_FADE_BGM_LIST(%i),\n", entries.size()); + + for (int i = 0; i < entries.size(); i++) + { + result += StringHelper::Sprintf("\t\tCS_FADE_BGM(%i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i),\n", entries[i]->base, entries[i]->startFrame, entries[i]->endFrame, + entries[i]->unknown0, entries[i]->unknown1, entries[i]->unknown2, entries[i]->unknown3, entries[i]->unknown4, entries[i]->unknown5, entries[i]->unknown6, entries[i]->unknown7, + entries[i]->unknown8, entries[i]->unknown9, entries[i]->unknown10); + } + + return result; +} + +size_t CutsceneCommandFadeBGM::GetCommandSize() +{ + return CutsceneCommand::GetCommandSize() + 0x30; +} + +MusicChangeEntry::MusicChangeEntry(vector rawData, int rawDataIndex) +{ + sequence = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 0); + startFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 2); + endFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 4); + unknown0 = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 6); + unknown1 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 8); + unknown2 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 12); + unknown3 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 16); + unknown4 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 20); + unknown5 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 24); + unknown6 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 28); + unknown7 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 32); +} + +CutsceneCommandPlayBGM::CutsceneCommandPlayBGM(vector rawData, int rawDataIndex) : CutsceneCommand(rawData, rawDataIndex) +{ + int numEntries = BitConverter::ToInt32BE(rawData, rawDataIndex + 0); + + rawDataIndex += 4; + + for (int i = 0; i < numEntries; i++) + { + entries.push_back(new MusicChangeEntry(rawData, rawDataIndex)); + rawDataIndex += 0x30; + } +} + +string CutsceneCommandPlayBGM::GenerateSourceCode(string roomName, int baseAddress) +{ + string result = ""; + + result += StringHelper::Sprintf("CS_PLAY_BGM_LIST(%i),\n", entries.size()); + + for (int i = 0; i < entries.size(); i++) + { + result += StringHelper::Sprintf("\t\tCS_PLAY_BGM(%i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i),\n", entries[i]->sequence, entries[i]->startFrame, + entries[i]->endFrame, entries[i]->unknown0, entries[i]->unknown1, entries[i]->unknown2, entries[i]->unknown3, entries[i]->unknown4, entries[i]->unknown5, + entries[i]->unknown6, entries[i]->unknown7); + } + + return result; +} + +string CutsceneCommandPlayBGM::GetCName(string prefix) +{ + return "CsCmdMusicChange"; +} + +size_t CutsceneCommandPlayBGM::GetCommandSize() +{ + return CutsceneCommand::GetCommandSize() + 0x30; +} + +CutsceneCommandStopBGM::CutsceneCommandStopBGM(vector rawData, int rawDataIndex) : CutsceneCommand(rawData, rawDataIndex) +{ + int numEntries = BitConverter::ToInt32BE(rawData, rawDataIndex + 0); + + rawDataIndex += 4; + + for (int i = 0; i < numEntries; i++) + { + entries.push_back(new MusicChangeEntry(rawData, rawDataIndex)); + rawDataIndex += 0x30; + } +} + +string CutsceneCommandStopBGM::GenerateSourceCode(string roomName, int baseAddress) +{ + string result = ""; + + result += StringHelper::Sprintf("CS_STOP_BGM_LIST(%i),\n", entries.size()); + + for (int i = 0; i < entries.size(); i++) + { + result += StringHelper::Sprintf("CS_STOP_BGM(%i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i),\n", entries[i]->sequence, entries[i]->startFrame, + entries[i]->endFrame, entries[i]->unknown0, entries[i]->unknown1, entries[i]->unknown2, entries[i]->unknown3, entries[i]->unknown4, entries[i]->unknown5, + entries[i]->unknown6, entries[i]->unknown7); + } + + return result; +} + +string CutsceneCommandStopBGM::GetCName(string prefix) +{ + return "CsCmdMusicChange"; +} + +size_t CutsceneCommandStopBGM::GetCommandSize() +{ + return CutsceneCommand::GetCommandSize() + 0x30; +} + +EnvLightingEntry::EnvLightingEntry(vector rawData, int rawDataIndex) +{ + setting = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 0); + startFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 2); + endFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 4); + unused0 = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 6); + unused1 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 8); + unused2 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 12); + unused3 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 16); + unused4 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 20); + unused5 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 24); + unused6 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 28); + unused7 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 32); +} + +CutsceneCommandEnvLighting::CutsceneCommandEnvLighting(vector rawData, int rawDataIndex) : CutsceneCommand(rawData, rawDataIndex) +{ + int numEntries = BitConverter::ToInt32BE(rawData, rawDataIndex + 0); + + rawDataIndex += 4; + + for (int i = 0; i < numEntries; i++) + { + entries.push_back(new EnvLightingEntry(rawData, rawDataIndex)); + rawDataIndex += 0x30; + } +} + +string CutsceneCommandEnvLighting::GenerateSourceCode(string roomName, int baseAddress) +{ + string result = ""; + + result += StringHelper::Sprintf("CS_LIGHTING_LIST(%i),\n", entries.size()); + + for (int i = 0; i < entries.size(); i++) + { + result += StringHelper::Sprintf("CS_LIGHTING(%i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i),\n", entries[i]->setting, entries[i]->startFrame, + entries[i]->endFrame, entries[i]->unused0, entries[i]->unused1, entries[i]->unused2, entries[i]->unused3, entries[i]->unused4, entries[i]->unused5, + entries[i]->unused6, entries[i]->unused7); + } + + return result; +} + +string CutsceneCommandEnvLighting::GetCName(string prefix) +{ + return "CsCmdEnvLighting"; +} + +size_t CutsceneCommandEnvLighting::GetCommandSize() +{ + return CutsceneCommand::GetCommandSize() + (0x30 * entries.size()); +} + +Unknown9Entry::Unknown9Entry(vector rawData, int rawDataIndex) +{ + base = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 0); + startFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 2); + endFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 4); + unk2 = rawData[rawDataIndex + 6]; + unk3 = rawData[rawDataIndex + 7]; + unk4 = rawData[rawDataIndex + 8]; + unused0 = rawData[rawDataIndex + 10]; + unused1 = rawData[rawDataIndex + 11];; +} + +CutsceneCommandUnknown9::CutsceneCommandUnknown9(vector rawData, int rawDataIndex) : CutsceneCommand(rawData, rawDataIndex) +{ + int numEntries = BitConverter::ToInt32BE(rawData, rawDataIndex); + + rawDataIndex += 4; + + for (int i = 0; i < numEntries; i++) + { + entries.push_back(new Unknown9Entry(rawData, rawDataIndex)); + rawDataIndex += 0x0C; + } +} + +string CutsceneCommandUnknown9::GenerateSourceCode(string roomName, int baseAddress) +{ + string result = ""; + + result += StringHelper::Sprintf("CS_CMD_09_LIST(%i),\n", entries.size()); + + for (int i = 0; i < entries.size(); i++) + { + result += StringHelper::Sprintf("CS_CMD_09(%i, %i, %i, %i, %i, %i, %i, %i),\n", entries[i]->base, entries[i]->startFrame, entries[i]->endFrame, entries[i]->unk2, + entries[i]->unk3, entries[i]->unk4, entries[i]->unused0, entries[i]->unused1); + } + + return result; +} + +string CutsceneCommandUnknown9::GetCName(string prefix) +{ + return "CsCmdUnknown9"; +} + +size_t CutsceneCommandUnknown9::GetCommandSize() +{ + return CutsceneCommand::GetCommandSize() + (entries.size() * 12); +} + +UnkEntry::UnkEntry(vector rawData, int rawDataIndex) +{ + unused0 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 0); + unused1 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 4); + unused2 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 8); + unused3 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 12); + unused4 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 16); + unused5 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 20); + unused6 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 24); + unused7 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 28); + unused8 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 32); + unused9 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 36); + unused10 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 40); + unused11 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 44); +} + +CutsceneCommandUnknown::CutsceneCommandUnknown(vector rawData, int rawDataIndex) : CutsceneCommand(rawData, rawDataIndex) +{ + int numEntries = BitConverter::ToInt32BE(rawData, rawDataIndex); + + rawDataIndex += 4; + + for (int i = 0; i < numEntries; i++) + { + entries.push_back(new UnkEntry(rawData, rawDataIndex)); + rawDataIndex += 0x30; + } +} + +string CutsceneCommandUnknown::GenerateSourceCode(string roomName, int baseAddress) +{ + string result = ""; + + result += StringHelper::Sprintf("CS_UNK_DATA_LIST(0x%02X, %i),\n", commandID, entries.size()); + + for (int i = 0; i < entries.size(); i++) + { + result += StringHelper::Sprintf("\tCS_UNK_DATA(%i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i),\n", entries[i]->unused0, entries[i]->unused1, entries[i]->unused2, + entries[i]->unused3, entries[i]->unused4, entries[i]->unused5, entries[i]->unused6, + entries[i]->unused7, entries[i]->unused8, entries[i]->unused9, entries[i]->unused10, entries[i]->unused11); + } + + return result; +} + +string CutsceneCommandUnknown::GetCName(string prefix) +{ + return "CsCmdUnknown1A"; +} + +size_t CutsceneCommandUnknown::GetCommandSize() +{ + return CutsceneCommand::GetCommandSize() + (entries.size() * 0x30); +} + +DayTimeEntry::DayTimeEntry(vector rawData, int rawDataIndex) +{ + base = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 0); + startFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 2); + endFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 4); + hour = rawData[rawDataIndex + 6]; + minute = rawData[rawDataIndex + 7]; + unused = rawData[rawDataIndex + 8]; +} + +CutsceneCommandDayTime::CutsceneCommandDayTime(vector rawData, int rawDataIndex) : CutsceneCommand(rawData, rawDataIndex) +{ + int numEntries = BitConverter::ToInt32BE(rawData, rawDataIndex); + + rawDataIndex += 4; + + for (int i = 0; i < numEntries; i++) + { + entries.push_back(new DayTimeEntry(rawData, rawDataIndex)); + rawDataIndex += 12; + } +} + +string CutsceneCommandDayTime::GetCName(string prefix) +{ + return "CsCmdDayTime"; +} + +string CutsceneCommandDayTime::GenerateSourceCode(string roomName, int baseAddress) +{ + string result = ""; + + result += StringHelper::Sprintf("CS_TIME_LIST(%i),\n", entries.size()); + + for (int i = 0; i < entries.size(); i++) + { + result += StringHelper::Sprintf("\t\tCS_TIME(%i, %i, %i, %i, %i, %i),\n", entries[i]->base, entries[i]->startFrame, entries[i]->endFrame, + entries[i]->hour, entries[i]->minute, entries[i]->unused); + } + + return result; +} + +size_t CutsceneCommandDayTime::GetCommandSize() +{ + return CutsceneCommand::GetCommandSize() + (entries.size() * 12); +} + +TextboxEntry::TextboxEntry(vector rawData, int rawDataIndex) +{ + base = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 0); + startFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 2); + endFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 4); + type = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 6); + textID1 = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 8); + textID2 = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 10); +} + +CutsceneCommandTextbox::CutsceneCommandTextbox(vector rawData, int rawDataIndex) : CutsceneCommand(rawData, rawDataIndex) +{ + int numEntries = BitConverter::ToInt32BE(rawData, rawDataIndex); + + rawDataIndex += 4; + + for (int i = 0; i < numEntries; i++) + { + entries.push_back(new TextboxEntry(rawData, rawDataIndex)); + rawDataIndex += 12; + } +} + +string CutsceneCommandTextbox::GetCName(string prefix) +{ + return "CsCmdTextbox"; +} + +string CutsceneCommandTextbox::GenerateSourceCode(string roomName, int baseAddress) +{ + string result = ""; + + result += StringHelper::Sprintf("CS_TEXT_LIST(%i),\n", entries.size()); + + for (int i = 0; i < entries.size(); i++) + { + if (entries[i]->base == 0xFFFF) + { + result += StringHelper::Sprintf("\t\tCS_TEXT_NONE(%i, %i),\n", entries[i]->startFrame, entries[i]->endFrame); + } + else + { + result += StringHelper::Sprintf("\t\tCS_TEXT_DISPLAY_TEXTBOX(%i, %i, %i, %i, %i, %i),\n", entries[i]->base, entries[i]->startFrame, entries[i]->endFrame, entries[i]->type, + entries[i]->textID1, entries[i]->textID2); + } + } + + return result; +} + +size_t CutsceneCommandTextbox::GetCommandSize() +{ + return CutsceneCommand::GetCommandSize() + (entries.size() * 12); +} + +ActorAction::ActorAction(vector rawData, int rawDataIndex) +{ + uint8_t* data = rawData.data(); + + action = (uint16_t)BitConverter::ToInt16BE(data, rawDataIndex + 0); + startFrame = (uint16_t)BitConverter::ToInt16BE(data, rawDataIndex + 2); + endFrame = (uint16_t)BitConverter::ToInt16BE(data, rawDataIndex + 4); + rotX = (uint16_t)BitConverter::ToInt16BE(data, rawDataIndex + 6); + rotY = (uint16_t)BitConverter::ToInt16BE(data, rawDataIndex + 8); + rotZ = (uint16_t)BitConverter::ToInt16BE(data, rawDataIndex + 10); + startPosX = BitConverter::ToInt32BE(data, rawDataIndex + 12); + startPosY = BitConverter::ToInt32BE(data, rawDataIndex + 16); + startPosZ = BitConverter::ToInt32BE(data, rawDataIndex + 20); + endPosX = BitConverter::ToInt32BE(data, rawDataIndex + 24); + endPosY = BitConverter::ToInt32BE(data, rawDataIndex + 28); + endPosZ = BitConverter::ToInt32BE(data, rawDataIndex + 32); + normalX = BitConverter::ToInt32BE(data, rawDataIndex + 36); + normalY = BitConverter::ToInt32BE(data, rawDataIndex + 40); + normalZ = BitConverter::ToInt32BE(data, rawDataIndex + 44); +} + +CutsceneCommandActorAction::CutsceneCommandActorAction(vector rawData, int rawDataIndex) : CutsceneCommand(rawData, rawDataIndex) +{ + int numEntries = BitConverter::ToInt32BE(rawData, rawDataIndex); + + rawDataIndex += 4; + + for (int i = 0; i < numEntries; i++) + { + entries.push_back(new ActorAction(rawData, rawDataIndex)); + rawDataIndex += 0x30; + } +} + +string CutsceneCommandActorAction::GenerateSourceCode(string roomName, int baseAddress) +{ + string result = ""; + + result += StringHelper::Sprintf("CS_NPC_ACTION_LIST(%i, %i),\n", commandID, entries.size()); + + for (int i = 0; i < entries.size(); i++) + { + result += StringHelper::Sprintf("\tCS_NPC_ACTION(0x%04X, %i, %i, 0x%04X, 0x%04X, 0x%04X, %i, %i, %i, %i, %i, %i, %i, %i, %i),\n", entries[i]->action, entries[i]->startFrame, entries[i]->endFrame, + entries[i]->rotX, entries[i]->rotY, entries[i]->rotZ, entries[i]->startPosX, entries[i]->startPosY, entries[i]->startPosZ, entries[i]->endPosX, entries[i]->endPosY, entries[i]->endPosZ, + *(int32_t*)&entries[i]->normalX, *(int32_t*)&entries[i]->normalY, *(int32_t*)&entries[i]->normalZ); + } + + return result; +} + +string CutsceneCommandActorAction::GetCName(string prefix) +{ + return "CsCmdBase"; +} + +size_t CutsceneCommandActorAction::GetCommandSize() +{ + return CutsceneCommand::GetCommandSize() + (entries.size() * 0x30); +} + +CutsceneCommandTerminator::CutsceneCommandTerminator(vector rawData, int rawDataIndex) : CutsceneCommand(rawData, rawDataIndex) +{ + rawDataIndex += 4; + + base = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 0); + startFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 2); + endFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 4); + unknown = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 6); +} + +string CutsceneCommandTerminator::GetCName(string prefix) +{ + return "CsCmdBase"; +} + +string CutsceneCommandTerminator::GenerateSourceCode(string roomName, int baseAddress) +{ + string result = ""; + + result += StringHelper::Sprintf("CS_TERMINATOR(0x%04X, %i, %i, 0x%04X),\n", base, startFrame, endFrame, unknown); + + return result; +} + +size_t CutsceneCommandTerminator::GetCommandSize() +{ + return CutsceneCommand::GetCommandSize() + 8; +} + +CutsceneCommandEnd::CutsceneCommandEnd(vector rawData, int rawDataIndex) : CutsceneCommand(rawData, rawDataIndex) +{ + base = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 0); + startFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 2); + endFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 4); +} + +string CutsceneCommandEnd::GenerateSourceCode(string roomName, int baseAddress) +{ + string result = ""; + + result += StringHelper::Sprintf("CS_END(),\n"); + + return result; +} + +string CutsceneCommandEnd::GetCName(string prefix) +{ + return "CsCmdBase"; +} + +size_t CutsceneCommandEnd::GetCommandSize() +{ + return CutsceneCommand::GetCommandSize() + 6; +} + +SpecialActionEntry::SpecialActionEntry(vector rawData, int rawDataIndex) +{ + uint8_t* data = rawData.data(); + + base = (uint16_t)BitConverter::ToInt16BE(data, rawDataIndex + 0); + startFrame = (uint16_t)BitConverter::ToInt16BE(data, rawDataIndex + 2); + endFrame = (uint16_t)BitConverter::ToInt16BE(data, rawDataIndex + 4); + unused0 = (uint16_t)BitConverter::ToInt16BE(data, rawDataIndex + 6); + unused1 = (uint32_t)BitConverter::ToInt32BE(data, rawDataIndex + 8); + unused2 = (uint32_t)BitConverter::ToInt32BE(data, rawDataIndex + 12); + unused3 = (uint32_t)BitConverter::ToInt32BE(data, rawDataIndex + 16); + unused4 = (uint32_t)BitConverter::ToInt32BE(data, rawDataIndex + 20); + unused5 = (uint32_t)BitConverter::ToInt32BE(data, rawDataIndex + 24); + unused6 = (uint32_t)BitConverter::ToInt32BE(data, rawDataIndex + 28); + unused7 = (uint32_t)BitConverter::ToInt32BE(data, rawDataIndex + 32); + unused8 = (uint32_t)BitConverter::ToInt32BE(data, rawDataIndex + 36); + unused9 = (uint32_t)BitConverter::ToInt32BE(data, rawDataIndex + 40); + unused10 = (uint32_t)BitConverter::ToInt32BE(data, rawDataIndex + 44); +} + +CutsceneCommandSpecialAction::CutsceneCommandSpecialAction(vector rawData, int rawDataIndex) : CutsceneCommand(rawData, rawDataIndex) +{ + int numEntries = BitConverter::ToInt32BE(rawData, rawDataIndex + 0); + + rawDataIndex += 4; + + for (int i = 0; i < numEntries; i++) + { + entries.push_back(new SpecialActionEntry(rawData, rawDataIndex)); + rawDataIndex += 0x30; + } +} + +string CutsceneCommandSpecialAction::GenerateSourceCode(string roomName, int baseAddress) +{ + string result = ""; + + result += StringHelper::Sprintf("CS_MISC_LIST(%i),\n", entries.size()); + + for (int i = 0; i < entries.size(); i++) + { + result += StringHelper::Sprintf("\t\tCS_MISC(0x%04X, %i, %i, 0x%04X, 0x%04X, 0x%04X, %i, %i, %i, %i, %i, %i, %i, %i),\n", entries[i]->base, entries[i]->startFrame, entries[i]->endFrame, + entries[i]->unused0, entries[i]->unused1, entries[i]->unused2, entries[i]->unused3, entries[i]->unused4, entries[i]->unused5, entries[i]->unused6, + entries[i]->unused7, entries[i]->unused8, entries[i]->unused9, entries[i]->unused10); + } + + return result; +} + +string CutsceneCommandSpecialAction::GetCName(string prefix) +{ + return "CsCmdBase"; +} + +size_t CutsceneCommandSpecialAction::GetCommandSize() +{ + return CutsceneCommand::GetCommandSize() + (0x30 * entries.size()); +} + +CutsceneCommandNop::CutsceneCommandNop(vector rawData, int rawDataIndex) : CutsceneCommand(rawData, rawDataIndex) +{ + base = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 0); + startFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 2); + endFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 4); +} + +string CutsceneCommandNop::GetCName(string prefix) +{ + return "CsCmdBase"; +} + +size_t CutsceneCommandNop::GetCommandSize() +{ + return CutsceneCommand::GetCommandSize() + 6; +} + +CutsceneCommandSceneTransFX::CutsceneCommandSceneTransFX(vector rawData, int rawDataIndex) : CutsceneCommand(rawData, rawDataIndex) +{ + rawDataIndex += 4; + + base = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 0); + startFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 2); + endFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 4); +} + +string CutsceneCommandSceneTransFX::GenerateSourceCode(string roomName, int baseAddress) +{ + return StringHelper::Sprintf("CS_SCENE_TRANS_FX(%i, %i, %i, %i),\n", base, startFrame, endFrame); +} + +string CutsceneCommandSceneTransFX::GetCName(string prefix) +{ + return "CsCmdBase"; +} + +size_t CutsceneCommandSceneTransFX::GetCommandSize() +{ + return CutsceneCommand::GetCommandSize() + 8; +} diff --git a/tools/ZAPD/ZAPD/ZCutscene.h b/tools/ZAPD/ZAPD/ZCutscene.h new file mode 100644 index 0000000000..9a7c45a960 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZCutscene.h @@ -0,0 +1,414 @@ +#pragma once + +#include +#include +#include +#include "ZResource.h" +#include "tinyxml2.h" + +enum class CutsceneCommands +{ + Cmd00 = 0x0000, + SetCameraPos = 0x0001, + SetCameraFocus = 0x0002, + SpecialAction = 0x0003, + SetLighting = 0x0004, + SetCameraPosLink = 0x0005, + SetCameraFocusLink = 0x0006, + Cmd07 = 0x0007, + Cmd08 = 0x0008, + Cmd09 = 0x0009, + Unknown = 0x001A, + Textbox = 0x0013, + SetActorAction0 = 0x000A, + SetActorAction1 = 0x000F, + SetActorAction2 = 0x000E, + SetActorAction3 = 0x0019, + SetActorAction4 = 0x001D, + SetActorAction5 = 0x001E, + SetActorAction6 = 0x002C, + SetActorAction7 = 0x001F, + SetActorAction8 = 0x0031, + SetActorAction9 = 0x003E, + SetActorAction10 = 0x008F, + SetSceneTransFX = 0x002D, + Nop = 0x000B, + PlayBGM = 0x0056, + StopBGM = 0x0057, + FadeBGM = 0x007C, + SetTime = 0x008C, + Terminator = 0x03E8, + End = 0xFFFF, + Error = 0xFEAF, +}; + +class CutsceneCameraPoint +{ +public: + int8_t continueFlag; + int8_t cameraRoll; + int16_t nextPointFrame; + uint32_t viewAngle; + int16_t posX, posY, posZ; + int16_t unused; + + CutsceneCameraPoint(std::vector rawData, int rawDataIndex); +}; + +class CutsceneCommand +{ +public: + uint32_t commandID; + uint32_t commandIndex; + + CutsceneCommand(std::vector rawData, int rawDataIndex); + virtual std::string GetCName(std::string prefix); + virtual std::string GenerateSourceCode(std::string roomName, int baseAddress); + virtual size_t GetCommandSize(); +}; + +class CutsceneCommandSetCameraPos : public CutsceneCommand +{ +public: + uint16_t base; + uint16_t startFrame; + uint16_t endFrame; + uint16_t unused; + + std::vector entries; + + CutsceneCommandSetCameraPos(std::vector rawData, int rawDataIndex); + std::string GetCName(std::string prefix); + std::string GenerateSourceCode(std::string roomName, int baseAddress); + size_t GetCommandSize(); +}; + +class SpecialActionEntry +{ +public: + uint16_t base; + uint16_t startFrame; + uint16_t endFrame; + uint16_t unused0; + uint32_t unused1; + uint32_t unused2; + uint32_t unused3; + uint32_t unused4; + uint32_t unused5; + uint32_t unused6; + uint32_t unused7; + uint32_t unused8; + uint32_t unused9; + uint32_t unused10; + + SpecialActionEntry(std::vector rawData, int rawDataIndex); +}; + +class CutsceneCommandSpecialAction : public CutsceneCommand +{ +public: + std::vector entries; + + CutsceneCommandSpecialAction(std::vector rawData, int rawDataIndex); + std::string GetCName(std::string prefix); + std::string GenerateSourceCode(std::string roomName, int baseAddress); + size_t GetCommandSize(); +}; + +class MusicFadeEntry +{ +public: + uint16_t base; + uint16_t startFrame; + uint16_t endFrame; + uint16_t unknown0; + uint32_t unknown1; + uint32_t unknown2; + uint32_t unknown3; + uint32_t unknown4; + uint32_t unknown5; + uint32_t unknown6; + uint32_t unknown7; + uint32_t unknown8; + uint32_t unknown9; + uint32_t unknown10; + + MusicFadeEntry(std::vector rawData, int rawDataIndex); +}; + +class CutsceneCommandFadeBGM : public CutsceneCommand +{ +public: + std::vector entries; + + CutsceneCommandFadeBGM( std::vector rawData, int rawDataIndex); + std::string GetCName(std::string prefix); + std::string GenerateSourceCode(std::string roomName, int baseAddress); + size_t GetCommandSize(); +}; + +class MusicChangeEntry +{ +public: + uint16_t sequence; + uint16_t startFrame; + uint16_t endFrame; + uint16_t unknown0; + uint32_t unknown1; + uint32_t unknown2; + uint32_t unknown3; + uint32_t unknown4; + uint32_t unknown5; + uint32_t unknown6; + uint32_t unknown7; + + MusicChangeEntry(std::vector rawData, int rawDataIndex); +}; + +class CutsceneCommandPlayBGM : public CutsceneCommand +{ +public: + std::vector entries; + + CutsceneCommandPlayBGM(std::vector rawData, int rawDataIndex); + std::string GetCName(std::string prefix); + std::string GenerateSourceCode(std::string roomName, int baseAddress); + size_t GetCommandSize(); +}; + +class CutsceneCommandStopBGM : public CutsceneCommand +{ +public: + std::vector entries; + + CutsceneCommandStopBGM(std::vector rawData, int rawDataIndex); + std::string GetCName(std::string prefix); + std::string GenerateSourceCode(std::string roomName, int baseAddress); + size_t GetCommandSize(); +}; + +class EnvLightingEntry +{ +public: + uint16_t setting; + uint16_t startFrame; + uint16_t endFrame; + uint16_t unused0; + uint32_t unused1; + uint32_t unused2; + uint32_t unused3; + uint32_t unused4; + uint32_t unused5; + uint32_t unused6; + uint32_t unused7; + + EnvLightingEntry(std::vector rawData, int rawDataIndex); +}; + +class CutsceneCommandEnvLighting : public CutsceneCommand +{ +public: + std::vector entries; + + CutsceneCommandEnvLighting(std::vector rawData, int rawDataIndex); + std::string GetCName(std::string prefix); + std::string GenerateSourceCode(std::string roomName, int baseAddress); + size_t GetCommandSize(); +}; + +class CutsceneCommandSceneTransFX : public CutsceneCommand +{ +public: + uint16_t base; + uint16_t startFrame; + uint16_t endFrame; + + CutsceneCommandSceneTransFX(std::vector rawData, int rawDataIndex); + std::string GetCName(std::string prefix); + std::string GenerateSourceCode(std::string roomName, int baseAddress); + size_t GetCommandSize(); +}; + +class Unknown9Entry +{ +public: + uint16_t base; + uint16_t startFrame; + uint16_t endFrame; + uint16_t unk2; + uint16_t unk3; + uint16_t unk4; + uint8_t unused0; + uint8_t unused1; + + Unknown9Entry(std::vector rawData, int rawDataIndex); +}; + +class CutsceneCommandUnknown9 : public CutsceneCommand +{ +public: + std::vector entries; + + CutsceneCommandUnknown9(std::vector rawData, int rawDataIndex); + std::string GetCName(std::string prefix); + std::string GenerateSourceCode(std::string roomName, int baseAddress); + size_t GetCommandSize(); +}; + +class UnkEntry +{ +public: + uint32_t unused0; + uint32_t unused1; + uint32_t unused2; + uint32_t unused3; + uint32_t unused4; + uint32_t unused5; + uint32_t unused6; + uint32_t unused7; + uint32_t unused8; + uint32_t unused9; + uint32_t unused10; + uint32_t unused11; + + UnkEntry(std::vector rawData, int rawDataIndex); +}; + +class CutsceneCommandUnknown : public CutsceneCommand +{ +public: + std::vector entries; + + CutsceneCommandUnknown(std::vector rawData, int rawDataIndex); + std::string GetCName(std::string prefix); + std::string GenerateSourceCode(std::string roomName, int baseAddress); + size_t GetCommandSize(); +}; + +class DayTimeEntry +{ +public: + uint16_t base; + uint16_t startFrame; + uint16_t endFrame; + uint8_t hour; + uint8_t minute; + uint8_t unused; + + DayTimeEntry(std::vector rawData, int rawDataIndex); +}; + +class CutsceneCommandDayTime : public CutsceneCommand +{ +public: + std::vector entries; + + CutsceneCommandDayTime(std::vector rawData, int rawDataIndex); + std::string GetCName(std::string prefix); + std::string GenerateSourceCode(std::string roomName, int baseAddress); + size_t GetCommandSize(); +}; + +class TextboxEntry +{ +public: + uint16_t base; + uint16_t startFrame; + uint16_t endFrame; + uint16_t type; + uint16_t textID1; + uint16_t textID2; + + TextboxEntry(std::vector rawData, int rawDataIndex); +}; + +class CutsceneCommandTextbox : public CutsceneCommand +{ +public: + std::vector entries; + + CutsceneCommandTextbox(std::vector rawData, int rawDataIndex); + std::string GetCName(std::string prefix); + std::string GenerateSourceCode(std::string roomName, int baseAddress); + size_t GetCommandSize(); +}; + +class ActorAction +{ +public: + uint16_t action; + uint16_t startFrame; + uint16_t endFrame; + int16_t rotX, rotY, rotZ; + int32_t startPosX, startPosY, startPosZ; + int32_t endPosX, endPosY, endPosZ; + int32_t normalX, normalY, normalZ; + + ActorAction(std::vector rawData, int rawDataIndex); +}; + +class CutsceneCommandActorAction : public CutsceneCommand +{ +public: + std::vector entries; + + CutsceneCommandActorAction(std::vector rawData, int rawDataIndex); + std::string GetCName(std::string prefix); + std::string GenerateSourceCode(std::string roomName, int baseAddress); + size_t GetCommandSize(); +}; + +class CutsceneCommandTerminator : public CutsceneCommand +{ +public: + uint16_t base; + uint16_t startFrame; + uint16_t endFrame; + uint16_t unknown; + + CutsceneCommandTerminator(std::vector rawData, int rawDataIndex); + std::string GetCName(std::string prefix); + std::string GenerateSourceCode(std::string roomName, int baseAddress); + size_t GetCommandSize(); +}; + +class CutsceneCommandEnd : public CutsceneCommand +{ +public: + uint16_t base; + uint16_t startFrame; + uint16_t endFrame; + + CutsceneCommandEnd(std::vector rawData, int rawDataIndex); + std::string GetCName(std::string prefix); + std::string GenerateSourceCode(std::string roomName, int baseAddress); + size_t GetCommandSize(); +}; + +class CutsceneCommandNop : public CutsceneCommand +{ +public: + uint16_t base; + uint16_t startFrame; + uint16_t endFrame; + + CutsceneCommandNop(std::vector rawData, int rawDataIndex); + std::string GetCName(std::string prefix); + size_t GetCommandSize(); +}; + +class ZCutscene : public ZResource +{ +public: + uint32_t segmentOffset; + + CutsceneCommands GetCommandFromID(int id); + ZCutscene(std::vector nRawData, int rawDataIndex, int rawDataSize); + + std::string GetSourceOutputCode(std::string prefix); + int GetRawDataSize(); +private: + int numCommands; + int endFrame; + std::vector commands; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZDisplayList.cpp b/tools/ZAPD/ZAPD/ZDisplayList.cpp new file mode 100644 index 0000000000..0a1ecbef76 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZDisplayList.cpp @@ -0,0 +1,1397 @@ +#include "ZDisplayList.h" +#include "BitConverter.h" +#include "StringHelper.h" +#include "HighLevel/HLModelIntermediette.h" +#include "Globals.h" +#include +#include +#include +#include +#include + +using namespace std; +using namespace tinyxml2; + +ZDisplayList::ZDisplayList() : ZResource() +{ + defines = ""; + sceneSegName = ""; + lastTexWidth = 0; + lastTexHeight = 0; + lastTexAddr = 0; + lastTexFmt = F3DZEXTexFormats::G_IM_FMT_RGBA; + lastTexSiz = F3DZEXTexSizes::G_IM_SIZ_16b; + lastTexSizTest = F3DZEXTexSizes::G_IM_SIZ_16b; + lastTexLoaded = false; + name = ""; + scene = nullptr; + + fileData = vector(); + instructions = vector(); + vertices = map>(); + vtxDeclarations = map(); + otherDLists = vector(); + textures = map(); + texDeclarations = map(); +} + +// EXTRACT MODE +ZDisplayList* ZDisplayList::ExtractFromXML(XMLElement* reader, vector nRawData, int nRawDataIndex, int rawDataSize, string nRelPath) +{ + ZDisplayList* dList = new ZDisplayList(); + + dList->ParseXML(reader); + + //dList->name = reader->Attribute("Name"); + + dList->rawData = nRawData; + dList->rawDataIndex = nRawDataIndex; + dList->fileData = dList->rawData; + dList->relativePath = nRelPath; + dList->rawData = vector(dList->rawData.data() + dList->rawDataIndex, dList->rawData.data() + dList->rawDataIndex + rawDataSize); + dList->ParseRawData(); + + return dList; +} + +ZDisplayList* ZDisplayList::BuildFromXML(XMLElement* reader, string inFolder, bool readFile) +{ + ZDisplayList* dList = new ZDisplayList(); + + dList->SetName(reader->Attribute("Name")); + return dList; +} + +ZDisplayList::ZDisplayList(vector nRawData, int nRawDataIndex, int rawDataSize) : ZDisplayList() +{ + fileData = nRawData; + rawDataIndex = nRawDataIndex; + name = StringHelper::Sprintf("Dlist0x%06X", rawDataIndex); + rawData = vector(nRawData.data() + rawDataIndex, nRawData.data() + rawDataIndex + rawDataSize); + ParseRawData(); +} + +void ZDisplayList::ParseRawData() +{ + int numInstructions = (int)rawData.size() / 8; + uint8_t* rawDataArr = rawData.data(); + + instructions.reserve(numInstructions); + + for (int i = 0; i < numInstructions; i++) + instructions.push_back(BitConverter::ToInt64BE(rawDataArr, (i * 8))); +} + +int ZDisplayList::GetDListLength(vector rawData, int rawDataIndex) +{ + int i = 0; + + while (true) + { + F3DZEXOpcode opcode = (F3DZEXOpcode)rawData[rawDataIndex + (i * 8)]; + i++; + + if (opcode == F3DZEXOpcode::G_ENDDL) + return i * 8; + } +} + +bool ZDisplayList::SequenceCheck(vector sequence, int startIndex) +{ + bool success = true; + + for (int j = 0; j < sequence.size(); j++) + { + F3DZEXOpcode opcode = (F3DZEXOpcode)(instructions[startIndex + j] >> 56); + + if (sequence[j] != opcode) + { + success = false; + break; + } + } + + if (success) + return true; + + return false; +} + +int ZDisplayList::OptimizationChecks(int startIndex, string& output, string prefix) +{ + int result = -1; + + result = OptimizationCheck_LoadTextureBlock(startIndex, output, prefix); + + if (result != -1) + return result; + + return -1; +} + +int ZDisplayList::OptimizationCheck_LoadTextureBlock(int startIndex, string& output, string prefix) +{ + std::vector sequence = { F3DZEXOpcode::G_SETTIMG, F3DZEXOpcode::G_SETTILE, F3DZEXOpcode::G_RDPLOADSYNC, F3DZEXOpcode::G_LOADBLOCK, F3DZEXOpcode::G_RDPPIPESYNC, F3DZEXOpcode::G_SETTILE, F3DZEXOpcode::G_SETTILESIZE }; + + bool seqRes = SequenceCheck(sequence, startIndex); + + if (seqRes) + { + // gsDPLoadTextureBlock(texAddr, fmt, siz, width, height, pal, cms, cmt, masks, maskt, shifts, shiftt) + // gsDPLoadMultiBlock(texAddr, tmem, rtile, fmt, siz, width, height, pal, cms, cmt, masks, maskt, shifts, shiftt) + // gsDPLoadTextureBlock_4b(texAddr, fmt, width, height, pal, cms, cmt, masks, maskt, shifts, shiftt) + // gsDPLoadMultiBlock_4b(texAddr, tmem, rtile, fmt, width, height, pal, cms, cmt, masks, maskt, shifts, shiftt) + + uint32_t texAddr, tmem, rtile, fmt, siz, sizB, width, height, width2, height2, pal, cms, cmt, masks, maskt, shifts, shiftt; + string texStr = ""; + + // gsDPSetTextureImage + { + uint64_t data = instructions[startIndex + 0]; + + int __ = (data & 0x00FF000000000000) >> 48; + int www = (data & 0x00000FFF00000000) >> 32; + + fmt = (__ & 0xE0) >> 5; + siz = (__ & 0x18) >> 3; + texAddr = SEG2FILESPACE(data); + int segmentNumber = (data & 0xFF000000) >> 24; + + if (segmentNumber == 0x80) // Is this texture defined in code? + texAddr -= SEG2FILESPACE(parent->baseAddress); + + lastTexSeg = (data & 0xFF000000); + + if (texAddr == 0xb880e0) + { + int bp = 0; + } + + Declaration* texDecl = nullptr; + + if (parent != nullptr) + { + texDecl = parent->GetDeclaration(texAddr); + + if (texDecl == nullptr) + texDecl = parent->GetDeclaration(data); + } + + if (texAddr != 0) + { + if (texDecl != nullptr) + texStr = StringHelper::Sprintf("%s", texDecl->varName.c_str()); + else if (segmentNumber == 2) + texStr = StringHelper::Sprintf("%sTex_%06X", scene->GetName().c_str(), texAddr); + else if (!Globals::Instance->HasSegment(segmentNumber)) // Probably an external asset we are unable to track + texStr = StringHelper::Sprintf("0x%06X", data); + else + texStr = StringHelper::Sprintf("%sTex_%06X", prefix.c_str(), texAddr); + } + else if (segmentNumber != 3) + texStr = StringHelper::Sprintf("0x%06X", data); + else + texStr = StringHelper::Sprintf("0"); + } + + // gsDPSetTile + { + uint64_t data = instructions[startIndex + 1]; + + tmem = (data & 0b0000000000000000111111111111111100000000000000000000000000000000) >> 32; + + cmt = (data & 0b0000000000000000000000000000000000000000000011000000000000000000) >> 18; + maskt = (data & 0b0000000000000000000000000000000000000000000000111100000000000000) >> 14; + shiftt = (data & 0b0000000000000000000000000000000000000000000000000011110000000000) >> 10; + cms = (data & 0b0000000000000000000000000000000000000000000000000000001100000000) >> 8; + masks = (data & 0b0000000000000000000000000000000000000000000000000000000011110000) >> 4; + shifts = (data & 0b0000000000000000000000000000000000000000000000000000000000001111); + + //sprintf(line, "gsDPSetTile(%s, %s, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i),", fmtTbl[fff].c_str(), sizTbl[ii].c_str(), nnnnnnnnn, mmmmmmmmm, ttt, pppp, cc, aaaa, ssss, dd, bbbb, uuuu); + + } + + // gsDPLoadSync + + // gsDPLoadBlock + + // gsDPPipeSync + + // gsDPSetTile + { + uint64_t data = instructions[startIndex + 5]; + int __ = (data & 0x00FF000000000000) >> 48; + pal = (data & 0b0000000000000000000000000000000000000000111100000000000000000000) >> 20; + //siz = (__ & 0x18) >> 3; + rtile = (data & 0b0000000000000000000000000000000011111111000000000000000000000000) >> 24; + sizB = (__ & 0x18) >> 3; + } + + // gsDPSetTileSize + { + uint64_t data = instructions[startIndex + 6]; + int uuu = (data & 0x0000000000FFF000) >> 12; + int vvv = (data & 0x0000000000000FFF); + + int shiftAmtW = 2; + int shiftAmtH = 2; + + if (sizB == (int)F3DZEXTexSizes::G_IM_SIZ_8b && fmt == (int)F3DZEXTexFormats::G_IM_FMT_IA) + shiftAmtW = 3; + + if (sizB == (int)F3DZEXTexSizes::G_IM_SIZ_4b) + shiftAmtW = 3; + + if (sizB == (int)F3DZEXTexSizes::G_IM_SIZ_4b && fmt == (int)F3DZEXTexFormats::G_IM_FMT_IA) + shiftAmtH = 3; + + if (texAddr == 0xb880e0) + { + int bp = 0; + } + + width = (uuu >> shiftAmtW) + 1; + height = (vvv >> shiftAmtH) + 1; + + width2 = (uuu >> 2) + 1; + height2 = (vvv >> 2) + 1; + } + + string fmtTbl[] = { "G_IM_FMT_RGBA", "G_IM_FMT_YUV", "G_IM_FMT_CI", "G_IM_FMT_IA", "G_IM_FMT_I" }; + string sizTbl[] = { "G_IM_SIZ_4b", "G_IM_SIZ_8b", "G_IM_SIZ_16b", "G_IM_SIZ_32b" }; + + //output += StringHelper::Sprintf("gsDPLoadTextureBlock(%s, %s, %s, %i, %i, %i, %i, %i, %i, %i, %i, %i),", + //texStr.c_str(), fmtTbl[fmt].c_str(), sizTbl[siz].c_str(), width, height, pal, cms, cmt, masks, maskt, shifts, shiftt); + + if (siz == 2 && sizB == 0) + { + if (tmem != 0) + output += StringHelper::Sprintf("gsDPLoadMultiBlock_4b(%s, %i, %i, %s, %i, %i, %i, %i, %i, %i, %i, %i, %i),", + texStr.c_str(), tmem, rtile, fmtTbl[fmt].c_str(), width2, height2, pal, cms, cmt, masks, maskt, shifts, shiftt); + else + output += StringHelper::Sprintf("gsDPLoadTextureBlock_4b(%s, %s, %i, %i, %i, %i, %i, %i, %i, %i, %i),", + texStr.c_str(), fmtTbl[fmt].c_str(), width2, height2, pal, cms, cmt, masks, maskt, shifts, shiftt); + } + /*else if (siz == 2 && sizB == 1) + { + output += StringHelper::Sprintf("gsDPLoadTextureBlock(%s, %s, %s, %i, %i, %i, %i, %i, %i, %i, %i, %i),", + texStr.c_str(), fmtTbl[fmt].c_str(), sizTbl[siz].c_str(), width2, height2, pal, cms, cmt, masks, maskt, shifts, shiftt); + }*/ + else + { + if (siz != sizB) + { + lastTexAddr = texAddr; + lastTexFmt = (F3DZEXTexFormats)fmt; + lastTexWidth = width; + lastTexHeight = height; + lastTexSiz = (F3DZEXTexSizes)siz; + lastTexLoaded = true; + + TextureGenCheck(prefix); + + return -1; + } + + output += StringHelper::Sprintf("gsDPLoadMultiBlock(%s, %i, %i, %s, %s, %i, %i, %i, %i, %i, %i, %i, %i, %i),", + texStr.c_str(), tmem, rtile, fmtTbl[fmt].c_str(), sizTbl[siz].c_str(), width, height, pal, cms, cmt, masks, maskt, shifts, shiftt); + } + + lastTexAddr = texAddr; + lastTexFmt = (F3DZEXTexFormats)fmt; + lastTexWidth = width; + lastTexHeight = height; + lastTexSiz = (F3DZEXTexSizes)siz; + lastTexLoaded = true; + + if (lastTexAddr == 0x8798) + { + int bp = 0; + } + + TextureGenCheck(prefix); + + return (int)sequence.size(); + } + + return -1; +} + +string ZDisplayList::GetSourceOutputHeader(string prefix) +{ + return ""; +} + +string ZDisplayList::GetSourceOutputCode(std::string prefix) +{ + char line[4096]; + string sourceOutput = ""; + + for (int i = 0; i < instructions.size(); i++) + { + F3DZEXOpcode opcode = (F3DZEXOpcode)(instructions[i] >> 56); + uint64_t data = instructions[i]; + sourceOutput += " "; + + auto start = chrono::steady_clock::now(); + + int optimizationResult = OptimizationChecks(i, sourceOutput, prefix); + + if (optimizationResult != -1) + { + i += optimizationResult - 1; + line[0] = '\0'; + } + else + { + switch (opcode) + { + case F3DZEXOpcode::G_NOOP: + sprintf(line, "gsDPNoOpTag(0x%08lX),", data & 0xFFFFFFFF); + break; + case F3DZEXOpcode::G_DL: + { + int pp = (data & 0x00FF000000000000) >> 56; + int segNum = (data & 0xFF000000) >> 24; + + Declaration* dListDecl = nullptr; + + if (parent != nullptr) + dListDecl = parent->GetDeclaration(SEG2FILESPACE(data)); + + // TEST + if (segNum != 8 && scene != nullptr && scene->parent->GetDeclarationName(data & 0x00FFFFFF) != "ERROR_COULD_NOT_FIND_DECLARATION") + { + int bp = 0; + } + + if (pp != 0) + { + if (dListDecl != nullptr) + sprintf(line, "gsSPBranchList(%s),", dListDecl->varName.c_str()); + else + sprintf(line, "gsSPBranchList(%sDlist0x%06X),", prefix.c_str(), SEG2FILESPACE(data)); + } + else + { + if (dListDecl != nullptr) + sprintf(line, "gsSPDisplayList(%s),", dListDecl->varName.c_str()); + else + sprintf(line, "gsSPDisplayList(%sDlist0x%06X),", prefix.c_str(), SEG2FILESPACE(data)); + } + + int segmentNumber = (data & 0xFF000000) >> 24; + + if (segmentNumber == 8 || segmentNumber == 9 || segmentNumber == 10 || segmentNumber == 11 || segmentNumber == 12 || segmentNumber == 13) // Used for runtime-generated display lists + { + if (pp != 0) + sprintf(line, "gsSPBranchList(0x%08lX),", data & 0xFFFFFFFF); + else + sprintf(line, "gsSPDisplayList(0x%08lX),", data & 0xFFFFFFFF); + } + else + { + ZDisplayList* nList = new ZDisplayList(fileData, data & 0x00FFFFFF, GetDListLength(fileData, data & 0x00FFFFFF)); + nList->scene = scene; + otherDLists.push_back(nList); + } + } + break; + case F3DZEXOpcode::G_MODIFYVTX: + { + int ww = (data & 0x00FF000000000000ULL) >> 48; + int nnnn = (data & 0x0000FFFF00000000ULL) >> 32; + int vvvvvvvv = (data & 0x00000000FFFFFFFFULL); + + sprintf(line, "gsSPModifyVertex(%i, %i, %i),", nnnn / 2, ww, vvvvvvvv); + } + break; + case F3DZEXOpcode::G_CULLDL: + { + int vvvv = (data & 0xFFFF00000000) >> 32; + int wwww = (data & 0x0000FFFF); + + sprintf(line, "gsSPCullDisplayList(%i, %i),", vvvv / 2, wwww / 2); + } + break; + /*case F3DZEXOpcode::G_BRANCH_Z: + { + int aaa = (data & 0x00FFF00000000000) >> 44; + int bbb = (data & 0x00000FFF00000000) >> 32; + int zzzzzzzz = (data & 0x00000000FFFFFFFF); + + sprintf(line, "gsSPBranchLessZraw(%i, %i, %i),", ); + } + break;*/ + case F3DZEXOpcode::G_TRI1: + { + int aa = ((data & 0x00FF000000000000ULL) >> 48) / 2; + int bb = ((data & 0x0000FF0000000000ULL) >> 40) / 2; + int cc = ((data & 0x000000FF00000000ULL) >> 32) / 2; + sprintf(line, "gsSP1Triangle(%i, %i, %i, 0),", aa, bb, cc); + } + break; + case F3DZEXOpcode::G_TRI2: + { + int aa = ((data & 0x00FF000000000000ULL) >> 48) / 2; + int bb = ((data & 0x0000FF0000000000ULL) >> 40) / 2; + int cc = ((data & 0x000000FF00000000ULL) >> 32) / 2; + int dd = ((data & 0x00000000FF0000ULL) >> 16) / 2; + int ee = ((data & 0x0000000000FF00ULL) >> 8) / 2; + int ff = ((data & 0x000000000000FFULL) >> 0) / 2; + sprintf(line, "gsSP2Triangles(%i, %i, %i, 0, %i, %i, %i, 0),", aa, bb, cc, dd, ee, ff); + } + break; + case F3DZEXOpcode::G_QUAD: + { + int aa = ((data & 0x00FF000000000000ULL) >> 48) / 2; + int bb = ((data & 0x0000FF0000000000ULL) >> 40) / 2; + int cc = ((data & 0x000000FF00000000ULL) >> 32) / 2; + int dd = ((data & 0x000000000000FFULL)) / 2; + sprintf(line, "gsSP1Quadrangle(%i, %i, %i, %i, 0),", aa, bb, cc, dd); + } + break; + case F3DZEXOpcode::G_VTX: + { + int nn = (data & 0x000FF00000000000ULL) >> 44; + int aa = (data & 0x000000FF00000000ULL) >> 32; + uint32_t vtxAddr = SEG2FILESPACE(data); + + if (GETSEGNUM(data) == 0x80) // Are these vertices defined in code? + vtxAddr -= SEG2FILESPACE(parent->baseAddress); + + sprintf(line, "gsSPVertex(%sVtx_%06X, %i, %i),", prefix.c_str(), vtxAddr, nn, ((aa >> 1) - nn)); + + { + uint32_t currentPtr = data & 0x00FFFFFF; + + if (GETSEGNUM(data) == 0x80) // Are these vertices defined in code? + currentPtr -= SEG2FILESPACE(parent->baseAddress); + + vector vtxList = vector(); + + vtxList.reserve(nn); + + for (int i = 0; i < nn; i++) + { + Vertex vtx = Vertex(fileData, currentPtr); + vtxList.push_back(vtx); + + currentPtr += 16; + } + + vertices[vtxAddr] = vtxList; + } + + } + break; + case F3DZEXOpcode::G_SETTIMG: // HOTSPOT + { + int __ = (data & 0x00FF000000000000) >> 48; + int www = (data & 0x00000FFF00000000) >> 32; + string fmtTbl[] = { "G_IM_FMT_RGBA", "G_IM_FMT_YUV", "G_IM_FMT_CI", "G_IM_FMT_IA", "G_IM_FMT_I" }; + string sizTbl[] = { "G_IM_SIZ_4b", "G_IM_SIZ_8b", "G_IM_SIZ_16b", "G_IM_SIZ_32b" }; + + uint32_t fmt = (__ & 0xE0) >> 5; + uint32_t siz = (__ & 0x18) >> 3; + + if (Globals::Instance->debugMessages) + printf("TextureGenCheck G_SETTIMG\n"); + + TextureGenCheck(prefix); // HOTSPOT + + lastTexFmt = (F3DZEXTexFormats)fmt; + lastTexSiz = (F3DZEXTexSizes)siz; + lastTexSeg = data; + lastTexAddr = data & 0x00FFFFFF; + + if (GETSEGNUM(lastTexSeg) == 0x80) // Is this texture defined in code? + lastTexAddr -= SEG2FILESPACE(parent->baseAddress); + + int segmentNumber = (data >> 24) & 0xFF; + + if (segmentNumber != 2) + { + char texStr[2048]; + + int32_t texAddress = SEG2FILESPACE(data); + + Declaration* texDecl = nullptr; + + if (parent != nullptr) + { + if (Globals::Instance->HasSegment(segmentNumber)) + texDecl = parent->GetDeclaration(texAddress); + else + texDecl = parent->GetDeclaration(data); + } + + if (texDecl != nullptr) + sprintf(texStr, "%s", texDecl->varName.c_str()); + else if (data != 0 && Globals::Instance->HasSegment(segmentNumber)) + sprintf(texStr, "%sTex_%06X", prefix.c_str(), texAddress); + else + { + // TEST: CHECK OTHER FILES FOR REF + //if (segmentNumber == 4) + //{ + //Globals::Instance->FindSymbolSegRef(segmentNumber, texAddress); + //} + //else + { + sprintf(texStr, "0x%08lX", data); + } + } + + sprintf(line, "gsDPSetTextureImage(%s, %s, %i, %s),", fmtTbl[fmt].c_str(), sizTbl[siz].c_str(), www + 1, texStr); + } + else + { + //sprintf(line, "gsDPSetTextureImage(%s, %s, %i, 0x%08X),", fmtTbl[fmt].c_str(), sizTbl[siz].c_str(), www + 1, data & 0xFFFFFFFF); + sprintf(line, "gsDPSetTextureImage(%s, %s, %i, %sTex_%06X),", fmtTbl[fmt].c_str(), sizTbl[siz].c_str(), www + 1, scene->GetName().c_str(), data & 0x00FFFFFF); + } + } + break; + case F3DZEXOpcode::G_GEOMETRYMODE: + { + int cccccc = (data & 0x00FFFFFF00000000) >> 32; + int ssssssss = (data & 0xFFFFFFFF); + string geoModeStr = "G_TEXTURE_ENABLE"; + + int geoModeParam = ~cccccc; + + if (ssssssss != 0) + geoModeParam = ssssssss; + + if (geoModeParam & 0x00000001) + geoModeStr += " | G_ZBUFFER"; + + if (geoModeParam & 0x00000004) + geoModeStr += " | G_SHADE"; + + if (geoModeParam & 0x00000200) + geoModeStr += " | G_CULL_FRONT"; + + if (geoModeParam & 0x00000400) + geoModeStr += " | G_CULL_BACK"; + + if (geoModeParam & 0x00010000) + geoModeStr += " | G_FOG"; + + if (geoModeParam & 0x00020000) + geoModeStr += " | G_LIGHTING"; + + if (geoModeParam & 0x00040000) + geoModeStr += " | G_TEXTURE_GEN"; + + if (geoModeParam & 0x00080000) + geoModeStr += " | G_TEXTURE_GEN_LINEAR"; + + if (geoModeParam & 0x00200000) + geoModeStr += " | G_SHADING_SMOOTH"; + + if (geoModeParam & 0x00800000) + geoModeStr += " | G_CLIPPING"; + + if (ssssssss != 0) + { + if ((~cccccc & 0xFF000000) != 0) + sprintf(line, "gsSPSetGeometryMode(%s),", geoModeStr.c_str()); + else + sprintf(line, "gsSPLoadGeometryMode(%s),", geoModeStr.c_str()); + } + else + sprintf(line, "gsSPClearGeometryMode(%s),", geoModeStr.c_str()); + + //sprintf(line, "gsSPGeometryMode(0x%08X, 0x%08X),", ~cccccc, ssssssss); + } + break; + case F3DZEXOpcode::G_SETPRIMCOLOR: + { + int mm = (data & 0x0000FF0000000000) >> 40; + int ff = (data & 0x000000FF00000000) >> 32; + int rr = (data & 0x00000000FF000000) >> 24; + int gg = (data & 0x0000000000FF0000) >> 16; + int bb = (data & 0x000000000000FF00) >> 8; + int aa = (data & 0x00000000000000FF) >> 0; + sprintf(line, "gsDPSetPrimColor(%i, %i, %i, %i, %i, %i),", mm, ff, rr, gg, bb, aa); + } + break; + case F3DZEXOpcode::G_SETOTHERMODE_L: + { + int ss = (data & 0x0000FF0000000000) >> 40; + int nn = (data & 0x000000FF00000000) >> 32; + int dd = (data & 0xFFFFFFFF); + + int sft = 32 - (nn + 1) - ss; + + //if (sft == 3) + if (false) + { + int mode1 = (dd & 0xCCCC0000) >> 0; + int mode2 = (dd & 0x33330000) >> 0; + + // TODO: Jesus Christ This is Messy + + uint32_t tblA[] = + { + G_RM_FOG_SHADE_A, G_RM_FOG_PRIM_A, G_RM_PASS, G_RM_AA_ZB_OPA_SURF, + G_RM_AA_ZB_XLU_SURF, G_RM_AA_ZB_OPA_DECAL, G_RM_AA_ZB_XLU_DECAL, + G_RM_AA_ZB_OPA_INTER, G_RM_AA_ZB_XLU_INTER, G_RM_AA_ZB_XLU_LINE, + G_RM_AA_ZB_DEC_LINE, G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_INTER, + G_RM_AA_ZB_SUB_SURF, G_RM_AA_ZB_PCL_SURF, G_RM_AA_ZB_OPA_TERR, + G_RM_AA_ZB_TEX_TERR, G_RM_AA_ZB_SUB_TERR, G_RM_RA_ZB_OPA_SURF, + G_RM_RA_ZB_OPA_DECAL, G_RM_RA_ZB_OPA_INTER, G_RM_AA_OPA_SURF, + G_RM_AA_XLU_SURF, G_RM_AA_XLU_LINE, G_RM_AA_DEC_LINE, + G_RM_AA_TEX_EDGE, G_RM_AA_SUB_SURF, G_RM_AA_PCL_SURF, + G_RM_AA_OPA_TERR, G_RM_AA_TEX_TERR, G_RM_AA_SUB_TERR, + G_RM_RA_OPA_SURF, G_RM_ZB_OPA_SURF, G_RM_ZB_XLU_SURF, + G_RM_ZB_OPA_DECAL, G_RM_ZB_XLU_DECAL, G_RM_ZB_CLD_SURF, + G_RM_ZB_OVL_SURF, G_RM_ZB_PCL_SURF, G_RM_OPA_SURF, + G_RM_XLU_SURF, G_RM_CLD_SURF, G_RM_TEX_EDGE, G_RM_PCL_SURF, + G_RM_ADD, G_RM_NOOP, G_RM_VISCVG, G_RM_OPA_CI + }; + + uint32_t tblB[] = + { + G_RM_AA_ZB_OPA_SURF2, + G_RM_AA_ZB_XLU_SURF2, G_RM_AA_ZB_OPA_DECAL2, G_RM_AA_ZB_XLU_DECAL2, + G_RM_AA_ZB_OPA_INTER2, G_RM_AA_ZB_XLU_INTER2, G_RM_AA_ZB_XLU_LINE2, + G_RM_AA_ZB_DEC_LINE2, G_RM_AA_ZB_TEX_EDGE2, G_RM_AA_ZB_TEX_INTER2, + G_RM_AA_ZB_SUB_SURF2, G_RM_AA_ZB_PCL_SURF2, G_RM_AA_ZB_OPA_TERR2, + G_RM_AA_ZB_TEX_TERR2, G_RM_AA_ZB_SUB_TERR2, G_RM_RA_ZB_OPA_SURF2, + G_RM_RA_ZB_OPA_DECAL2, G_RM_RA_ZB_OPA_INTER2, G_RM_AA_OPA_SURF2, + G_RM_AA_XLU_SURF2, G_RM_AA_XLU_LINE2, G_RM_AA_DEC_LINE2, + G_RM_AA_TEX_EDGE2, G_RM_AA_SUB_SURF2, G_RM_AA_PCL_SURF2, + G_RM_AA_OPA_TERR2, G_RM_AA_TEX_TERR2, G_RM_AA_SUB_TERR2, + G_RM_RA_OPA_SURF2, G_RM_ZB_OPA_SURF2, G_RM_ZB_XLU_SURF2, + G_RM_ZB_OPA_DECAL2, G_RM_ZB_XLU_DECAL2, G_RM_ZB_CLD_SURF2, + G_RM_ZB_OVL_SURF2, G_RM_ZB_PCL_SURF2, G_RM_OPA_SURF2, + G_RM_XLU_SURF2, G_RM_CLD_SURF2, G_RM_TEX_EDGE2, G_RM_PCL_SURF2, + G_RM_ADD2, G_RM_NOOP2,G_RM_VISCVG2, G_RM_OPA_CI2 + }; + + map str = + { + { G_RM_FOG_SHADE_A, "G_RM_FOG_SHADE_A" }, + { G_RM_FOG_PRIM_A, "G_RM_FOG_PRIM_A" }, + { G_RM_PASS, "G_RM_PASS" }, + { G_RM_AA_ZB_OPA_SURF, "G_RM_AA_ZB_OPA_SURF" }, + { G_RM_AA_ZB_OPA_SURF2, "G_RM_AA_ZB_OPA_SURF2" }, + { G_RM_AA_ZB_XLU_SURF, "G_RM_AA_ZB_XLU_SURF" }, + { G_RM_AA_ZB_XLU_SURF2, "G_RM_AA_ZB_XLU_SURF2" }, + { G_RM_AA_ZB_OPA_DECAL, "G_RM_AA_ZB_OPA_DECAL" }, + { G_RM_AA_ZB_OPA_DECAL2, "G_RM_AA_ZB_OPA_DECAL2" }, + { G_RM_AA_ZB_XLU_DECAL, "G_RM_AA_ZB_XLU_DECAL" }, + { G_RM_AA_ZB_XLU_DECAL2, "G_RM_AA_ZB_XLU_DECAL2" }, + { G_RM_AA_ZB_OPA_INTER, "G_RM_AA_ZB_OPA_INTER" }, + { G_RM_AA_ZB_OPA_INTER2, "G_RM_AA_ZB_OPA_INTER2" }, + { G_RM_AA_ZB_XLU_INTER, "G_RM_AA_ZB_XLU_INTER" }, + { G_RM_AA_ZB_XLU_INTER2, "G_RM_AA_ZB_XLU_INTER2" }, + { G_RM_AA_ZB_XLU_LINE, "G_RM_AA_ZB_XLU_LINE" }, + { G_RM_AA_ZB_XLU_LINE2, "G_RM_AA_ZB_XLU_LINE2" }, + { G_RM_AA_ZB_DEC_LINE, "G_RM_AA_ZB_DEC_LINE" }, + { G_RM_AA_ZB_DEC_LINE2, "G_RM_AA_ZB_DEC_LINE2" }, + { G_RM_AA_ZB_TEX_EDGE, "G_RM_AA_ZB_TEX_EDGE" }, + { G_RM_AA_ZB_TEX_EDGE2, "G_RM_AA_ZB_TEX_EDGE2" }, + { G_RM_AA_ZB_TEX_INTER, "G_RM_AA_ZB_TEX_INTER" }, + { G_RM_AA_ZB_TEX_INTER2, "G_RM_AA_ZB_TEX_INTER2" }, + { G_RM_AA_ZB_SUB_SURF, "G_RM_AA_ZB_SUB_SURF" }, + { G_RM_AA_ZB_SUB_SURF2, "G_RM_AA_ZB_SUB_SURF2" }, + { G_RM_AA_ZB_PCL_SURF, "G_RM_AA_ZB_PCL_SURF" }, + { G_RM_AA_ZB_PCL_SURF2, "G_RM_AA_ZB_PCL_SURF2" }, + { G_RM_AA_ZB_OPA_TERR, "G_RM_AA_ZB_OPA_TERR" }, + { G_RM_AA_ZB_OPA_TERR2, "G_RM_AA_ZB_OPA_TERR2" }, + { G_RM_AA_ZB_TEX_TERR, "G_RM_AA_ZB_TEX_TERR" }, + { G_RM_AA_ZB_TEX_TERR2, "G_RM_AA_ZB_TEX_TERR2" }, + { G_RM_AA_ZB_SUB_TERR, "G_RM_AA_ZB_SUB_TERR" }, + { G_RM_AA_ZB_SUB_TERR2, "G_RM_AA_ZB_SUB_TERR2" }, + { G_RM_RA_ZB_OPA_SURF, "G_RM_RA_ZB_OPA_SURF" }, + { G_RM_RA_ZB_OPA_SURF2, "G_RM_RA_ZB_OPA_SURF2" }, + { G_RM_RA_ZB_OPA_DECAL, "G_RM_RA_ZB_OPA_DECAL" }, + { G_RM_RA_ZB_OPA_DECAL2, "G_RM_RA_ZB_OPA_DECAL2" }, + { G_RM_RA_ZB_OPA_INTER, "G_RM_RA_ZB_OPA_INTER" }, + { G_RM_RA_ZB_OPA_INTER2, "G_RM_RA_ZB_OPA_INTER2" }, + { G_RM_AA_OPA_SURF, "G_RM_AA_OPA_SURF" }, + { G_RM_AA_OPA_SURF2, "G_RM_AA_OPA_SURF2" }, + { G_RM_AA_XLU_SURF, "G_RM_AA_XLU_SURF" }, + { G_RM_AA_XLU_SURF2, "G_RM_AA_XLU_SURF2" }, + { G_RM_AA_XLU_LINE, "G_RM_AA_XLU_LINE" }, + { G_RM_AA_XLU_LINE2, "G_RM_AA_XLU_LINE2" }, + { G_RM_AA_DEC_LINE, "G_RM_AA_DEC_LINE" }, + { G_RM_AA_DEC_LINE2, "G_RM_AA_DEC_LINE2" }, + { G_RM_AA_TEX_EDGE, "G_RM_AA_TEX_EDGE" }, + { G_RM_AA_TEX_EDGE2, "G_RM_AA_TEX_EDGE2" }, + { G_RM_AA_SUB_SURF, "G_RM_AA_SUB_SURF" }, + { G_RM_AA_SUB_SURF2, "G_RM_AA_SUB_SURF2" }, + { G_RM_AA_PCL_SURF, "G_RM_AA_PCL_SURF" }, + { G_RM_AA_PCL_SURF2, "G_RM_AA_PCL_SURF2" }, + { G_RM_AA_OPA_TERR, "G_RM_AA_OPA_TERR" }, + { G_RM_AA_OPA_TERR2, "G_RM_AA_OPA_TERR2" }, + { G_RM_AA_TEX_TERR, "G_RM_AA_TEX_TERR" }, + { G_RM_AA_TEX_TERR2, "G_RM_AA_TEX_TERR2" }, + { G_RM_AA_TEX_TERR, "G_RM_AA_TEX_TERR" }, + { G_RM_AA_TEX_TERR2, "G_RM_AA_TEX_TERR2" }, + { G_RM_AA_SUB_TERR, "G_RM_AA_SUB_TERR" }, + { G_RM_AA_SUB_TERR2, "G_RM_AA_SUB_TERR2" }, + { G_RM_RA_OPA_SURF, "G_RM_RA_OPA_SURF" }, + { G_RM_RA_OPA_SURF2, "G_RM_RA_OPA_SURF2" }, + { G_RM_ZB_OPA_SURF, "G_RM_ZB_OPA_SURF" }, + { G_RM_ZB_OPA_SURF2, "G_RM_ZB_OPA_SURF2" }, + { G_RM_ZB_XLU_SURF, "G_RM_ZB_XLU_SURF" }, + { G_RM_ZB_XLU_SURF2, "G_RM_ZB_XLU_SURF2" }, + { G_RM_ZB_OPA_DECAL, "G_RM_ZB_OPA_DECAL" }, + { G_RM_ZB_OPA_DECAL2, "G_RM_ZB_OPA_DECAL2" }, + { G_RM_ZB_XLU_DECAL, "G_RM_ZB_XLU_DECAL" }, + { G_RM_ZB_XLU_DECAL2, "G_RM_ZB_XLU_DECAL2" }, + { G_RM_ZB_CLD_SURF, "G_RM_ZB_CLD_SURF" }, + { G_RM_ZB_CLD_SURF2, "G_RM_ZB_CLD_SURF2" }, + { G_RM_ZB_OVL_SURF, "G_RM_ZB_OVL_SURF" }, + { G_RM_ZB_OVL_SURF2, "G_RM_ZB_OVL_SURF2" }, + { G_RM_ZB_PCL_SURF, "G_RM_ZB_PCL_SURF" }, + { G_RM_ZB_PCL_SURF2, "G_RM_ZB_PCL_SURF2" }, + { G_RM_OPA_SURF, "G_RM_OPA_SURF" }, + { G_RM_OPA_SURF2, "G_RM_OPA_SURF2" }, + { G_RM_XLU_SURF, "G_RM_XLU_SURF" }, + { G_RM_XLU_SURF2, "G_RM_XLU_SURF2" }, + { G_RM_CLD_SURF, "G_RM_CLD_SURF" }, + { G_RM_CLD_SURF2, "G_RM_CLD_SURF2" }, + { G_RM_TEX_EDGE, "G_RM_TEX_EDGE" }, + { G_RM_TEX_EDGE2, "G_RM_TEX_EDGE2" }, + { G_RM_PCL_SURF, "G_RM_PCL_SURF" }, + { G_RM_PCL_SURF2, "G_RM_PCL_SURF2" }, + { G_RM_ADD, "G_RM_ADD" }, + { G_RM_ADD2, "G_RM_ADD2" }, + { G_RM_NOOP, "G_RM_NOOP" }, + { G_RM_NOOP2, "G_RM_NOOP2" }, + { G_RM_VISCVG, "G_RM_VISCVG" }, + { G_RM_VISCVG2, "G_RM_VISCVG2" }, + { G_RM_OPA_CI, "G_RM_OPA_CI" }, + { G_RM_OPA_CI2, "G_RM_OPA_CI2" }, + }; + + for (int k = 0; k < sizeof(tblA) / 4; k++) + { + if ((dd & tblA[k]) == tblA[k]) + { + if (tblA[k] > mode1) + mode1 = tblA[k]; + + int bp = 0; + } + } + + for (int k = 0; k < sizeof(tblB) / 4; k++) + { + if ((dd & tblB[k]) == tblB[k]) + { + if (tblB[k] > mode2) + mode2 = tblB[k]; + + int bp = 0; + } + } + + sprintf(line, "gsDPSetRenderMode(%s, %s),", str[mode1].c_str(), str[mode2].c_str()); + } + else + sprintf(line, "gsSPSetOtherMode(0xE2, %i, %i, 0x%08X),", sft, nn + 1, dd); + } + break; + case F3DZEXOpcode::G_SETOTHERMODE_H: + { + int ss = (data & 0x0000FF0000000000) >> 40; + int nn = (data & 0x000000FF00000000) >> 32; + int dd = (data & 0xFFFFFFFF); + + int sft = 32 - (nn + 1) - ss; + + if (sft == 14) // G_MDSFT_TEXTLUT + { + string types[] = { "G_TT_NONE", "G_TT_NONE", "G_TT_RGBA16", "G_TT_IA16" }; + sprintf(line, "gsDPSetTextureLUT(%s),", types[dd >> 14].c_str()); + } + else + sprintf(line, "gsSPSetOtherMode(0xE3, %i, %i, 0x%08X),", sft, nn + 1, dd); + } + break; + case F3DZEXOpcode::G_SETTILE: + { + int fff = (data & 0b0000000011100000000000000000000000000000000000000000000000000000) >> 53; + int ii = (data & 0b0000000000011000000000000000000000000000000000000000000000000000) >> 51; + int nnnnnnnnn = (data & 0b0000000000000011111111100000000000000000000000000000000000000000) >> 41; + int mmmmmmmmm = (data & 0b0000000000000000000000011111111100000000000000000000000000000000) >> 32; + int ttt = (data & 0b0000000000000000000000000000000000000111000000000000000000000000) >> 24; + int pppp = (data & 0b0000000000000000000000000000000000000000111100000000000000000000) >> 20; + int cc = (data & 0b0000000000000000000000000000000000000000000011000000000000000000) >> 18; + int aaaa = (data & 0b0000000000000000000000000000000000000000000000111100000000000000) >> 14; + int ssss = (data & 0b0000000000000000000000000000000000000000000000000011110000000000) >> 10; + int dd = (data & 0b0000000000000000000000000000000000000000000000000000001100000000) >> 8; + int bbbb = (data & 0b0000000000000000000000000000000000000000000000000000000011110000) >> 4; + int uuuu = (data & 0b0000000000000000000000000000000000000000000000000000000000001111); + + string fmtTbl[] = { "G_IM_FMT_RGBA", "G_IM_FMT_YUV", "G_IM_FMT_CI", "G_IM_FMT_IA", "G_IM_FMT_I" }; + string sizTbl[] = { "G_IM_SIZ_4b", "G_IM_SIZ_8b", "G_IM_SIZ_16b", "G_IM_SIZ_32b" }; + + if (fff == (int)F3DZEXTexFormats::G_IM_FMT_CI) + lastCISiz = (F3DZEXTexSizes)ii; + + lastTexSizTest = (F3DZEXTexSizes)ii; + + sprintf(line, "gsDPSetTile(%s, %s, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i),", fmtTbl[fff].c_str(), sizTbl[ii].c_str(), nnnnnnnnn, mmmmmmmmm, ttt, pppp, cc, aaaa, ssss, dd, bbbb, uuuu); + } + break; + case F3DZEXOpcode::G_SETTILESIZE: + { + int sss = (data & 0x00FFF00000000000) >> 44; + int ttt = (data & 0x00000FFF00000000) >> 32; + int uuu = (data & 0x0000000000FFF000) >> 12; + int vvv = (data & 0x0000000000000FFF); + int i = (data & 0x000000000F000000) >> 24; + + int shiftAmtW = 2; + int shiftAmtH = 2; + + if (lastTexSizTest == F3DZEXTexSizes::G_IM_SIZ_8b && lastTexFmt == F3DZEXTexFormats::G_IM_FMT_IA) + shiftAmtW = 3; + + //if (lastTexFmt == F3DZEXTexFormats::G_IM_FMT_I || lastTexFmt == F3DZEXTexFormats::G_IM_FMT_CI) + if (lastTexSizTest == F3DZEXTexSizes::G_IM_SIZ_4b) + shiftAmtW = 3; + + if (lastTexSizTest == F3DZEXTexSizes::G_IM_SIZ_4b && lastTexFmt == F3DZEXTexFormats::G_IM_FMT_IA) + shiftAmtH = 3; + + + lastTexWidth = (uuu >> shiftAmtW) + 1; + lastTexHeight = (vvv >> shiftAmtH) + 1; + + if (Globals::Instance->debugMessages) + printf("lastTexWidth: %i lastTexHeight: %i, lastTexSizTest: 0x%x, lastTexFmt: 0x%x\n", lastTexWidth, lastTexHeight, (uint32_t)lastTexSizTest, (uint32_t)lastTexFmt); + + if (Globals::Instance->debugMessages) + printf("TextureGenCheck G_SETTILESIZE\n"); + + TextureGenCheck(prefix); + + sprintf(line, "gsDPSetTileSize(%i, %i, %i, %i, %i),", i, sss, ttt, uuu, vvv); + } + break; + case F3DZEXOpcode::G_LOADBLOCK: + { + int sss = (data & 0x00FFF00000000000) >> 48; + int ttt = (data & 0x00000FFF00000000) >> 36; + int i = (data & 0x000000000F000000) >> 24; + int xxx = (data & 0x0000000000FFF000) >> 12; + int ddd = (data & 0x0000000000000FFF); + + //lastTexHeight = (ddd + 1) / 16; + + lastTexLoaded = true; + + //TextureGenCheck(prefix); + + sprintf(line, "gsDPLoadBlock(%i, %i, %i, %i, %i),", i, sss, ttt, xxx, ddd); + } + break; + case F3DZEXOpcode::G_TEXTURE: + { + int ____ = (data & 0x0000FFFF00000000) >> 32; + int ssss = (data & 0x00000000FFFF0000) >> 16; + int tttt = (data & 0x000000000000FFFF); + int lll = (____ & 0x3800) >> 11; + int ddd = (____ & 0x700) >> 8; + int nnnnnnn = (____ & 0xFE) >> 1; + + sprintf(line, "gsSPTexture(%i, %i, %i, %i, %s),", ssss, tttt, lll, ddd, nnnnnnn == 1 ? "G_ON" : "G_OFF"); + } + break; + case F3DZEXOpcode::G_RDPSETOTHERMODE: + { + int hhhhhh = (data & 0x00FFFFFF00000000) >> 32; + int llllllll = (data & 0x00000000FFFFFFFF); + + sprintf(line, "gsDPSetOtherMode(%i, %i),", hhhhhh, llllllll); + } + break; + case F3DZEXOpcode::G_POPMTX: + { + sprintf(line, "gsSPPopMatrix(%li),", data); + } + break; + case F3DZEXOpcode::G_LOADTLUT: + { + int t = (data & 0x0000000007000000) >> 24; + int ccc = (data & 0x00000000003FF000) >> 14; + + lastTexWidth = sqrt(ccc + 1); + lastTexHeight = sqrt(ccc + 1); + + lastTexLoaded = true; + + if (Globals::Instance->debugMessages) + printf("TextureGenCheck G_LOADTLUT (lastCISiz: %i)\n", (uint32_t)lastCISiz); + + TextureGenCheck(prefix); + + sprintf(line, "gsDPLoadTLUTCmd(%i, %i),", t, ccc); + } + break; + case F3DZEXOpcode::G_SETENVCOLOR: + { + uint8_t r = (uint8_t)((data & 0xFF000000) >> 24); + uint8_t g = (uint8_t)((data & 0x00FF0000) >> 16); + uint8_t b = (uint8_t)((data & 0xFF00FF00) >> 8); + uint8_t a = (uint8_t)((data & 0x000000FF) >> 0); + + sprintf(line, "gsDPSetEnvColor(%i, %i, %i, %i),", r, g, b, a); + } + break; + case F3DZEXOpcode::G_SETCOMBINE: + { + int a0 = (data & 0b000000011110000000000000000000000000000000000000000000000000000) >> 52; + int c0 = (data & 0b000000000001111100000000000000000000000000000000000000000000000) >> 47; + int aa0 = (data & 0b00000000000000011100000000000000000000000000000000000000000000) >> 44; + int ac0 = (data & 0b00000000000000000011100000000000000000000000000000000000000000) >> 41; + int a1 = (data & 0b000000000000000000000011110000000000000000000000000000000000000) >> 37; + int c1 = (data & 0b000000000000000000000000001111100000000000000000000000000000000) >> 32; + int b0 = (data & 0b000000000000000000000000000000011110000000000000000000000000000) >> 28; + int b1 = (data & 0b000000000000000000000000000000000001111000000000000000000000000) >> 24; + int aa1 = (data & 0b00000000000000000000000000000000000000111000000000000000000000) >> 21; + int ac1 = (data & 0b00000000000000000000000000000000000000000111000000000000000000) >> 18; + int d0 = (data & 0b000000000000000000000000000000000000000000000111000000000000000) >> 15; + int ab0 = (data & 0b00000000000000000000000000000000000000000000000111000000000000) >> 12; + int ad0 = (data & 0b00000000000000000000000000000000000000000000000000111000000000) >> 9; + int d1 = (data & 0b000000000000000000000000000000000000000000000000000000111000000) >> 6; + int ab1 = (data & 0b00000000000000000000000000000000000000000000000000000000111000) >> 3; + int ad1 = (data & 0b00000000000000000000000000000000000000000000000000000000000111) >> 0; + + string modes[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "1", "COMBINED_ALPHA", + "TEXEL0_ALPHA", "TEXEL1_ALPHA", "PRIMITIVE_ALPHA", "SHADE_ALPHA", "ENV_ALPHA", "LOD_FRACTION", "PRIM_LOD_FRAC", "K5", + "17", "18", "19", "20", "21", "22", "23", "24", + "25", "26", "27", "28", "29", "30", "31", "0" }; + + string modes2[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "1", "0" }; + + sprintf(line, "gsDPSetCombineLERP(%s, %s, %s, %s, %s, %s, %s, %s,\n %s, %s, %s, %s, %s, %s, %s, %s),", + modes[a0].c_str(), modes[b0].c_str(), modes[c0].c_str(), modes[d0].c_str(), + modes2[aa0].c_str(), modes2[ab0].c_str(), modes2[ac0].c_str(), modes2[ad0].c_str(), + modes[a1].c_str(), modes[b1].c_str(), modes[c1].c_str(), modes[d1].c_str(), + modes2[aa1].c_str(), modes2[ab1].c_str(), modes2[ac1].c_str(), modes2[ad1].c_str()); + } + break; + case F3DZEXOpcode::G_RDPLOADSYNC: + sprintf(line, "gsDPLoadSync(),"); + break; + case F3DZEXOpcode::G_RDPPIPESYNC: + sprintf(line, "gsDPPipeSync(),"); + break; + case F3DZEXOpcode::G_RDPTILESYNC: + sprintf(line, "gsDPTileSync(),"); + break; + case F3DZEXOpcode::G_RDPFULLSYNC: + sprintf(line, "gsDPFullSync(),"); + break; + case F3DZEXOpcode::G_ENDDL: + sprintf(line, "gsSPEndDisplayList(),"); + + if (Globals::Instance->debugMessages) + printf("TextureGenCheck G_ENDDL\n"); + + TextureGenCheck(prefix); + break; + case F3DZEXOpcode::G_RDPHALF_1: + { + uint64_t data2 = instructions[i + 1]; + uint32_t h = (data & 0xFFFFFFFF); + F3DZEXOpcode opcode2 = (F3DZEXOpcode)(instructions[i + 1] >> 56); + + if (opcode2 == F3DZEXOpcode::G_BRANCH_Z) + { + uint32_t a = (data2 & 0x00FFF00000000000) >> 44; + uint32_t b = (data2 & 0x00000FFF00000000) >> 32; + uint32_t z = (data2 & 0x00000000FFFFFFFF) >> 0; + + //sprintf(line, "gsDPWord(%i, 0),", h); + sprintf(line, "gsSPBranchLessZraw(%sDlist0x%06X, 0x%02X, 0x%02X),", prefix.c_str(), h & 0x00FFFFFF, (a / 5) | (b / 2), z); + + ZDisplayList* nList = new ZDisplayList(fileData, h & 0x00FFFFFF, GetDListLength(fileData, h & 0x00FFFFFF)); + nList->scene = scene; + otherDLists.push_back(nList); + + i++; + } + } + break; + /*case F3DZEXOpcode::G_BRANCH_Z: + { + uint8_t h = (data & 0xFFFFFFFF); + + sprintf(line, "gsSPBranchLessZraw(%i, %i, %i),", h); + } + break;*/ + case F3DZEXOpcode::G_MTX: + { + // TODO: FINISH THIS + uint32_t pp = (data & 0x000000FF00000000) >> 32; + uint32_t mm = (data & 0x00000000FFFFFFFF); + std::string matrixRef = ""; + + if (Globals::Instance->symbolMap.find(mm) != Globals::Instance->symbolMap.end()) + matrixRef = StringHelper::Sprintf("&%s", Globals::Instance->symbolMap[mm].c_str()); + else + matrixRef = StringHelper::Sprintf("0x%08X", mm); + + sprintf(line, "gsSPMatrix(%s, 0x%02X),", matrixRef.c_str(), pp ^ 0x01); + } + break; + default: + sprintf(line, "// Opcode 0x%02X unimplemented!", (uint32_t)opcode); + break; + } + } + + auto end = chrono::steady_clock::now(); + auto diff = chrono::duration_cast(end - start).count(); + +#if _MSC_VER + //if (diff > 5) + //printf("F3DOP: 0x%02X, TIME: %ims\n", opcode, diff); +#endif + + sourceOutput += line; + + if (i < instructions.size() - 1) + sourceOutput += "\n"; + } + + // Iterate through our vertex lists, connect intersecting lists. + if (vertices.size() > 0) + { + vector>> verticesSorted(vertices.begin(), vertices.end()); + + sort(verticesSorted.begin(), verticesSorted.end(), [](const auto& lhs, const auto& rhs) + { + return lhs.first < rhs.first; + }); + + for (int i = 0; i < verticesSorted.size() - 1; i++) + { + //int vtxSize = verticesSorted[i].second.size() * 16; + int vtxSize = (int)vertices[verticesSorted[i].first].size() * 16; + + if ((verticesSorted[i].first + vtxSize) > verticesSorted[i + 1].first) + { + int intersectAmt = (verticesSorted[i].first + vtxSize) - verticesSorted[i + 1].first; + int intersectIndex = intersectAmt / 16; + + for (int j = intersectIndex; j < verticesSorted[i + 1].second.size(); j++) + { + vertices[verticesSorted[i].first].push_back(verticesSorted[i + 1].second[j]); + } + + defines += StringHelper::Sprintf("#define %sVtx_%06X ((u32)%sVtx_%06X + 0x%06X)\n", prefix.c_str(), verticesSorted[i + 1].first, prefix.c_str(), verticesSorted[i].first, verticesSorted[i + 1].first - verticesSorted[i].first); + + int nSize = (int)vertices[verticesSorted[i].first].size(); + + vertices.erase(verticesSorted[i + 1].first); + verticesSorted.erase(verticesSorted.begin() + i + 1); + + i--; + } + } + + if (scene == nullptr) // TODO: Bit of a hack but it works for now... + parent->defines += defines; + + // Generate Vertex Declarations + for (pair> item : vertices) + { + string declaration = ""; + + int curAddr = item.first; + + for (Vertex vtx : item.second) + { + if (curAddr != item.first) + declaration += "\n"; + + declaration += StringHelper::Sprintf(" VTX(%i, %i, %i, %i, %i, %i, %i, %i, %i),", + vtx.x, vtx.y, vtx.z, vtx.s, vtx.t, vtx.r, vtx.g, vtx.b, vtx.a); + + curAddr += 16; + } + + vtxDeclarations[item.first] = declaration; + + if (parent != nullptr) + { + parent->AddDeclarationArray(item.first, DeclarationAlignment::None, item.second.size() * 16, "Vtx", + StringHelper::Sprintf("%sVtx_%06X", prefix.c_str(), item.first, item.second.size()), 0, declaration); + } + } + + // Check for texture intersections + { + if (scene != nullptr && scene->textures.size() != 0) + { + vector> texturesSorted(scene->textures.begin(), scene->textures.end()); + + sort(texturesSorted.begin(), texturesSorted.end(), [](const auto& lhs, const auto& rhs) + { + return lhs.first < rhs.first; + }); + + for (int i = 0; i < texturesSorted.size() - 1; i++) + { + int texSize = scene->textures[texturesSorted[i].first]->GetRawDataSize(); + + if ((texturesSorted[i].first + texSize) > texturesSorted[i + 1].first) + { + int intersectAmt = (texturesSorted[i].first + texSize) - texturesSorted[i + 1].first; + + defines += StringHelper::Sprintf("#define %sTex_%06X ((u32)%sTex_%06X + 0x%06X)\n", scene->GetName().c_str(), texturesSorted[i + 1].first, scene->GetName().c_str(), + texturesSorted[i].first, texturesSorted[i + 1].first - texturesSorted[i].first); + + scene->parent->declarations.erase(texturesSorted[i + 1].first); + scene->textures.erase(texturesSorted[i + 1].first); + texturesSorted.erase(texturesSorted.begin() + i + 1); + + i--; + } + } + + scene->extDefines += defines; + } + + { + vector> texturesSorted(textures.begin(), textures.end()); + + sort(texturesSorted.begin(), texturesSorted.end(), [](const auto& lhs, const auto& rhs) + { + return lhs.first < rhs.first; + }); + + for (int i = 0; i < texturesSorted.size() - 1; i++) + { + if (texturesSorted.size() == 0) // ????? + break; + + int texSize = textures[texturesSorted[i].first]->GetRawDataSize(); + + if ((texturesSorted[i].first + texSize) > texturesSorted[i + 1].first) + { + int intersectAmt = (texturesSorted[i].first + texSize) - texturesSorted[i + 1].first; + + defines += StringHelper::Sprintf("#define %sTex_%06X ((u32)%sTex_%06X + 0x%06X)\n", prefix.c_str(), texturesSorted[i + 1].first, prefix.c_str(), + texturesSorted[i].first, texturesSorted[i + 1].first - texturesSorted[i].first); + + textures.erase(texturesSorted[i + 1].first); + texturesSorted.erase(texturesSorted.begin() + i + 1); + + i--; + } + } + } + } + + + // Generate Texture Declarations + for (pair item : textures) + { + string declaration = ""; + + declaration += item.second->GetSourceOutputCode(prefix); + texDeclarations[item.first] = declaration; + + if (parent != nullptr) + { + if (parent->GetDeclaration(item.first) == nullptr) + { + if (Globals::Instance->debugMessages) + printf("SAVING IMAGE TO %s\n", Globals::Instance->outputPath.c_str()); + + item.second->Save(Globals::Instance->outputPath); + + parent->AddDeclarationIncludeArray(item.first, StringHelper::Sprintf("%s/%s.%s.inc.c", + Globals::Instance->outputPath.c_str(), Path::GetFileNameWithoutExtension(item.second->GetName()).c_str(), + item.second->GetExternalExtension().c_str()), item.second->GetRawDataSize(), + "u64", StringHelper::Sprintf("%sTex_%06X", prefix.c_str(), item.first), 0); + } + } + } + + } + + if (parent != nullptr) + { + parent->AddDeclarationArray(rawDataIndex, DeclarationAlignment::None, GetRawDataSize(), "Gfx", StringHelper::Sprintf("%s", name.c_str()), 0, sourceOutput); + return ""; + } + + return sourceOutput; +} + +// HOTSPOT +void ZDisplayList::TextureGenCheck(string prefix) +{ + if (TextureGenCheck(fileData, textures, scene, parent, prefix, lastTexWidth, lastTexHeight, lastTexAddr, lastTexSeg, lastTexFmt, lastTexSiz, lastTexLoaded)) + { + lastTexAddr = 0; + lastTexLoaded = false; + } +} + +// HOTSPOT +bool ZDisplayList::TextureGenCheck(vector fileData, map& textures, ZRoom* scene, ZFile* parent, string prefix, uint32_t texWidth, uint32_t texHeight, uint32_t texAddr, uint32_t texSeg, F3DZEXTexFormats texFmt, F3DZEXTexSizes texSiz, bool texLoaded) +{ + int segmentNumber = (texSeg & 0xFF000000) >> 24; + + if (Globals::Instance->debugMessages) + printf("TextureGenCheck seg=%i width=%i height=%i addr=0x%06X\n", segmentNumber, texWidth, texHeight, texAddr); + + if (texAddr != 0 && texWidth != 0 && texHeight != 0 && texLoaded && Globals::Instance->HasSegment(segmentNumber)) + { + if (segmentNumber != 2) // Not from a scene file + { + ZTexture* tex = ZTexture::FromBinary(TexFormatToTexType(texFmt, texSiz), fileData, texAddr, StringHelper::Sprintf("%sTex_%06X", prefix.c_str(), texAddr), texWidth, texHeight); + + //tex->Save(Globals::Instance->outputPath); + textures[texAddr] = tex; + + return true; + } + else + { + ZTexture* tex = ZTexture::FromBinary(TexFormatToTexType(texFmt, texSiz), scene->GetRawData(), texAddr, + StringHelper::Sprintf("%sTex_%06X", Globals::Instance->lastScene->GetName().c_str(), texAddr), texWidth, texHeight); + + //tex->Save(Globals::Instance->outputPath); + + if (scene != nullptr) + { + scene->textures[texAddr] = tex; + scene->parent->AddDeclarationIncludeArray(texAddr, StringHelper::Sprintf("%s/%s.%s.inc.c", + Globals::Instance->outputPath.c_str(), Path::GetFileNameWithoutExtension(tex->GetName()).c_str(), tex->GetExternalExtension().c_str()), tex->GetRawDataSize(), + "u64", StringHelper::Sprintf("%sTex_%06X", Globals::Instance->lastScene->GetName().c_str(), texAddr), 0); + } + + return true; + } + } + + return false; +} + +TextureType ZDisplayList::TexFormatToTexType(F3DZEXTexFormats fmt, F3DZEXTexSizes siz) +{ + if (fmt == F3DZEXTexFormats::G_IM_FMT_RGBA) + { + if (siz == F3DZEXTexSizes::G_IM_SIZ_16b) + return TextureType::RGBA16bpp; + else if (siz == F3DZEXTexSizes::G_IM_SIZ_32b) + return TextureType::RGBA32bpp; + } + else if (fmt == F3DZEXTexFormats::G_IM_FMT_CI) + { + //if (siz == F3DZEXTexSizes::G_IM_SIZ_8b) + return TextureType::Palette8bpp; + } + else if (fmt == F3DZEXTexFormats::G_IM_FMT_IA) + { + if (siz == F3DZEXTexSizes::G_IM_SIZ_16b) + return TextureType::GrayscaleAlpha16bpp; + else if (siz == F3DZEXTexSizes::G_IM_SIZ_8b) + return TextureType::GrayscaleAlpha8bpp; + } + else if (fmt == F3DZEXTexFormats::G_IM_FMT_I) + { + if (siz == F3DZEXTexSizes::G_IM_SIZ_4b) + return TextureType::Grayscale4bpp; + else if (siz == F3DZEXTexSizes::G_IM_SIZ_8b) + return TextureType::Grayscale8bpp; + else if (siz == F3DZEXTexSizes::G_IM_SIZ_16b) + return TextureType::Grayscale8bpp; + + } + + return TextureType::RGBA16bpp; +} + +void ZDisplayList::Save(string outFolder) +{ + //HLModelIntermediette* mdl = HLModelIntermediette::FromZDisplayList(this); + + // For testing purposes only at the moment... + //if (Globals::Instance->testMode) + //{ + //string xml = mdl->OutputXML(); + //string obj = mdl->ToOBJFile(); + //string fbx = mdl->ToFBXFile(); + + //File::WriteAllText(outFolder + "/" + name + ".mdli", xml); + //File::WriteAllText(outFolder + "/" + name + ".obj", obj); + //File::WriteAllText(outFolder + "/" + name + ".fbx", fbx); + //} +} + +void ZDisplayList::GenerateHLIntermediette(HLFileIntermediette& hlFile) +{ + HLModelIntermediette* mdl = (HLModelIntermediette*)&hlFile; + HLModelIntermediette::FromZDisplayList(mdl, this); + mdl->blocks.push_back(new HLTerminator()); +} + +vector ZDisplayList::GetRawData() +{ + return rawData; +} + +int ZDisplayList::GetRawDataSize() +{ + return (int)instructions.size() * 8; +} + +Vertex::Vertex() +{ + x = 0; + y = 0; + z = 0; + flag = 0; + s = 0; + t = 0; + r = 0; + g = 0; + b = 0; + a = 0; +} + +Vertex::Vertex(int16_t nX, int16_t nY, int16_t nZ, uint16_t nFlag, int16_t nS, int16_t nT, uint8_t nR, uint8_t nG, uint8_t nB, uint8_t nA) +{ + x = nX; + y = nY; + z = nZ; + flag = nFlag; + s = nS; + t = nT; + r = nR; + g = nG; + b = nB; + a = nA; +} + +Vertex::Vertex(std::vector rawData, int rawDataIndex) +{ + uint8_t* data = rawData.data(); + + x = BitConverter::ToInt16BE(data, rawDataIndex + 0); + y = BitConverter::ToInt16BE(data, rawDataIndex + 2); + z = BitConverter::ToInt16BE(data, rawDataIndex + 4); + flag = BitConverter::ToInt16BE(data, rawDataIndex + 6); + s = BitConverter::ToInt16BE(data, rawDataIndex + 8); + t = BitConverter::ToInt16BE(data, rawDataIndex + 10); + r = data[rawDataIndex + 12]; + g = data[rawDataIndex + 13]; + b = data[rawDataIndex + 14]; + a = data[rawDataIndex + 15]; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZDisplayList.h b/tools/ZAPD/ZAPD/ZDisplayList.h new file mode 100644 index 0000000000..7eeac465fe --- /dev/null +++ b/tools/ZAPD/ZAPD/ZDisplayList.h @@ -0,0 +1,265 @@ +#pragma once + +#include "ZResource.h" +#include "ZTexture.h" +#include "ZRoom/ZRoom.h" +#include "tinyxml2.h" + +#include +#include +#include + +enum class F3DZEXOpcode +{ + G_NOOP = 0x00, + G_VTX = 0x01, + G_MODIFYVTX = 0x02, + G_CULLDL = 0x03, + G_BRANCH_Z = 0x04, + G_TRI1 = 0x05, + G_TRI2 = 0x06, + G_QUAD = 0x07, + G_SPECIAL_3 = 0xD3, + G_SPECIAL_2 = 0xD4, + G_SPECIAL_1 = 0xD5, + G_DMA_IO = 0xD6, + G_TEXTURE = 0xD7, + G_POPMTX = 0xD8, + G_GEOMETRYMODE = 0xD9, + G_MTX = 0xDA, + G_MOVEWORD = 0xDB, + G_MOVEMEM = 0xDC, + G_LOAD_UCODE = 0xDD, + G_DL = 0xDE, + G_ENDDL = 0xDF, + G_SPNOOP = 0xE0, + G_RDPHALF_1 = 0xE1, + G_SETOTHERMODE_L = 0xE2, + G_SETOTHERMODE_H = 0xE3, + G_TEXRECT = 0xE4, + G_TEXRECTFLIP = 0xE5, + G_RDPLOADSYNC = 0xE6, + G_RDPPIPESYNC = 0xE7, + G_RDPTILESYNC = 0xE8, + G_RDPFULLSYNC = 0xE9, + G_SETKEYGB = 0xEA, + G_SETKEYR = 0xEB, + G_SETCONVERT = 0xEC, + G_SETSCISSOR = 0xED, + G_SETPRIMDEPTH = 0xEE, + G_RDPSETOTHERMODE = 0xEF, + G_LOADTLUT = 0xF0, + G_RDPHALF_2 = 0xF1, + G_SETTILESIZE = 0xF2, + G_LOADBLOCK = 0xF3, + G_LOADTILE = 0xF4, + G_SETTILE = 0xF5, + G_FILLRECT = 0xF6, + G_SETFILLCOLOR = 0xF7, + G_SETFOGCOLOR = 0xF8, + G_SETBLENDCOLOR = 0xF9, + G_SETPRIMCOLOR = 0xFA, + G_SETENVCOLOR = 0xFB, + G_SETCOMBINE = 0xFC, + G_SETTIMG = 0xFD, + G_SETZIMG = 0xFE, + G_SETCIMG = 0xFF, +}; + +enum class F3DZEXTexFormats +{ + G_IM_FMT_RGBA, + G_IM_FMT_YUV, + G_IM_FMT_CI, + G_IM_FMT_IA, + G_IM_FMT_I +}; + +enum class F3DZEXTexSizes +{ + G_IM_SIZ_4b, + G_IM_SIZ_8b, + G_IM_SIZ_16b, + G_IM_SIZ_32b +}; + +enum class OoTSegments +{ + DirectReference = 0, + TitleStatic = 1, + Scene = 2, + Room = 3, + GameplayKeep = 4, + FieldDungeonKeep = 5, + Object = 6, + LinkAnimation = 7, + IconItemStatic = 8, + IconItem24Static = 9, + Unknown10 = 10, + Unknown11 = 11, + Unknown12 = 12, + IconFieldDungeonStatic = 13, + IconItemLanguageStatic = 14, + ZBuffer = 15, + FrameBuffer = 16, +}; + +#define G_RM_FOG_SHADE_A 0xC8000000 +#define G_RM_FOG_PRIM_A 0xC4000000 +#define G_RM_PASS 0x0C080000 +#define G_RM_AA_ZB_OPA_SURF 0x442078 +#define G_RM_AA_ZB_OPA_SURF2 0x112078 +#define G_RM_AA_ZB_XLU_SURF 0x4049D8 +#define G_RM_AA_ZB_XLU_SURF2 0x1049D8 +#define G_RM_AA_ZB_OPA_DECAL 0x442D58 +#define G_RM_AA_ZB_OPA_DECAL2 0x112D58 +#define G_RM_AA_ZB_XLU_DECAL 0x404DD8 +#define G_RM_AA_ZB_XLU_DECAL2 0x104DD8 +#define G_RM_AA_ZB_OPA_INTER 0x442478 +#define G_RM_AA_ZB_OPA_INTER2 0x112478 +#define G_RM_AA_ZB_XLU_INTER 0x4045D8 +#define G_RM_AA_ZB_XLU_INTER2 0x1045D8 +#define G_RM_AA_ZB_XLU_LINE 0x407858 +#define G_RM_AA_ZB_XLU_LINE2 0x107858 +#define G_RM_AA_ZB_DEC_LINE 0x407F58 +#define G_RM_AA_ZB_DEC_LINE2 0x107F58 +#define G_RM_AA_ZB_TEX_EDGE 0x443078 +#define G_RM_AA_ZB_TEX_EDGE2 0x113078 +#define G_RM_AA_ZB_TEX_INTER 0x443478 +#define G_RM_AA_ZB_TEX_INTER2 0x113478 +#define G_RM_AA_ZB_SUB_SURF 0x442878 +#define G_RM_AA_ZB_SUB_SURF2 0x112278 +#define G_RM_AA_ZB_PCL_SURF 0x40007B +#define G_RM_AA_ZB_PCL_SURF2 0x10007B +#define G_RM_AA_ZB_OPA_TERR 0x402078 +#define G_RM_AA_ZB_OPA_TERR2 0x102078 +#define G_RM_AA_ZB_TEX_TERR 0x403078 +#define G_RM_AA_ZB_TEX_TERR2 0x103078 +#define G_RM_AA_ZB_SUB_TERR 0x402278 +#define G_RM_AA_ZB_SUB_TERR2 0x102278 +#define G_RM_RA_ZB_OPA_SURF 0x442038 +#define G_RM_RA_ZB_OPA_SURF2 0x112038 +#define G_RM_RA_ZB_OPA_DECAL 0x442D18 +#define G_RM_RA_ZB_OPA_DECAL2 0x112D18 +#define G_RM_RA_ZB_OPA_INTER 0x442438 +#define G_RM_RA_ZB_OPA_INTER2 0x112438 +#define G_RM_AA_OPA_SURF 0x442048 +#define G_RM_AA_OPA_SURF2 0x112048 +#define G_RM_AA_XLU_SURF 0x4041C8 +#define G_RM_AA_XLU_SURF2 0x1041C8 +#define G_RM_AA_XLU_LINE 0x407048 +#define G_RM_AA_XLU_LINE2 0x107048 +#define G_RM_AA_DEC_LINE 0x407248 +#define G_RM_AA_DEC_LINE2 0x107248 +#define G_RM_AA_TEX_EDGE 0x443048 +#define G_RM_AA_TEX_EDGE2 0x113048 +#define G_RM_AA_SUB_SURF 0x442248 +#define G_RM_AA_SUB_SURF2 0x112248 +#define G_RM_AA_PCL_SURF 0x40004B +#define G_RM_AA_PCL_SURF2 0x10004B +#define G_RM_AA_OPA_TERR 0x402048 +#define G_RM_AA_OPA_TERR2 0x102048 +#define G_RM_AA_TEX_TERR 0x403048 +#define G_RM_AA_TEX_TERR2 0x103048 +#define G_RM_AA_SUB_TERR 0x402248 +#define G_RM_AA_SUB_TERR2 0x102248 +#define G_RM_RA_OPA_SURF 0x442008 +#define G_RM_RA_OPA_SURF2 0x112008 +#define G_RM_ZB_OPA_SURF 0x442230 +#define G_RM_ZB_OPA_SURF2 0x112230 +#define G_RM_ZB_XLU_SURF 0x404A50 +#define G_RM_ZB_XLU_SURF2 0x104A50 +#define G_RM_ZB_OPA_DECAL 0x442E10 +#define G_RM_ZB_OPA_DECAL2 0x112E10 +#define G_RM_ZB_XLU_DECAL 0x404E50 +#define G_RM_ZB_XLU_DECAL2 0x104E50 +#define G_RM_ZB_CLD_SURF 0x404B50 +#define G_RM_ZB_CLD_SURF2 0x104B50 +#define G_RM_ZB_OVL_SURF 0x404F50 +#define G_RM_ZB_OVL_SURF2 0x104F50 +#define G_RM_ZB_PCL_SURF 0x0C080233 +#define G_RM_ZB_PCL_SURF2 0x03020233 +#define G_RM_OPA_SURF 0x0C084000 +#define G_RM_OPA_SURF2 0x03024000 +#define G_RM_XLU_SURF 0x00404200 +#define G_RM_XLU_SURF2 0x00104240 +#define G_RM_CLD_SURF 0x00404340 +#define G_RM_CLD_SURF2 0x00104340 +#define G_RM_TEX_EDGE 0x0C087008 +#define G_RM_TEX_EDGE2 0x03027008 +#define G_RM_PCL_SURF 0x0C084203 +#define G_RM_PCL_SURF2 0x03024203 +#define G_RM_ADD 0x04484340 +#define G_RM_ADD2 0x01124340 +#define G_RM_NOOP 0x00000000 +#define G_RM_NOOP2 0x00000000 +#define G_RM_VISCVG 0x0C844040 +#define G_RM_VISCVG2 0x03214040 +#define G_RM_OPA_CI 0x0C080000 +#define G_RM_OPA_CI2 0x03020000 + +class Vertex +{ +public: + int16_t x, y, z; + uint16_t flag; + int16_t s, t; + uint8_t r, g, b, a; + + Vertex(); + Vertex(int16_t nX, int16_t nY, int16_t nZ, uint16_t nFlag, int16_t nS, int16_t nT, uint8_t nR, uint8_t nG, uint8_t nB, uint8_t nA); + Vertex(std::vector rawData, int rawDataIndex); +}; + +class ZDisplayList : public ZResource +{ +protected: + // Test + uint32_t lastTexWidth, lastTexHeight, lastTexAddr, lastTexSeg; + F3DZEXTexFormats lastTexFmt; + F3DZEXTexSizes lastTexSiz, lastTexSizTest, lastCISiz; + bool lastTexLoaded; + + //void ParseXML(tinyxml2::XMLElement* reader); + static TextureType TexFormatToTexType(F3DZEXTexFormats fmt, F3DZEXTexSizes siz); + void ParseRawData(); + + // Various Instruction Optimizations + bool SequenceCheck(std::vector sequence, int startIndex); + int OptimizationChecks(int startIndex, std::string& output, std::string prefix); + int OptimizationCheck_LoadTextureBlock(int startIndex, std::string& output, std::string prefix); + int OptimizationCheck_LoadMultiBlock(int startIndex, std::string& output, std::string prefix); +public: + std::string sceneSegName; + ZRoom* scene; + std::vector instructions; + + //int dListAddress; + + std::map> vertices; + std::map vtxDeclarations; + std::vector otherDLists; + + std::map textures; + std::map texDeclarations; + + std::string defines; // Hack for special cases where vertex arrays intersect... + std::vector fileData; + + ZDisplayList(); + ZDisplayList(std::vector nRawData, int rawDataIndex, int rawDataSize); + + static ZDisplayList* ExtractFromXML(tinyxml2::XMLElement* reader, std::vector nRawData, int rawDataIndex, int rawDataSize, std::string nRelPath); + static ZDisplayList* BuildFromXML(tinyxml2::XMLElement* reader, std::string inFolder, bool readFile); + + void TextureGenCheck(std::string prefix); + static bool TextureGenCheck(std::vector fileData, std::map& textures, ZRoom* scene, ZFile* parent, std::string prefix, uint32_t texWidth, uint32_t texHeight, uint32_t texAddr, uint32_t texSeg, F3DZEXTexFormats texFmt, F3DZEXTexSizes texSiz, bool texLoaded); + static int GetDListLength(std::vector rawData, int rawDataIndex); + + std::vector GetRawData(); + int GetRawDataSize(); + std::string GetSourceOutputHeader(std::string prefix); + std::string GetSourceOutputCode(std::string prefix); + void Save(std::string outFolder); + virtual void GenerateHLIntermediette(HLFileIntermediette& hlFile); +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZFile.cpp b/tools/ZAPD/ZAPD/ZFile.cpp new file mode 100644 index 0000000000..b2de4a83b1 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZFile.cpp @@ -0,0 +1,859 @@ +#include "ZFile.h" +#include "ZBlob.h" +#include "ZDisplayList.h" +#include "ZRoom/ZRoom.h" +#include "ZTexture.h" +#include "ZAnimation.h" +#include "ZSkeleton.h" +#include "ZCollision.h" +#include "Path.h" +#include "File.h" +#include "Directory.h" +#include "Globals.h" +#include "HighLevel/HLModelIntermediette.h" +#include +#include + +using namespace tinyxml2; +using namespace std; + +ZFile::ZFile() +{ + resources = vector(); + basePath = ""; + outputPath = Directory::GetCurrentDirectory(); + declarations = map(); + defines = ""; + baseAddress = 0; + rangeStart = 0x000000000; + rangeEnd = 0xFFFFFFFF; +} + +ZFile::ZFile(string nOutPath, string nName) : ZFile() +{ + outputPath = nOutPath; + name = nName; +} + +ZFile::ZFile(ZFileMode mode, XMLElement* reader, string nBasePath, string nOutPath, bool placeholderMode) : ZFile() +{ + if (nBasePath == "") + basePath = Directory::GetCurrentDirectory(); + else + basePath = nBasePath; + + if (nOutPath == "") + outputPath = Directory::GetCurrentDirectory(); + else + outputPath = nOutPath; + + ParseXML(mode, reader, placeholderMode); +} + +void ZFile::ParseXML(ZFileMode mode, XMLElement* reader, bool placeholderMode) +{ + name = reader->Attribute("Name"); + int segment = -1; + + if (reader->Attribute("BaseAddress") != NULL) + baseAddress = (uint32_t)strtoul(StringHelper::Split(reader->Attribute("BaseAddress"), "0x")[1].c_str(), NULL, 16); + + if (reader->Attribute("RangeStart") != NULL) + rangeStart = (uint32_t)strtoul(StringHelper::Split(reader->Attribute("RangeStart"), "0x")[1].c_str(), NULL, 16); + + if (reader->Attribute("RangeEnd") != NULL) + rangeEnd = (uint32_t)strtoul(StringHelper::Split(reader->Attribute("RangeEnd"), "0x")[1].c_str(), NULL, 16); + + if (reader->Attribute("Segment") != NULL) + segment = strtol(reader->Attribute("Segment"), NULL, 10); + + if (segment != -1) + { + //printf("Adding Segment %i\n", segment); + Globals::Instance->AddSegment(segment); + } + + string folderName = basePath + "/" + Path::GetFileNameWithoutExtension(name); + + if (mode == ZFileMode::Extract) + { + if (!File::Exists(basePath + "/" + name)) + throw StringHelper::Sprintf("Error! File %s does not exist.", (basePath + "/" + name).c_str()); + + rawData = File::ReadAllBytes(basePath + "/" + name); + } + + int rawDataIndex = 0; + + for (XMLElement* child = reader->FirstChildElement(); child != NULL; child = child->NextSiblingElement()) + { + if (child->Attribute("Offset") != NULL) + rawDataIndex = strtol(StringHelper::Split(child->Attribute("Offset"), "0x")[1].c_str(), NULL, 16); + + printf("%s: 0x%06X\n", child->Attribute("Name"), rawDataIndex); + + if (string(child->Name()) == "Texture") + { + ZTexture* tex = nullptr; + + if (mode == ZFileMode::Extract) + tex = ZTexture::ExtractFromXML(child, rawData, rawDataIndex, folderName); + else + tex = ZTexture::BuildFromXML(child, folderName, mode == ZFileMode::Build); + + tex->SetRawDataIndex(rawDataIndex); + + tex->parent = this; + + resources.push_back(tex); + rawDataIndex += tex->GetRawDataSize(); + } + else if (string(child->Name()) == "Blob") + { + ZBlob* blob = nullptr; + + if (mode == ZFileMode::Extract) + blob = ZBlob::ExtractFromXML(child, rawData, rawDataIndex, folderName); + else + blob = ZBlob::BuildFromXML(child, folderName, mode == ZFileMode::Build); + + blob->parent = this; + + resources.push_back(blob); + + rawDataIndex += blob->GetRawDataSize(); + } + else if (string(child->Name()) == "DList") + { + ZResource* dList = nullptr; + + if (mode == ZFileMode::Extract) + dList = ZDisplayList::ExtractFromXML(child, rawData, rawDataIndex, ZDisplayList::GetDListLength(rawData, rawDataIndex), folderName); + //else + //dList = ZDisplayList::BuildFromXML(child, folderName, mode == ZFileMode::Build); + else + dList = ZBlob::BuildFromXML(child, folderName, mode == ZFileMode::Build); + + dList->parent = this; + + resources.push_back(dList); + + rawDataIndex += dList->GetRawDataSize(); + } + else if (string(child->Name()) == "Scene" || string(child->Name()) == "Room") + { + ZRoom* room = nullptr; + + if (mode == ZFileMode::Extract) + room = ZRoom::ExtractFromXML(child, rawData, rawDataIndex, folderName, this, Globals::Instance->lastScene); + + if (string(child->Name()) == "Scene") + { + Globals::Instance->lastScene = room; + + if (segment == -1) + segment = SEGMENT_SCENE; + } + else + { + if (segment == -1) + segment = SEGMENT_ROOM; + } + + if (segment != -1) + Globals::Instance->AddSegment(segment); + + resources.push_back(room); + + rawDataIndex += room->GetRawDataSize(); + } + else if (string(child->Name()) == "Animation") + { + ZAnimation* anim = nullptr; + + if (mode == ZFileMode::Extract) + anim = ZNormalAnimation::ExtractFromXML(child, rawData, rawDataIndex, folderName); + + anim->parent = this; + resources.push_back(anim); + + rawDataIndex += anim->GetRawDataSize(); + } + else if (string(child->Name()) == "PlayerAnimation") + { + ZLinkAnimation* anim = nullptr; + + if (mode == ZFileMode::Extract) + anim = ZLinkAnimation::ExtractFromXML(child, rawData, rawDataIndex, folderName); + + anim->parent = this; + resources.push_back(anim); + + rawDataIndex += anim->GetRawDataSize(); + } + else if (string(child->Name()) == "Skeleton") + { + ZSkeleton* skeleton = nullptr; + + if (mode == ZFileMode::Extract) + skeleton = ZSkeleton::FromXML(child, rawData, rawDataIndex, folderName, this); + + resources.push_back(skeleton); + rawDataIndex += skeleton->GetRawDataSize(); + } + else if (string(child->Name()) == "Limb") + { + ZLimbStandard* limb = nullptr; + + if (mode == ZFileMode::Extract) + limb = ZLimbStandard::FromXML(child, rawData, rawDataIndex, folderName, this); + + resources.push_back(limb); + + rawDataIndex += limb->GetRawDataSize(); + } + else if (string(child->Name()) == "Symbol") + { + ZResource* res = nullptr; + + if (mode == ZFileMode::Extract) + { + res = new ZResource(); + res->SetName(child->Attribute("Name")); + res->SetRawDataIndex(rawDataIndex); + res->outputDeclaration = false; + } + + resources.push_back(res); + } + else if (string(child->Name()) == "Collision") + { + ZCollisionHeader* res = nullptr; + + if (mode == ZFileMode::Extract) + { + res = new ZCollisionHeader(this, child->Attribute("Name"), rawData, rawDataIndex); + res->SetName(child->Attribute("Name")); + res->SetRawDataIndex(rawDataIndex); + } + + resources.push_back(res); + } + else if (string(child->Name()) == "Vec3s") + { + + } + else if (string(child->Name()) == "Vec3f") + { + + } + else if (string(child->Name()) == "Vec3i") + { + + } + else if (string(child->Name()) == "String") + { + + } + else + { + + } + } +} + +void ZFile::BuildResources() +{ + cout << "Building resources " << name << "\n"; + + int size = 0; + + for (ZResource* res : resources) + size += res->GetRawDataSize(); + + // Make sure size is 16 byte aligned + if (size % 16 != 0) + size = ((size / 16) + 1) * 16; + + vector file = vector(size); + int fileIndex = 0; + + for (ZResource* res : resources) + { + //Console.WriteLine("Building resource " + res.GetName()); + memcpy(file.data() + fileIndex, res->GetRawData().data(), res->GetRawData().size()); + //Array.Copy(res.GetRawData(), 0, file, fileIndex, res.GetRawData().Length); + fileIndex += res->GetRawData().size(); + } + + File::WriteAllBytes(basePath + "/" + name, file); +} + +void ZFile::BuildSourceFile(string outputDir) +{ + string folderName = Path::GetFileNameWithoutExtension(outputPath); + + if (!Directory::Exists(outputPath)) + Directory::CreateDirectory(outputPath); + + GenerateSourceFiles(outputDir); +} + +std::string ZFile::GetVarName(int address) +{ + for (pair pair : declarations) + { + if (pair.first == address) + return pair.second->varName; + } + + return ""; +} + +void ZFile::ExtractResources(string outputDir) +{ + string folderName = Path::GetFileNameWithoutExtension(outputPath); + + //printf("DIR CHECK: %s\n", folderName.c_str()); + //printf("OUT CHECK: %s\n", outputDir.c_str()); + + if (!Directory::Exists(outputPath)) + Directory::CreateDirectory(outputPath); + + for (ZResource* res : resources) + res->PreGenSourceFiles(); + + if (Globals::Instance->genSourceFile) + GenerateSourceFiles(outputDir); + + for (ZResource* res : resources) + { + printf("Saving resource %s\n", res->GetName().c_str()); + res->CalcHash(); // TEST + res->Save(outputPath); + } + + if (Globals::Instance->testMode) + GenerateHLIntermediette(); +} + +void ZFile::AddResource(ZResource* res) +{ + resources.push_back(res); +} + +Declaration* ZFile::AddDeclaration(uint32_t address, DeclarationAlignment alignment, uint32_t size, std::string varType, std::string varName, std::string body) +{ +#if _DEBUG + if (declarations.find(address) != declarations.end()) + { + int bp = 0; + } +#endif + + AddDeclarationDebugChecks(address); + + Declaration* decl = new Declaration(alignment, size, varType, varName, false, body); + declarations[address] = decl; + return decl; +} + +void ZFile::AddDeclaration(uint32_t address, DeclarationAlignment alignment, DeclarationPadding padding, uint32_t size, string varType, string varName, std::string body) +{ +#if _DEBUG + if (declarations.find(address) != declarations.end()) + { + int bp = 0; + } +#endif + + AddDeclarationDebugChecks(address); + + declarations[address] = new Declaration(alignment, padding, size, varType, varName, false, body); +} + +void ZFile::AddDeclarationArray(uint32_t address, DeclarationAlignment alignment, uint32_t size, std::string varType, std::string varName, int arrayItemCnt, std::string body) +{ +#if _DEBUG + if (declarations.find(address) != declarations.end()) + { + int bp = 0; + } +#endif + + AddDeclarationDebugChecks(address); + + declarations[address] = new Declaration(alignment, size, varType, varName, true, arrayItemCnt, body); +} + + +void ZFile::AddDeclarationArray(uint32_t address, DeclarationAlignment alignment, DeclarationPadding padding, uint32_t size, string varType, string varName, int arrayItemCnt, std::string body) +{ +#if _DEBUG + if (declarations.find(address) != declarations.end()) + { + int bp = 0; + } +#endif + + AddDeclarationDebugChecks(address); + + declarations[address] = new Declaration(alignment, padding, size, varType, varName, true, arrayItemCnt, body); +} + + +void ZFile::AddDeclarationPlaceholder(uint32_t address) +{ + AddDeclarationDebugChecks(address); + + if (declarations.find(address) == declarations.end()) + declarations[address] = new Declaration(DeclarationAlignment::None, 0, "", "", false, ""); +} + +void ZFile::AddDeclarationPlaceholder(uint32_t address, string varName) +{ + AddDeclarationDebugChecks(address); + + if (declarations.find(address) == declarations.end()) + declarations[address] = new Declaration(DeclarationAlignment::None, 0, "", varName, false, ""); +} + +void ZFile::AddDeclarationInclude(uint32_t address, string includePath, uint32_t size, string varType, string varName) +{ + AddDeclarationDebugChecks(address); + + if (declarations.find(address) == declarations.end()) + declarations[address] = new Declaration(includePath, size, varType, varName); +} + +void ZFile::AddDeclarationIncludeArray(uint32_t address, std::string includePath, uint32_t size, std::string varType, std::string varName, int arrayItemCnt) +{ +#if _DEBUG + if (declarations.find(address) != declarations.end()) + { + int bp = 0; + } +#endif + + AddDeclarationDebugChecks(address); + + Declaration* decl = new Declaration(includePath, size, varType, varName); + + decl->isArray = true; + decl->arrayItemCnt = arrayItemCnt; + + declarations[address] = decl; +} + +void ZFile::AddDeclarationDebugChecks(uint32_t address) +{ +#ifdef _DEBUG + if (address == 0xB888E0) + { + int bp = 0; + } +#endif +} + +std::string ZFile::GetDeclarationName(uint32_t address) +{ + return GetDeclarationName(address, "ERROR_COULD_NOT_FIND_DECLARATION"); // Note: For now that default message is just for testing +} + +std::string ZFile::GetDeclarationName(uint32_t address, std::string defaultResult) +{ + if (declarations.find(address) != declarations.end()) + return declarations[address]->varName; + + return defaultResult; +} + +Declaration* ZFile::GetDeclaration(uint32_t address) +{ + if (declarations.find(address) != declarations.end()) + return declarations[address]; + + return nullptr; +} + +Declaration* ZFile::GetDeclarationRanged(uint32_t address) +{ + for (const auto decl : declarations) + { + if (address >= decl.first && address <= decl.first + decl.second->size) + { + return decl.second; + } + } + + return nullptr; +} + +bool ZFile::HasDeclaration(uint32_t address) +{ + return (declarations.find(address) != declarations.end()); +} + +void ZFile::GenerateSourceFiles(string outputDir) +{ + sourceOutput = ""; + + sourceOutput += "#include \"ultra64.h\"\n"; + sourceOutput += "#include \"z64.h\"\n"; + sourceOutput += "#include \"macros.h\"\n"; + sourceOutput += GetHeaderInclude(); + + GeneratePlaceholderDeclarations(); + + // Generate Code + for (ZResource* res : resources) + { + string resSrc = res->GetSourceOutputCode(name); + + if (res->IsExternalResource()) + { + //cout << "EXTERN\n"; + string path = Path::GetFileNameWithoutExtension(res->GetName()).c_str(); + + while (StringHelper::EndsWith(outputDir, "/")) + outputDir = outputDir.substr(0, outputDir.length() - 1); + + // HACK + string declType = "u64"; + + if (res->GetResourceType() != ZResourceType::Texture) + declType = "u8"; + + AddDeclarationIncludeArray(res->GetRawDataIndex(), StringHelper::Sprintf("%s/%s.%s.inc.c", + outputDir.c_str(), Path::GetFileNameWithoutExtension(res->GetOutName()).c_str(), res->GetExternalExtension().c_str()), res->GetRawDataSize(), + declType, res->GetName(), 0); + + + //File::WriteAllText("build/" + outputDir + "/" + Path::GetFileNameWithoutExtension(res->GetName()) + ".inc.c", resSrc); + } + else + { + //cout << "NOT EXTERN\n"; + sourceOutput += resSrc; + } + + if (resSrc != "" && !res->IsExternalResource()) + sourceOutput += "\n"; + } + + sourceOutput += ProcessDeclarations(); + + while (StringHelper::EndsWith(outputDir, "/")) + outputDir = outputDir.substr(0, outputDir.length() - 1); + + //string buildPath = "build/" + outputDir + "/" + "basefile.txt"; + string outPath = outputDir + "/" + Path::GetFileNameWithoutExtension(name) + ".c"; + //printf("WRITING %s\n", buildPath.c_str()); + + //if (!Directory::Exists(Path::GetPath(outPath))) + //Directory::CreateDirectory(Path::GetPath(outPath)); + + //if (!Directory::Exists(Path::GetPath(buildPath))) + //Directory::CreateDirectory(Path::GetPath(buildPath)); + + File::WriteAllText(outPath, sourceOutput); + //File::WriteAllText(buildPath, outPath); + + // Generate Header + sourceOutput = ""; + + for (ZResource* res : resources) + { + string resSrc = res->GetSourceOutputHeader(""); + sourceOutput += resSrc; + + if (resSrc != "") + sourceOutput += "\n"; + } + + sourceOutput += ProcessExterns(); + + File::WriteAllText(outputDir + "/" + Path::GetFileNameWithoutExtension(name) + ".h", sourceOutput); +} + +void ZFile::GenerateHLIntermediette() +{ + // This is kinda hacky but it gets the job done for now... + HLModelIntermediette* mdl = new HLModelIntermediette(); + + for (ZResource* res : resources) + { + if (typeid(ZDisplayList) == typeid(*res) || typeid(ZSkeleton) == typeid(*res)) + res->GenerateHLIntermediette(*mdl); + } + + std::string test = mdl->ToOBJFile(); + std::string test2 = mdl->ToFBXFile(); +} + +std::string ZFile::GetHeaderInclude() +{ + return StringHelper::Sprintf("#include \"%s\"\n\n", (Path::GetFileNameWithoutExtension(name) + ".h").c_str()); +} + +void ZFile::GeneratePlaceholderDeclarations() +{ + // Generate placeholder declarations + for (ZResource* res : resources) + { + if (GetDeclaration(res->GetRawDataIndex()) == nullptr) + AddDeclarationPlaceholder(res->GetRawDataIndex(), res->GetName()); + } +} + +string ZFile::ProcessDeclarations() +{ + string output = ""; + + if (declarations.size() == 0) + return output; + + auto declarationKeysSorted = vector>(declarations.begin(), declarations.end()); + sort(declarationKeysSorted.begin(), declarationKeysSorted.end(), [](const auto& lhs, const auto& rhs) + { + return lhs.first < rhs.first; + }); + + // Account for padding/alignment + int lastAddr = 0; + + //printf("RANGE START: 0x%06X - RANGE END: 0x%06X\n", rangeStart, rangeEnd); + + for (pair item : declarationKeysSorted) + { + while (declarations[item.first]->size % 4 != 0) + { + declarations[item.first]->size++; + } + + if (lastAddr != 0) + { + if (item.second->alignment == DeclarationAlignment::Align16) + { + int lastAddrSizeTest = declarations[lastAddr]->size; + int curPtr = lastAddr + declarations[lastAddr]->size; + + while (curPtr % 4 != 0) + { + declarations[lastAddr]->size++; + //declarations[item.first]->size++; + curPtr++; + } + + /*while (curPtr % 16 != 0) + { + char buffer[2048]; + + sprintf(buffer, "static u32 align%02X = 0;\n", curPtr); + declarations[item.first]->text = buffer + declarations[item.first]->text; + + declarations[lastAddr]->size += 4; + curPtr += 4; + }*/ + } + else if (item.second->alignment == DeclarationAlignment::Align8) + { + int curPtr = lastAddr + declarations[lastAddr]->size; + + while (curPtr % 4 != 0) + { + declarations[lastAddr]->size++; + //item.second->size++; + //declarations[item.first]->size++; + curPtr++; + } + + while (curPtr % 8 != 0) + { + char buffer[2048]; + + sprintf(buffer, "static u32 align%02X = 0;\n", curPtr); + declarations[item.first]->preText = buffer + declarations[item.first]->preText; + + declarations[lastAddr]->size += 4; + //item.second->size += 4; + //declarations[item.first]->size += 4; + curPtr += 4; + } + } + } + + if (item.second->padding == DeclarationPadding::Pad16) + { + int curPtr = item.first + item.second->size; + + while (curPtr % 4 != 0) + { + item.second->size++; + curPtr++; + } + + while (curPtr % 16 != 0) + { + declarations[item.first]->postText += StringHelper::Sprintf("static u32 pad%02X = 0;\n", curPtr); + + item.second->size += 4; + curPtr += 4; + } + } + + lastAddr = item.first; + } + + // Handle unaccounted data + lastAddr = 0; + for (pair item : declarationKeysSorted) + { + if (lastAddr != 0 && item.first >= rangeStart && item.first < rangeEnd) + { + if (lastAddr + declarations[lastAddr]->size > item.first) + { + // UH OH! + int bp = 0; + } + + uint8_t* rawDataArr = rawData.data(); + + if (lastAddr + declarations[lastAddr]->size != item.first) + { + int diff = item.first - (lastAddr + declarations[lastAddr]->size); + + string src = " "; + + + for (int i = 0; i < diff; i++) + { + src += StringHelper::Sprintf("0x%02X, ", rawDataArr[lastAddr + declarations[lastAddr]->size + i]); + + if ((i % 16 == 15) && (i != (diff - 1))) + src += "\n "; + } + + if (declarations.find(lastAddr + declarations[lastAddr]->size) == declarations.end()) + { + if (diff > 0) + { + AddDeclarationArray(lastAddr + declarations[lastAddr]->size, DeclarationAlignment::None, diff, "static u8", StringHelper::Sprintf("unaccounted_%06X", lastAddr + declarations[lastAddr]->size), + diff, src); + } + } + } + } + + lastAddr = item.first; + } + + // TODO: THIS CONTAINS REDUNDANCIES. CLEAN THIS UP! + if (lastAddr + declarations[lastAddr]->size < rawData.size() && lastAddr + declarations[lastAddr]->size >= rangeStart && lastAddr + declarations[lastAddr]->size < rangeEnd) + { + int diff = (int)(rawData.size() - (lastAddr + declarations[lastAddr]->size)); + + string src = " "; + + for (int i = 0; i < diff; i++) + { + src += StringHelper::Sprintf("0x%02X, ", rawData[lastAddr + declarations[lastAddr]->size + i]); + + if (i % 16 == 15) + src += "\n "; + } + + if (declarations.find(lastAddr + declarations[lastAddr]->size) == declarations.end()) + { + if (diff > 0) + { + AddDeclarationArray(lastAddr + declarations[lastAddr]->size, DeclarationAlignment::None, diff, "static u8", StringHelper::Sprintf("unaccounted_%06X", lastAddr + declarations[lastAddr]->size), + diff, src); + } + } + } + + // Go through include declarations + declarationKeysSorted = vector>(declarations.begin(), declarations.end()); + sort(declarationKeysSorted.begin(), declarationKeysSorted.end(), [](const auto& lhs, const auto& rhs) + { + return lhs.first < rhs.first; + }); + + for (pair item : declarationKeysSorted) + { + if (item.second->includePath != "") + { + //output += StringHelper::Sprintf("#include \"%s\"\n", item.second->includePath.c_str()); + output += StringHelper::Sprintf("%s %s[] = {\n#include \"%s\"\n};\n\n", item.second->varType.c_str(), item.second->varName.c_str(), item.second->includePath.c_str()); + } + else if (item.second->varType != "") + { + if (item.second->preText != "") + output += item.second->preText + "\n"; + + if (item.second->isArray) + { + if (item.second->arrayItemCnt == 0) + output += StringHelper::Sprintf("%s %s[] = {\n", item.second->varType.c_str(), item.second->varName.c_str()); + else + output += StringHelper::Sprintf("%s %s[%i] = {\n", item.second->varType.c_str(), item.second->varName.c_str(), item.second->arrayItemCnt); + + output += item.second->text + "\n"; + } + else + { + output += StringHelper::Sprintf("%s %s = { ", item.second->varType.c_str(), item.second->varName.c_str()); + output += item.second->text; + } + + if (output.back() == '\n') + output += "};"; + else + output += " };"; + + output += " " + item.second->rightText + "\n\n"; + + if (item.second->postText != "") + output += item.second->postText + "\n"; + } + } + + output += "\n"; + + return output; +} + + +string ZFile::ProcessExterns() +{ + string output = ""; + + auto declarationKeysSorted = vector>(declarations.begin(), declarations.end()); + sort(declarationKeysSorted.begin(), declarationKeysSorted.end(), [](const auto& lhs, const auto& rhs) + { + return lhs.first < rhs.first; + }); + + for (pair item : declarationKeysSorted) + { + if (!StringHelper::StartsWith(item.second->varType, "static ") && item.second->varType != "")// && item.second->includePath == "") + { + if (item.second->isArray) + { + if (item.second->arrayItemCnt == 0) + output += StringHelper::Sprintf("extern %s %s[];\n", item.second->varType.c_str(), item.second->varName.c_str()); + else + output += StringHelper::Sprintf("extern %s %s[%i];\n", item.second->varType.c_str(), item.second->varName.c_str(), item.second->arrayItemCnt); + } + else + output += StringHelper::Sprintf("extern %s %s;\n", item.second->varType.c_str(), item.second->varName.c_str()); + } + } + + output += "\n"; + + output += defines; + + return output; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZFile.h b/tools/ZAPD/ZAPD/ZFile.h new file mode 100644 index 0000000000..a9e7c23973 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZFile.h @@ -0,0 +1,68 @@ +#pragma once + +#include +#include +#include "tinyxml2.h" +#include "ZResource.h" + +enum class ZFileMode +{ + Build, + BuildTexture, + BuildOverlay, + BuildModelIntermediette, + BuildAnimationIntermediette, + BuildBlob, + BuildSourceFile, + Extract, + Invalid +}; + +class ZFile +{ +public: + std::map declarations; + std::string defines; + std::vector resources; + uint32_t baseAddress, rangeStart, rangeEnd; + + ZFile(std::string nOutPath, std::string nName); + ZFile(ZFileMode mode, tinyxml2::XMLElement* reader, std::string nBasePath, std::string nOutPath, bool placeholderMode); + + std::string GetVarName(int address); + void ExtractResources(std::string outputDir); + void BuildResources(); + void BuildSourceFile(std::string outputDir); + void AddResource(ZResource* res); + + Declaration* AddDeclaration(uint32_t address, DeclarationAlignment alignment, uint32_t size, std::string varType, std::string varName, std::string body); + void AddDeclaration(uint32_t address, DeclarationAlignment alignment, DeclarationPadding padding, uint32_t size, std::string varType, std::string varName, std::string body); + void AddDeclarationArray(uint32_t address, DeclarationAlignment alignment, uint32_t size, std::string varType, std::string varName, int arrayItemCnt, std::string body); + void AddDeclarationArray(uint32_t address, DeclarationAlignment alignment, DeclarationPadding padding, uint32_t size, std::string varType, std::string varName, int arrayItemCnt, std::string body); + void AddDeclarationPlaceholder(uint32_t address); + void AddDeclarationPlaceholder(uint32_t address, std::string varName); + void AddDeclarationInclude(uint32_t address, std::string includePath, uint32_t size, std::string varType, std::string varName); + void AddDeclarationIncludeArray(uint32_t address, std::string includePath, uint32_t size, std::string varType, std::string varName, int arrayItemCnt); + std::string GetDeclarationName(uint32_t address); + std::string GetDeclarationName(uint32_t address, std::string defaultResult); + Declaration* GetDeclaration(uint32_t address); + Declaration* GetDeclarationRanged(uint32_t address); + bool HasDeclaration(uint32_t address); + std::string GetHeaderInclude(); + void GeneratePlaceholderDeclarations(); + +protected: + std::vector rawData; + std::string name; + std::string basePath; + std::string outputPath; + std::string sourceOutput; + + ZFile(); + void ParseXML(ZFileMode mode, tinyxml2::XMLElement* reader, bool placeholderMode); + void GenerateSourceFiles(std::string outputDir); + void GenerateHLIntermediette(); + void AddDeclarationDebugChecks(uint32_t address); + std::string ProcessDeclarations(); + std::string ProcessExterns(); +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZResource.cpp b/tools/ZAPD/ZAPD/ZResource.cpp new file mode 100644 index 0000000000..489724e80e --- /dev/null +++ b/tools/ZAPD/ZAPD/ZResource.cpp @@ -0,0 +1,110 @@ +#include "ZResource.h" + +using namespace std; + +ZResource::ZResource() +{ + parent = nullptr; + name = ""; + outName = ""; + relativePath = ""; + sourceOutput = ""; + rawData = vector(); + rawDataIndex = 0; + outputDeclaration = true; + arrayCnt = -1; +} + +void ZResource::ParseXML(tinyxml2::XMLElement* reader) +{ + name = reader->Attribute("Name"); + + if (reader->Attribute("OutName") != nullptr) + outName = reader->Attribute("OutName"); + else + outName = name; +} + +void ZResource::Save(string outFolder) +{ + +} + +void ZResource::PreGenSourceFiles() +{ +} + +string ZResource::GetName() +{ + return name; +} + +std::string ZResource::GetOutName() +{ + return outName; +} + +void ZResource::SetName(string nName) +{ + name = nName; +} + +bool ZResource::IsExternalResource() +{ + return false; +} + +std::string ZResource::GetExternalExtension() +{ + return ""; +} + +string ZResource::GetRelativePath() +{ + return relativePath; +} + +vector ZResource::GetRawData() +{ + return rawData; +} + +int ZResource::GetRawDataIndex() +{ + return rawDataIndex; +} + +int ZResource::GetRawDataSize() +{ + return rawData.size(); +} + +void ZResource::SetRawDataIndex(int value) +{ + rawDataIndex = value; +} + +string ZResource::GetSourceOutputCode(std::string prefix) +{ + return ""; +} + +string ZResource::GetSourceOutputHeader(std::string prefix) +{ + return ""; +} + +void ZResource::GenerateHLIntermediette(HLFileIntermediette& hlFile) +{ + +} + +ZResourceType ZResource::GetResourceType() +{ + return ZResourceType::Error; +} + +void ZResource::CalcHash() +{ + hash = 0; +} diff --git a/tools/ZAPD/ZAPD/ZResource.h b/tools/ZAPD/ZAPD/ZResource.h new file mode 100644 index 0000000000..4548473d67 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZResource.h @@ -0,0 +1,118 @@ +#pragma once + +#include +#include +#include +#include +#include "tinyxml2.h" + +#define SEGMENT_SCENE 2 +#define SEGMENT_ROOM 3 +#define SEGMENT_KEEP 4 +#define SEGMENT_FIELDDANGEON_KEEP 5 +#define SEGMENT_OBJECT 6 +#define SEGMENT_LINKANIMETION 7 + +#define SEG2FILESPACE(x) (x & 0x00FFFFFF) +#define GETSEGNUM(x) ((x >> 24) & 0xFF) + +class ZFile; +class HLFileIntermediette; + +class Declaration; +struct CommandSet; + +enum class ZResourceType +{ + Error, + Texture, + DisplayList, + Room, + Overlay, + Animation, + Cutscene, + Blob, + Limb, + Skeleton +}; + +class ZResource +{ +public: + ZFile* parent; + bool outputDeclaration; + int arrayCnt; + + ZResource(); + virtual void ParseXML(tinyxml2::XMLElement* reader); + virtual void Save(std::string outFolder); + virtual void PreGenSourceFiles(); + std::string GetName(); + std::string GetOutName(); + void SetName(std::string nName); + std::string GetRelativePath(); + virtual std::vector GetRawData(); + virtual bool IsExternalResource(); + virtual std::string GetExternalExtension(); + virtual int GetRawDataIndex(); + virtual int GetRawDataSize(); + virtual void SetRawDataIndex(int value); + virtual std::string GetSourceOutputCode(std::string prefix); + virtual std::string GetSourceOutputHeader(std::string prefix); + virtual void GenerateHLIntermediette(HLFileIntermediette& hlFile); + virtual ZResourceType GetResourceType(); + virtual void CalcHash(); + +protected: + std::string name; + std::string outName; + std::string relativePath; + std::vector rawData; + int rawDataIndex; + std::string sourceOutput; + uint64_t hash; +}; + +enum class DeclarationAlignment +{ + None, + Align4, + Align8, + Align16 +}; + +enum class DeclarationPadding +{ + None, + Pad4, + Pad8, + Pad16 +}; + +class Declaration +{ +public: + DeclarationAlignment alignment; + DeclarationPadding padding; + uint32_t size; + std::string preText; + std::string text; + std::string rightText; + std::string postText; + std::string preComment; + std::string postComment; + std::string varType; + std::string varName; + std::string includePath; + bool isArray; + int arrayItemCnt; + + Declaration(DeclarationAlignment nAlignment, uint32_t nSize, std::string nVarType, std::string nVarName, bool nIsArray, std::string nText); + Declaration(DeclarationAlignment nAlignment, DeclarationPadding nPadding, uint32_t nSize, std::string nVarType, std::string nVarName, bool nIsArray, std::string nText); + Declaration(DeclarationAlignment nAlignment, uint32_t nSize, std::string nVarType, std::string nVarName, bool nIsArray, int nArrayItemCnt, std::string nText); + Declaration(DeclarationAlignment nAlignment, DeclarationPadding nPadding, uint32_t nSize, std::string nVarType, std::string nVarName, bool nIsArray, int nArrayItemCnt, std::string nText); + Declaration(std::string nIncludePath, uint32_t nSize, std::string nVarType, std::string nVarName); + +protected: + Declaration(DeclarationAlignment nAlignment, DeclarationPadding nPadding, uint32_t nSize, std::string nText); +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/ActorList.h b/tools/ZAPD/ZAPD/ZRoom/ActorList.h new file mode 100644 index 0000000000..a5c88aa2d8 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/ActorList.h @@ -0,0 +1,478 @@ +#pragma once + +#include + +static const std::string ActorList[] = +{ + "ACTOR_PLAYER", + "ACTOR_UNSET_1", + "ACTOR_EN_TEST", + "ACTOR_UNSET_3", + "ACTOR_EN_GIRLA", + "ACTOR_UNSET_5", + "ACTOR_UNSET_6", + "ACTOR_EN_PART", + "ACTOR_EN_LIGHT", + "ACTOR_EN_DOOR", + "ACTOR_EN_BOX", + "ACTOR_BG_DY_YOSEIZO", + "ACTOR_BG_HIDAN_FIREWALL", + "ACTOR_EN_POH", + "ACTOR_EN_OKUTA", + "ACTOR_BG_YDAN_SP", + "ACTOR_EN_BOM", + "ACTOR_EN_WALLMAS", + "ACTOR_EN_DODONGO", + "ACTOR_EN_FIREFLY", + "ACTOR_EN_HORSE", + "ACTOR_EN_ITEM00", + "ACTOR_EN_ARROW", + "ACTOR_UNSET_17", + "ACTOR_EN_ELF", + "ACTOR_EN_NIW", + "ACTOR_UNSET_1A", + "ACTOR_EN_TITE", + "ACTOR_EN_REEBA", + "ACTOR_EN_PEEHAT", + "ACTOR_EN_BUTTE", + "ACTOR_UNSET_1F", + "ACTOR_EN_INSECT", + "ACTOR_EN_FISH", + "ACTOR_UNSET_22", + "ACTOR_EN_HOLL", + "ACTOR_EN_SCENE_CHANGE", + "ACTOR_EN_ZF", + "ACTOR_EN_HATA", + "ACTOR_BOSS_DODONGO", + "ACTOR_BOSS_GOMA", + "ACTOR_EN_ZL1", + "ACTOR_EN_VIEWER", + "ACTOR_EN_GOMA", + "ACTOR_BG_PUSHBOX", + "ACTOR_EN_BUBBLE", + "ACTOR_DOOR_SHUTTER", + "ACTOR_EN_DODOJR", + "ACTOR_EN_BDFIRE", + "ACTOR_UNSET_31", + "ACTOR_EN_BOOM", + "ACTOR_EN_TORCH2", + "ACTOR_EN_BILI", + "ACTOR_EN_TP", + "ACTOR_UNSET_36", + "ACTOR_EN_ST", + "ACTOR_EN_BW", + "ACTOR_EN_A_OBJ", + "ACTOR_EN_EIYER", + "ACTOR_EN_RIVER_SOUND", + "ACTOR_EN_HORSE_NORMAL", + "ACTOR_EN_OSSAN", + "ACTOR_BG_TREEMOUTH", + "ACTOR_BG_DODOAGO", + "ACTOR_BG_HIDAN_DALM", + "ACTOR_BG_HIDAN_HROCK", + "ACTOR_EN_HORSE_GANON", + "ACTOR_BG_HIDAN_ROCK", + "ACTOR_BG_HIDAN_RSEKIZOU", + "ACTOR_BG_HIDAN_SEKIZOU", + "ACTOR_BG_HIDAN_SIMA", + "ACTOR_BG_HIDAN_SYOKU", + "ACTOR_EN_XC", + "ACTOR_BG_HIDAN_CURTAIN", + "ACTOR_BG_SPOT00_HANEBASI", + "ACTOR_EN_MB", + "ACTOR_EN_BOMBF", + "ACTOR_EN_ZL2", + "ACTOR_BG_HIDAN_FSLIFT", + "ACTOR_EN_OE2", + "ACTOR_BG_YDAN_HASI", + "ACTOR_BG_YDAN_MARUTA", + "ACTOR_BOSS_GANONDROF", + "ACTOR_UNSET_53", + "ACTOR_EN_AM", + "ACTOR_EN_DEKUBABA", + "ACTOR_EN_M_FIRE1", + "ACTOR_EN_M_THUNDER", + "ACTOR_BG_DDAN_JD", + "ACTOR_BG_BREAKWALL", + "ACTOR_EN_JJ", + "ACTOR_EN_HORSE_ZELDA", + "ACTOR_BG_DDAN_KD", + "ACTOR_DOOR_WARP1", + "ACTOR_OBJ_SYOKUDAI", + "ACTOR_ITEM_B_HEART", + "ACTOR_EN_DEKUNUTS", + "ACTOR_BG_MENKURI_KAITEN", + "ACTOR_BG_MENKURI_EYE", + "ACTOR_EN_VALI", + "ACTOR_BG_MIZU_MOVEBG", + "ACTOR_BG_MIZU_WATER", + "ACTOR_ARMS_HOOK", + "ACTOR_EN_FHG", + "ACTOR_BG_MORI_HINERI", + "ACTOR_EN_BB", + "ACTOR_BG_TOKI_HIKARI", + "ACTOR_EN_YUKABYUN", + "ACTOR_BG_TOKI_SWD", + "ACTOR_EN_FHG_FIRE", + "ACTOR_BG_MJIN", + "ACTOR_BG_HIDAN_KOUSI", + "ACTOR_DOOR_TOKI", + "ACTOR_BG_HIDAN_HAMSTEP", + "ACTOR_EN_BIRD", + "ACTOR_UNSET_73", + "ACTOR_UNSET_74", + "ACTOR_UNSET_75", + "ACTOR_UNSET_76", + "ACTOR_EN_WOOD02", + "ACTOR_UNSET_78", + "ACTOR_UNSET_79", + "ACTOR_UNSET_7A", + "ACTOR_UNSET_7B", + "ACTOR_EN_LIGHTBOX", + "ACTOR_EN_PU_BOX", + "ACTOR_UNSET_7E", + "ACTOR_UNSET_7F", + "ACTOR_EN_TRAP", + "ACTOR_EN_AROW_TRAP", + "ACTOR_EN_VASE", + "ACTOR_UNSET_83", + "ACTOR_EN_TA", + "ACTOR_EN_TK", + "ACTOR_BG_MORI_BIGST", + "ACTOR_BG_MORI_ELEVATOR", + "ACTOR_BG_MORI_KAITENKABE", + "ACTOR_BG_MORI_RAKKATENJO", + "ACTOR_EN_VM", + "ACTOR_DEMO_EFFECT", + "ACTOR_DEMO_KANKYO", + "ACTOR_BG_HIDAN_FWBIG", + "ACTOR_EN_FLOORMAS", + "ACTOR_EN_HEISHI1", + "ACTOR_EN_RD", + "ACTOR_EN_PO_SISTERS", + "ACTOR_BG_HEAVY_BLOCK", + "ACTOR_BG_PO_EVENT", + "ACTOR_OBJ_MURE", + "ACTOR_EN_SW", + "ACTOR_BOSS_FD", + "ACTOR_OBJECT_KANKYO", + "ACTOR_EN_DU", + "ACTOR_EN_FD", + "ACTOR_EN_HORSE_LINK_CHILD", + "ACTOR_DOOR_ANA", + "ACTOR_BG_SPOT02_OBJECTS", + "ACTOR_BG_HAKA", + "ACTOR_MAGIC_WIND", + "ACTOR_MAGIC_FIRE", + "ACTOR_UNSET_A0", + "ACTOR_EN_RU1", + "ACTOR_BOSS_FD2", + "ACTOR_EN_FD_FIRE", + "ACTOR_EN_DH", + "ACTOR_EN_DHA", + "ACTOR_EN_RL", + "ACTOR_EN_ENCOUNT1", + "ACTOR_DEMO_DU", + "ACTOR_DEMO_IM", + "ACTOR_DEMO_TRE_LGT", + "ACTOR_EN_FW", + "ACTOR_BG_VB_SIMA", + "ACTOR_EN_VB_BALL", + "ACTOR_BG_HAKA_MEGANE", + "ACTOR_BG_HAKA_MEGANEBG", + "ACTOR_BG_HAKA_SHIP", + "ACTOR_BG_HAKA_SGAMI", + "ACTOR_UNSET_B2", + "ACTOR_EN_HEISHI2", + "ACTOR_EN_ENCOUNT2", + "ACTOR_EN_FIRE_ROCK", + "ACTOR_EN_BROB", + "ACTOR_MIR_RAY", + "ACTOR_BG_SPOT09_OBJ", + "ACTOR_BG_SPOT18_OBJ", + "ACTOR_BOSS_VA", + "ACTOR_BG_HAKA_TUBO", + "ACTOR_BG_HAKA_TRAP", + "ACTOR_BG_HAKA_HUTA", + "ACTOR_BG_HAKA_ZOU", + "ACTOR_BG_SPOT17_FUNEN", + "ACTOR_EN_SYATEKI_ITM", + "ACTOR_EN_SYATEKI_MAN", + "ACTOR_EN_TANA", + "ACTOR_EN_NB", + "ACTOR_BOSS_MO", + "ACTOR_EN_SB", + "ACTOR_EN_BIGOKUTA", + "ACTOR_EN_KAREBABA", + "ACTOR_BG_BDAN_OBJECTS", + "ACTOR_DEMO_SA", + "ACTOR_DEMO_GO", + "ACTOR_EN_IN", + "ACTOR_EN_TR", + "ACTOR_BG_SPOT16_BOMBSTONE", + "ACTOR_UNSET_CE", + "ACTOR_BG_HIDAN_KOWARERUKABE", + "ACTOR_BG_BOMBWALL", + "ACTOR_BG_SPOT08_ICEBLOCK", + "ACTOR_EN_RU2", + "ACTOR_OBJ_DEKUJR", + "ACTOR_BG_MIZU_UZU", + "ACTOR_BG_SPOT06_OBJECTS", + "ACTOR_BG_ICE_OBJECTS", + "ACTOR_BG_HAKA_WATER", + "ACTOR_UNSET_D8", + "ACTOR_EN_MA2", + "ACTOR_EN_BOM_CHU", + "ACTOR_EN_HORSE_GAME_CHECK", + "ACTOR_BOSS_TW", + "ACTOR_EN_RR", + "ACTOR_EN_BA", + "ACTOR_EN_BX", + "ACTOR_EN_ANUBICE", + "ACTOR_EN_ANUBICE_FIRE", + "ACTOR_BG_MORI_HASHIGO", + "ACTOR_BG_MORI_HASHIRA4", + "ACTOR_BG_MORI_IDOMIZU", + "ACTOR_BG_SPOT16_DOUGHNUT", + "ACTOR_BG_BDAN_SWITCH", + "ACTOR_EN_MA1", + "ACTOR_BOSS_GANON", + "ACTOR_BOSS_SST", + "ACTOR_UNSET_EA", + "ACTOR_UNSET_EB", + "ACTOR_EN_NY", + "ACTOR_EN_FR", + "ACTOR_ITEM_SHIELD", + "ACTOR_BG_ICE_SHELTER", + "ACTOR_EN_ICE_HONO", + "ACTOR_ITEM_OCARINA", + "ACTOR_UNSET_F2", + "ACTOR_UNSET_F3", + "ACTOR_MAGIC_DARK", + "ACTOR_DEMO_6K", + "ACTOR_EN_ANUBICE_TAG", + "ACTOR_BG_HAKA_GATE", + "ACTOR_BG_SPOT15_SAKU", + "ACTOR_BG_JYA_GOROIWA", + "ACTOR_BG_JYA_ZURERUKABE", + "ACTOR_UNSET_FB", + "ACTOR_BG_JYA_COBRA", + "ACTOR_BG_JYA_KANAAMI", + "ACTOR_FISHING", + "ACTOR_OBJ_OSHIHIKI", + "ACTOR_BG_GATE_SHUTTER", + "ACTOR_EFF_DUST", + "ACTOR_BG_SPOT01_FUSYA", + "ACTOR_BG_SPOT01_IDOHASHIRA", + "ACTOR_BG_SPOT01_IDOMIZU", + "ACTOR_BG_PO_SYOKUDAI", + "ACTOR_BG_GANON_OTYUKA", + "ACTOR_BG_SPOT15_RRBOX", + "ACTOR_BG_UMAJUMP", + "ACTOR_UNSET_0109", + "ACTOR_ARROW_FIRE", + "ACTOR_ARROW_ICE", + "ACTOR_ARROW_LIGHT", + "ACTOR_UNSET_010D", + "ACTOR_UNSET_010E", + "ACTOR_ITEM_ETCETERA", + "ACTOR_OBJ_KIBAKO", + "ACTOR_OBJ_TSUBO", + "ACTOR_EN_WONDER_ITEM", + "ACTOR_EN_IK", + "ACTOR_DEMO_IK", + "ACTOR_EN_SKJ", + "ACTOR_EN_SKJNEEDLE", + "ACTOR_EN_G_SWITCH", + "ACTOR_DEMO_EXT", + "ACTOR_DEMO_SHD", + "ACTOR_EN_DNS", + "ACTOR_ELF_MSG", + "ACTOR_EN_HONOTRAP", + "ACTOR_EN_TUBO_TRAP", + "ACTOR_OBJ_ICE_POLY", + "ACTOR_BG_SPOT03_TAKI", + "ACTOR_BG_SPOT07_TAKI", + "ACTOR_EN_FZ", + "ACTOR_EN_PO_RELAY", + "ACTOR_BG_RELAY_OBJECTS", + "ACTOR_EN_DIVING_GAME", + "ACTOR_EN_KUSA", + "ACTOR_OBJ_BEAN", + "ACTOR_OBJ_BOMBIWA", + "ACTOR_UNSET_0128", + "ACTOR_UNSET_0129", + "ACTOR_OBJ_SWITCH", + "ACTOR_OBJ_ELEVATOR", + "ACTOR_OBJ_LIFT", + "ACTOR_OBJ_HSBLOCK", + "ACTOR_EN_OKARINA_TAG", + "ACTOR_EN_YABUSAME_MARK", + "ACTOR_EN_GOROIWA", + "ACTOR_EN_EX_RUPPY", + "ACTOR_EN_TORYO", + "ACTOR_EN_DAIKU", + "ACTOR_UNSET_0134", + "ACTOR_EN_NWC", + "ACTOR_EN_BLKOBJ", + "ACTOR_ITEM_INBOX", + "ACTOR_EN_GE1", + "ACTOR_OBJ_BLOCKSTOP", + "ACTOR_EN_SDA", + "ACTOR_EN_CLEAR_TAG", + "ACTOR_EN_NIW_LADY", + "ACTOR_EN_GM", + "ACTOR_EN_MS", + "ACTOR_EN_HS", + "ACTOR_BG_INGATE", + "ACTOR_EN_KANBAN", + "ACTOR_EN_HEISHI3", + "ACTOR_EN_SYATEKI_NIW", + "ACTOR_EN_ATTACK_NIW", + "ACTOR_BG_SPOT01_IDOSOKO", + "ACTOR_EN_SA", + "ACTOR_EN_WONDER_TALK", + "ACTOR_BG_GJYO_BRIDGE", + "ACTOR_EN_DS", + "ACTOR_EN_MK", + "ACTOR_EN_BOM_BOWL_MAN", + "ACTOR_EN_BOM_BOWL_PIT", + "ACTOR_EN_OWL", + "ACTOR_EN_ISHI", + "ACTOR_OBJ_HANA", + "ACTOR_OBJ_LIGHTSWITCH", + "ACTOR_OBJ_MURE2", + "ACTOR_EN_GO", + "ACTOR_EN_FU", + "ACTOR_UNSET_0154", + "ACTOR_EN_CHANGER", + "ACTOR_BG_JYA_MEGAMI", + "ACTOR_BG_JYA_LIFT", + "ACTOR_BG_JYA_BIGMIRROR", + "ACTOR_BG_JYA_BOMBCHUIWA", + "ACTOR_BG_JYA_AMISHUTTER", + "ACTOR_BG_JYA_BOMBIWA", + "ACTOR_BG_SPOT18_BASKET", + "ACTOR_UNSET_015D", + "ACTOR_EN_GANON_ORGAN", + "ACTOR_EN_SIOFUKI", + "ACTOR_EN_STREAM", + "ACTOR_UNSET_0161", + "ACTOR_EN_MM", + "ACTOR_EN_KO", + "ACTOR_EN_KZ", + "ACTOR_EN_WEATHER_TAG", + "ACTOR_BG_SST_FLOOR", + "ACTOR_EN_ANI", + "ACTOR_EN_EX_ITEM", + "ACTOR_BG_JYA_IRONOBJ", + "ACTOR_EN_JS", + "ACTOR_EN_JSJUTAN", + "ACTOR_EN_CS", + "ACTOR_EN_MD", + "ACTOR_EN_HY", + "ACTOR_EN_GANON_MANT", + "ACTOR_EN_OKARINA_EFFECT", + "ACTOR_EN_MAG", + "ACTOR_DOOR_GERUDO", + "ACTOR_ELF_MSG2", + "ACTOR_DEMO_GT", + "ACTOR_EN_PO_FIELD", + "ACTOR_EFC_ERUPC", + "ACTOR_BG_ZG", + "ACTOR_EN_HEISHI4", + "ACTOR_EN_ZL3", + "ACTOR_BOSS_GANON2", + "ACTOR_EN_KAKASI", + "ACTOR_EN_TAKARA_MAN", + "ACTOR_OBJ_MAKEOSHIHIKI", + "ACTOR_OCEFF_SPOT", + "ACTOR_END_TITLE", + "ACTOR_UNSET_0180", + "ACTOR_EN_TORCH", + "ACTOR_DEMO_EC", + "ACTOR_SHOT_SUN", + "ACTOR_EN_DY_EXTRA", + "ACTOR_EN_WONDER_TALK2", + "ACTOR_EN_GE2", + "ACTOR_OBJ_ROOMTIMER", + "ACTOR_EN_SSH", + "ACTOR_EN_STH", + "ACTOR_OCEFF_WIPE", + "ACTOR_OCEFF_STORM", + "ACTOR_EN_WEIYER", + "ACTOR_BG_SPOT05_SOKO", + "ACTOR_BG_JYA_1FLIFT", + "ACTOR_BG_JYA_HAHENIRON", + "ACTOR_BG_SPOT12_GATE", + "ACTOR_BG_SPOT12_SAKU", + "ACTOR_EN_HINTNUTS", + "ACTOR_EN_NUTSBALL", + "ACTOR_BG_SPOT00_BREAK", + "ACTOR_EN_SHOPNUTS", + "ACTOR_EN_IT", + "ACTOR_EN_GELDB", + "ACTOR_OCEFF_WIPE2", + "ACTOR_OCEFF_WIPE3", + "ACTOR_EN_NIW_GIRL", + "ACTOR_EN_DOG", + "ACTOR_EN_SI", + "ACTOR_BG_SPOT01_OBJECTS2", + "ACTOR_OBJ_COMB", + "ACTOR_BG_SPOT11_BAKUDANKABE", + "ACTOR_OBJ_KIBAKO2", + "ACTOR_EN_DNT_DEMO", + "ACTOR_EN_DNT_JIJI", + "ACTOR_EN_DNT_NOMAL", + "ACTOR_EN_GUEST", + "ACTOR_BG_BOM_GUARD", + "ACTOR_EN_HS2", + "ACTOR_DEMO_KEKKAI", + "ACTOR_BG_SPOT08_BAKUDANKABE", + "ACTOR_BG_SPOT17_BAKUDANKABE", + "ACTOR_UNSET_01A9", + "ACTOR_OBJ_MURE3", + "ACTOR_EN_TG", + "ACTOR_EN_MU", + "ACTOR_EN_GO2", + "ACTOR_EN_WF", + "ACTOR_EN_SKB", + "ACTOR_DEMO_GJ", + "ACTOR_DEMO_GEFF", + "ACTOR_BG_GND_FIREMEIRO", + "ACTOR_BG_GND_DARKMEIRO", + "ACTOR_BG_GND_SOULMEIRO", + "ACTOR_BG_GND_NISEKABE", + "ACTOR_BG_GND_ICEBLOCK", + "ACTOR_EN_GB", + "ACTOR_EN_GS", + "ACTOR_BG_MIZU_BWALL", + "ACTOR_BG_MIZU_SHUTTER", + "ACTOR_EN_DAIKU_KAKARIKO", + "ACTOR_BG_BOWL_WALL", + "ACTOR_EN_WALL_TUBO", + "ACTOR_EN_PO_DESERT", + "ACTOR_EN_CROW", + "ACTOR_DOOR_KILLER", + "ACTOR_BG_SPOT11_OASIS", + "ACTOR_BG_SPOT18_FUTA", + "ACTOR_BG_SPOT18_SHUTTER", + "ACTOR_EN_MA3", + "ACTOR_EN_COW", + "ACTOR_BG_ICE_TURARA", + "ACTOR_BG_ICE_SHUTTER", + "ACTOR_EN_KAKASI2", + "ACTOR_EN_KAKASI3", + "ACTOR_OCEFF_WIPE4", + "ACTOR_EN_EG", + "ACTOR_BG_MENKURI_NISEKABE", + "ACTOR_EN_ZO", + "ACTOR_OBJ_MAKEKINSUTA", + "ACTOR_EN_GE3", + "ACTOR_OBJ_TIMEBLOCK", + "ACTOR_OBJ_HAMISHI", + "ACTOR_EN_ZL4", + "ACTOR_EN_MM2", + "ACTOR_BG_JYA_BLOCK", + "ACTOR_OBJ_WARP2BLOCK", +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/EndMarker.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/EndMarker.cpp new file mode 100644 index 0000000000..a077ce9744 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/EndMarker.cpp @@ -0,0 +1,23 @@ +#include "EndMarker.h" +#include "../../StringHelper.h" + +using namespace std; + +EndMarker::EndMarker(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ +} + +string EndMarker::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + return StringHelper::Sprintf("%s 0x00, 0x00", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str()); +} + +string EndMarker::GetCommandCName() +{ + return "SCmdEndMarker"; +} + +RoomCommand EndMarker::GetRoomCommand() +{ + return RoomCommand::EndMarker; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/EndMarker.h b/tools/ZAPD/ZAPD/ZRoom/Commands/EndMarker.h new file mode 100644 index 0000000000..74aae4ac8c --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/EndMarker.h @@ -0,0 +1,15 @@ +#pragma once + +#include "../ZRoomCommand.h" + +class EndMarker : public ZRoomCommand +{ +public: + EndMarker(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual std::string GetCommandCName(); + virtual RoomCommand GetRoomCommand(); + +private: +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetActorList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetActorList.cpp new file mode 100644 index 0000000000..5869d6e32f --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetActorList.cpp @@ -0,0 +1,107 @@ +#include "SetActorList.h" +#include "../../ZFile.h" +#include "../ZRoom.h" +#include "../ActorList.h" +#include "../../BitConverter.h" +#include "../../StringHelper.h" + +using namespace std; + +SetActorList::SetActorList(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ + numActors = rawData[rawDataIndex + 1]; + segmentOffset = SEG2FILESPACE(BitConverter::ToInt32BE(rawData, rawDataIndex + 4)); + + _rawData = rawData; + _rawDataIndex = rawDataIndex; + + if (segmentOffset != 0) + zRoom->parent->AddDeclarationPlaceholder(segmentOffset); +} + +string SetActorList::GetSourceOutputCode(std::string prefix) +{ + return ""; +} + +string SetActorList::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + return ""; +} + + +string SetActorList::GenerateSourceCodePass2(string roomName, int baseAddress) +{ + string sourceOutput = ""; + int numActorsReal = zRoom->GetDeclarationSizeFromNeighbor(segmentOffset) / 16; + actors = vector(); + uint32_t currentPtr = segmentOffset; + + for (int i = 0; i < numActorsReal; i++) + { + ActorSpawnEntry* entry = new ActorSpawnEntry(_rawData, currentPtr); + actors.push_back(entry); + + currentPtr += 16; + } + + sourceOutput += StringHelper::Sprintf("%s 0x%02X, (u32)%sActorList0x%06X };", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str(), numActors, roomName.c_str(), segmentOffset); + + //zRoom->parent->AddDeclaration(segmentOffset, DeclarationAlignment::None, DeclarationPadding::None, GetRawDataSize(), + //"SCmdActorList", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress), sourceOutput); + + string declaration = ""; + + int index = 0; + for (ActorSpawnEntry* entry : actors) + { + if (entry->actorNum < sizeof(ActorList) / sizeof(ActorList[0])) + declaration += StringHelper::Sprintf("\t{ %s, %i, %i, %i, %i, %i, %i, 0x%04X }, //0x%06X", ActorList[entry->actorNum].c_str(), entry->posX, entry->posY, entry->posZ, entry->rotX, entry->rotY, entry->rotZ, (uint16_t)entry->initVar, segmentOffset + (index * 16)); + else + declaration += StringHelper::Sprintf("\t{ 0x%04X, %i, %i, %i, %i, %i, %i, 0x%04X }, //0x%06X", entry->actorNum, entry->posX, entry->posY, entry->posZ, entry->rotX, entry->rotY, entry->rotZ, (uint16_t)entry->initVar, segmentOffset + (index * 16)); + + if (index < actors.size() - 1) + declaration += "\n"; + + index++; + } + + zRoom->parent->AddDeclarationArray(segmentOffset, DeclarationAlignment::None, DeclarationPadding::Pad16, actors.size() * 16, + "ActorEntry", StringHelper::Sprintf("%sActorList0x%06X", roomName.c_str(), segmentOffset), actors.size(), declaration); + + return sourceOutput; +} + +int32_t SetActorList::GetRawDataSize() +{ + return ZRoomCommand::GetRawDataSize() + ((int)actors.size() * 16); +} + +string SetActorList::GenerateExterns() +{ + return StringHelper::Sprintf("extern ActorEntry %sActorList0x%06X[%i];\n", zRoom->GetName().c_str(), segmentOffset, (int)actors.size()); +} + +string SetActorList::GetCommandCName() +{ + return "SCmdActorList"; +} + +RoomCommand SetActorList::GetRoomCommand() +{ + return RoomCommand::SetActorList; +} + +ActorSpawnEntry::ActorSpawnEntry(std::vector rawData, int rawDataIndex) +{ + uint8_t* data = rawData.data(); + + actorNum = BitConverter::ToInt16BE(data, rawDataIndex + 0); + posX = BitConverter::ToInt16BE(data, rawDataIndex + 2); + posY = BitConverter::ToInt16BE(data, rawDataIndex + 4); + posZ = BitConverter::ToInt16BE(data, rawDataIndex + 6); + rotX = BitConverter::ToInt16BE(data, rawDataIndex + 8); + rotY = BitConverter::ToInt16BE(data, rawDataIndex + 10); + rotZ = BitConverter::ToInt16BE(data, rawDataIndex + 12); + initVar = BitConverter::ToInt16BE(data, rawDataIndex + 14); +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetActorList.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetActorList.h new file mode 100644 index 0000000000..c5b12b2fc7 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetActorList.h @@ -0,0 +1,39 @@ +#pragma once + +#include "../ZRoomCommand.h" + +class ActorSpawnEntry +{ +public: + uint16_t actorNum; + int16_t posX; + int16_t posY; + int16_t posZ; + int16_t rotX; + int16_t rotY; + int16_t rotZ; + uint16_t initVar; + + ActorSpawnEntry(std::vector rawData, int rawDataIndex); +}; + +class SetActorList : public ZRoomCommand +{ +public: + SetActorList(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + std::string GetSourceOutputCode(std::string prefix); + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual std::string GenerateSourceCodePass2(std::string roomName, int baseAddress); + virtual RoomCommand GetRoomCommand(); + virtual int32_t GetRawDataSize(); + virtual std::string GetCommandCName(); + virtual std::string GenerateExterns(); + +private: + int numActors; + std::vector actors; + uint32_t segmentOffset; + std::vector _rawData; + int _rawDataIndex; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetAlternateHeaders.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetAlternateHeaders.cpp new file mode 100644 index 0000000000..8f55c6445a --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetAlternateHeaders.cpp @@ -0,0 +1,66 @@ +#include "SetAlternateHeaders.h" +#include "../../ZFile.h" +#include "../../BitConverter.h" +#include "../../StringHelper.h" + +using namespace std; + +SetAlternateHeaders::SetAlternateHeaders(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ + segmentOffset = SEG2FILESPACE(BitConverter::ToInt32BE(rawData, rawDataIndex + 4)); + + if (segmentOffset != 0) + zRoom->parent->AddDeclarationPlaceholder(segmentOffset); + + _rawData = rawData; + _rawDataIndex = rawDataIndex; +} + +string SetAlternateHeaders::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + string sourceOutput = ""; + int numHeaders = zRoom->GetDeclarationSizeFromNeighbor(segmentOffset) / 4; + + for (int i = 0; i < numHeaders; i++) + { + int32_t address = BitConverter::ToInt32BE(_rawData, segmentOffset + (i * 4)); + headers.push_back(address); + + if (address != 0) + zRoom->commandSets.push_back(CommandSet(address)); + } + + sourceOutput += StringHelper::Sprintf("%s 0, (u32)&%sAlternateHeaders0x%06X", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str(), roomName.c_str(), segmentOffset); + + string declaration = ""; + + for (int i = 0; i < numHeaders; i++) + { + //sprintf(line, "\t0x%06X,\n", headers[i]); + + if (headers[i] == 0) + declaration += StringHelper::Sprintf("\t0,\n"); + else + declaration += StringHelper::Sprintf("\t(u32)&%sSet%04XCmd00,\n", roomName.c_str(), headers[i] & 0x00FFFFFF); + } + + zRoom->parent->declarations[segmentOffset] = new Declaration(DeclarationAlignment::None, headers.size() * 4, + "u32", StringHelper::Sprintf("%sAlternateHeaders0x%06X", roomName.c_str(), segmentOffset), true, declaration); + + return sourceOutput; +} + +int32_t SetAlternateHeaders::GetRawDataSize() +{ + return ZRoomCommand::GetRawDataSize() + 0; +} + +string SetAlternateHeaders::GetCommandCName() +{ + return "SCmdAltHeaders"; +} + +RoomCommand SetAlternateHeaders::GetRoomCommand() +{ + return RoomCommand::SetAlternateHeaders; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetAlternateHeaders.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetAlternateHeaders.h new file mode 100644 index 0000000000..d1dca33ca4 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetAlternateHeaders.h @@ -0,0 +1,21 @@ +#pragma once + +#include "../ZRoomCommand.h" +#include "../ZRoom.h" + +class SetAlternateHeaders : public ZRoomCommand +{ +public: + SetAlternateHeaders(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual int32_t GetRawDataSize(); + virtual std::string GetCommandCName(); + virtual RoomCommand GetRoomCommand(); + +private: + int32_t segmentOffset; + std::vector headers; + std::vector _rawData; + int _rawDataIndex; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetCameraSettings.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCameraSettings.cpp new file mode 100644 index 0000000000..830aacc439 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCameraSettings.cpp @@ -0,0 +1,26 @@ +#include "SetCameraSettings.h" +#include "../../BitConverter.h" +#include "../../StringHelper.h" + +using namespace std; + +SetCameraSettings::SetCameraSettings(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ + cameraMovement = rawData[rawDataIndex + 0x01]; + mapHighlight = BitConverter::ToInt32BE(rawData, rawDataIndex + 4); +} + +string SetCameraSettings::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + return StringHelper::Sprintf("%s 0x%02X, 0x%08X", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str(), cameraMovement, mapHighlight); +} + +string SetCameraSettings::GetCommandCName() +{ + return "SCmdMiscSettings"; +} + +RoomCommand SetCameraSettings::GetRoomCommand() +{ + return RoomCommand::SetCameraSettings; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetCameraSettings.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCameraSettings.h new file mode 100644 index 0000000000..3e197e7fa6 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCameraSettings.h @@ -0,0 +1,17 @@ +#pragma once + +#include "../ZRoomCommand.h" + +class SetCameraSettings : public ZRoomCommand +{ +public: + SetCameraSettings(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual std::string GetCommandCName(); + virtual RoomCommand GetRoomCommand(); + +private: + uint8_t cameraMovement; + uint32_t mapHighlight; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetCollisionHeader.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCollisionHeader.cpp new file mode 100644 index 0000000000..7141abf960 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCollisionHeader.cpp @@ -0,0 +1,38 @@ +#include "SetCollisionHeader.h" +#include "../ZRoom.h" +#include "../../ZFile.h" +#include "../../BitConverter.h" +#include "../../StringHelper.h" + +using namespace std; + +SetCollisionHeader::SetCollisionHeader(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ + segmentOffset = SEG2FILESPACE(BitConverter::ToInt32BE(rawData, rawDataIndex + 4)); + collisionHeader = ZCollisionHeader(nZRoom->parent, StringHelper::Sprintf("%sCollisionHeader0x%06X", nZRoom->GetName().c_str(), segmentOffset), rawData, segmentOffset); +} + +string SetCollisionHeader::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + return StringHelper::Sprintf("%s 0x00, (u32)&%sCollisionHeader0x%06X", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str(), zRoom->GetName().c_str(), segmentOffset); +} + +string SetCollisionHeader::GenerateSourceCodePass2(string roomName, int baseAddress) +{ + return ""; +} + +string SetCollisionHeader::GetCommandCName() +{ + return "SCmdColHeader"; +} + +string SetCollisionHeader::GenerateExterns() +{ + return ""; +} + +RoomCommand SetCollisionHeader::GetRoomCommand() +{ + return RoomCommand::SetCollisionHeader; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetCollisionHeader.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCollisionHeader.h new file mode 100644 index 0000000000..d9ba188eb0 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCollisionHeader.h @@ -0,0 +1,20 @@ +#pragma once + +#include "../ZRoomCommand.h" +#include "../../ZCollision.h" + +class SetCollisionHeader : public ZRoomCommand +{ +public: + SetCollisionHeader(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual std::string GenerateSourceCodePass2(std::string roomName, int baseAddress); + virtual std::string GetCommandCName(); + virtual std::string GenerateExterns(); + virtual RoomCommand GetRoomCommand(); + +private: + ZCollisionHeader collisionHeader; + uint32_t segmentOffset; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetCutscenes.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCutscenes.cpp new file mode 100644 index 0000000000..c6320ffe83 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCutscenes.cpp @@ -0,0 +1,53 @@ +#include "SetCutscenes.h" +#include "../ZRoom.h" +#include "../../ZFile.h" +#include "../../BitConverter.h" +#include "../../StringHelper.h" + +using namespace std; + +SetCutscenes::SetCutscenes(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ + segmentOffset = BitConverter::ToInt32BE(rawData, rawDataIndex + 4) & 0x00FFFFFF; + + uint32_t curPtr = segmentOffset; + string output = ""; + + cutscene = new ZCutscene(rawData, segmentOffset, 9999); + + output += cutscene->GetSourceOutputCode(zRoom->GetName()); + + if (segmentOffset != 0) + zRoom->parent->AddDeclarationArray(segmentOffset, DeclarationAlignment::None, DeclarationPadding::Pad16, cutscene->GetRawDataSize(), "s32", + StringHelper::Sprintf("%sCutsceneData0x%06X", zRoom->GetName().c_str(), segmentOffset), 0, output); +} + +string SetCutscenes::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + return StringHelper::Sprintf("%s 0, (u32)%sCutsceneData0x%06X", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str(), zRoom->GetName().c_str(), segmentOffset); +} + +int32_t SetCutscenes::GetRawDataSize() +{ + return ZRoomCommand::GetRawDataSize() + (0); +} + +string SetCutscenes::GenerateExterns() +{ + return StringHelper::Sprintf("extern s32 %sCutsceneData0x%06X[];\n", zRoom->GetName().c_str(), segmentOffset); +} + +string SetCutscenes::GetCommandCName() +{ + return "SCmdCutsceneData"; +} + +RoomCommand SetCutscenes::GetRoomCommand() +{ + return RoomCommand::SetCutscenes; +} + +string SetCutscenes::GetSourceOutputCode(std::string prefix) +{ + return ""; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetCutscenes.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCutscenes.h new file mode 100644 index 0000000000..c2c383def1 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCutscenes.h @@ -0,0 +1,23 @@ +#pragma once + +#include "../ZRoomCommand.h" +#include "../../ZCutscene.h" + +class SetCutscenes : public ZRoomCommand +{ +public: + SetCutscenes(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + std::string GetSourceOutputCode(std::string prefix); + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual RoomCommand GetRoomCommand(); + virtual int32_t GetRawDataSize(); + virtual std::string GetCommandCName(); + virtual std::string GenerateExterns(); + +private: + ZCutscene* cutscene; + uint32_t segmentOffset; + std::vector _rawData; + int _rawDataIndex; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetEchoSettings.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetEchoSettings.cpp new file mode 100644 index 0000000000..1d4c9826b2 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetEchoSettings.cpp @@ -0,0 +1,24 @@ +#include "SetEchoSettings.h" +#include "../../StringHelper.h" + +using namespace std; + +SetEchoSettings::SetEchoSettings(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ + echo = rawData[rawDataIndex + 0x07]; +} + +string SetEchoSettings::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + return StringHelper::Sprintf("%s 0, { 0 }, 0x%02X", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str(), echo); +} + +string SetEchoSettings::GetCommandCName() +{ + return "SCmdEchoSettings"; +} + +RoomCommand SetEchoSettings::GetRoomCommand() +{ + return RoomCommand::SetEchoSettings; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetEchoSettings.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetEchoSettings.h new file mode 100644 index 0000000000..2f952addd8 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetEchoSettings.h @@ -0,0 +1,16 @@ +#pragma once + +#include "../ZRoomCommand.h" + +class SetEchoSettings : public ZRoomCommand +{ +public: + SetEchoSettings(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual std::string GetCommandCName(); + virtual RoomCommand GetRoomCommand(); + +private: + uint8_t echo; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetEntranceList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetEntranceList.cpp new file mode 100644 index 0000000000..12ed7c1523 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetEntranceList.cpp @@ -0,0 +1,71 @@ +#include "SetEntranceList.h" +#include "SetStartPositionList.h" +#include "../../ZFile.h" +#include "../ZRoom.h" +#include "../../BitConverter.h" +#include "../../StringHelper.h" + +using namespace std; + +SetEntranceList::SetEntranceList(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ + segmentOffset = BitConverter::ToInt32BE(rawData, rawDataIndex + 4) & 0x00FFFFFF; + entrances = vector(); + + _rawData = rawData; + _rawDataIndex = rawDataIndex; +} + +string SetEntranceList::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + string sourceOutput = StringHelper::Sprintf("%s 0x00, (u32)&%sEntranceList0x%06X", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str(), zRoom->GetName().c_str(), segmentOffset); + + // Parse Entrances and Generate Declaration + zRoom->parent->AddDeclarationPlaceholder(segmentOffset); // Make sure this segment is defined + int numEntrances = zRoom->GetDeclarationSizeFromNeighbor(segmentOffset) / 2; + uint32_t currentPtr = segmentOffset; + + for (int i = 0; i < numEntrances; i++) + { + EntranceEntry* entry = new EntranceEntry(_rawData, currentPtr); + entrances.push_back(entry); + + currentPtr += 2; + } + + string declaration = ""; + + int index = 0; + + for (EntranceEntry* entry : entrances) + { + declaration += StringHelper::Sprintf("\t{ 0x%02X, 0x%02X }, //0x%06X \n", entry->startPositionIndex, entry->roomToLoad, segmentOffset + (index * 2)); + index++; + } + + zRoom->parent->AddDeclarationArray(segmentOffset, DeclarationAlignment::None, entrances.size() * 2, "EntranceEntry", + StringHelper::Sprintf("%sEntranceList0x%06X", zRoom->GetName().c_str(), segmentOffset), entrances.size(), declaration); + + return sourceOutput; +} + +string SetEntranceList::GenerateExterns() +{ + return StringHelper::Sprintf("extern EntranceEntry %sEntranceList0x%06X[];\n", zRoom->GetName().c_str(), segmentOffset); +} + +string SetEntranceList::GetCommandCName() +{ + return "SCmdEntranceList"; +} + +RoomCommand SetEntranceList::GetRoomCommand() +{ + return RoomCommand::SetEntranceList; +} + +EntranceEntry::EntranceEntry(std::vector rawData, int rawDataIndex) +{ + startPositionIndex = rawData[rawDataIndex + 0]; + roomToLoad = rawData[rawDataIndex + 1]; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetEntranceList.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetEntranceList.h new file mode 100644 index 0000000000..9b0c05221b --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetEntranceList.h @@ -0,0 +1,29 @@ +#pragma once + +#include "../ZRoomCommand.h" + +class EntranceEntry +{ +public: + uint8_t startPositionIndex; + uint8_t roomToLoad; + + EntranceEntry(std::vector rawData, int rawDataIndex); +}; + +class SetEntranceList : public ZRoomCommand +{ +public: + SetEntranceList(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual std::string GenerateExterns(); + virtual std::string GetCommandCName(); + virtual RoomCommand GetRoomCommand(); + +private: + std::vector entrances; + uint32_t segmentOffset; + std::vector _rawData; + int32_t _rawDataIndex; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetExitList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetExitList.cpp new file mode 100644 index 0000000000..edb66f34ec --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetExitList.cpp @@ -0,0 +1,62 @@ +#include "SetExitList.h" +#include "../ZRoom.h" +#include "../../ZFile.h" +#include "../../BitConverter.h" +#include "../../StringHelper.h" + +using namespace std; + +SetExitList::SetExitList(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ + segmentOffset = SEG2FILESPACE(BitConverter::ToInt32BE(rawData, rawDataIndex + 4)); + exits = vector(); + + if (segmentOffset != 0) + zRoom->parent->AddDeclarationPlaceholder(segmentOffset); + + _rawData = rawData; + _rawDataIndex = rawDataIndex; +} + +string SetExitList::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + string sourceOutput = StringHelper::Sprintf("%s 0x00, (u32)&%sExitList0x%06X", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str(), zRoom->GetName().c_str(), segmentOffset); + + // Parse Entrances and Generate Declaration + zRoom->parent->AddDeclarationPlaceholder(segmentOffset); // Make sure this segment is defined + int numEntrances = zRoom->GetDeclarationSizeFromNeighbor(segmentOffset) / 2; + uint32_t currentPtr = segmentOffset; + + for (int i = 0; i < numEntrances; i++) + { + uint16_t exit = BitConverter::ToInt16BE(_rawData, currentPtr); + exits.push_back(exit); + + currentPtr += 2; + } + + string declaration = ""; + + for (uint16_t exit : exits) + declaration += StringHelper::Sprintf("\t0x%04X,\n", exit);; + + zRoom->parent->AddDeclarationArray(segmentOffset, DeclarationAlignment::None, exits.size() * 2, "u16", StringHelper::Sprintf("%sExitList0x%06X", zRoom->GetName().c_str(), segmentOffset), + exits.size(), declaration); + + return sourceOutput; +} + +string SetExitList::GenerateExterns() +{ + return StringHelper::Sprintf("extern u16 %sExitList0x%06X[];\n", zRoom->GetName().c_str(), segmentOffset);; +} + +string SetExitList::GetCommandCName() +{ + return "SCmdExitList"; +} + +RoomCommand SetExitList::GetRoomCommand() +{ + return RoomCommand::SetExitList; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetExitList.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetExitList.h new file mode 100644 index 0000000000..2624dd27cb --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetExitList.h @@ -0,0 +1,20 @@ +#pragma once + +#include "../ZRoomCommand.h" + +class SetExitList : public ZRoomCommand +{ +public: + SetExitList(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual std::string GenerateExterns(); + virtual std::string GetCommandCName(); + virtual RoomCommand GetRoomCommand(); + +private: + std::vector exits; + uint32_t segmentOffset; + std::vector _rawData; + int32_t _rawDataIndex; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetLightList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetLightList.cpp new file mode 100644 index 0000000000..57b5430664 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetLightList.cpp @@ -0,0 +1,53 @@ +#include "SetLightList.h" +#include "../../BitConverter.h" +#include "../../StringHelper.h" + +using namespace std; + +SetLightList::SetLightList(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ + this->ptrRoom = nZRoom; + this->numLights = rawData[rawDataIndex + 1]; + this->segment = BitConverter::ToInt32BE(rawData, rawDataIndex + 4) & 0x00FFFFFF; + + //std::string declarations = StringHelper::Sprintf("LightInfo %sLightInfo0x%06X[] =\n{\n", this->ptrRoom->GetName().c_str(), this->segment); + string declarations = ""; + + for (int i = 0; i < this->numLights; i++) + { + uint8_t type = rawData[this->segment + ((0xE * i) + 0)]; + std::vector params; + + for (int y = 0; y < 6; y++) + { + params.push_back(BitConverter::ToInt16BE(rawData, this->segment + ((0xE * i) + 2 + (y * 2)))); + } + + declarations += StringHelper::Sprintf("\t{ 0x%02X, { 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X } },\n", type, params[0], params[1], params[2], params[3], params[4], params[5]); + } + + declarations += "};\n"; + + this->ptrRoom->parent->AddDeclarationArray(this->segment, DeclarationAlignment::None, this->numLights * 0xE, "LightInfo", + StringHelper::Sprintf("%sLightInfo0x%06X", this->ptrRoom->GetName().c_str(), this->segment), this->numLights, declarations); +} + +string SetLightList::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + return StringHelper::Sprintf("%s %i, &%sLightInfo0x%06X};", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str(), this->numLights, this->ptrRoom->GetName().c_str(), this->segment); +} + +string SetLightList::GetCommandCName() +{ + return "SCmdLightList"; +} + +string SetLightList::GenerateExterns() +{ + return StringHelper::Sprintf("extern LightInfo %sLightInfo0x%06X[];\n", this->ptrRoom->GetName().c_str(), this->segment); +} + +RoomCommand SetLightList::GetRoomCommand() +{ + return RoomCommand::SetLightList; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetLightList.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetLightList.h new file mode 100644 index 0000000000..625d3b8e9d --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetLightList.h @@ -0,0 +1,25 @@ +#pragma once + +#include + +#include "ZFile.h" +#include "../ZRoom.h" +#include "../ZRoomCommand.h" + +class SetLightList : public ZRoomCommand +{ +public: + SetLightList(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual std::string GetCommandCName(); + virtual RoomCommand GetRoomCommand(); + virtual std::string GenerateExterns(); + +private: + uint8_t code; + uint8_t numLights; + uint32_t segment; + + ZRoom* ptrRoom; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetLightingSettings.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetLightingSettings.cpp new file mode 100644 index 0000000000..11af4e7106 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetLightingSettings.cpp @@ -0,0 +1,93 @@ +#include "SetLightingSettings.h" +#include "../ZRoom.h" +#include "../../ZFile.h" +#include "../../BitConverter.h" +#include "../../StringHelper.h" + +using namespace std; + +SetLightingSettings::SetLightingSettings(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ + uint8_t numLights = rawData[rawDataIndex + 1]; + segmentOffset = SEG2FILESPACE(BitConverter::ToInt32BE(rawData, rawDataIndex + 4)); + + for (int i = 0; i < numLights; i++) + settings.push_back(new LightingSettings(rawData, segmentOffset + (i * 22))); + + if (numLights > 0) + { + string declaration = ""; + + for (int i = 0; i < numLights; i++) + { + declaration += StringHelper::Sprintf("\t{ 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%04X, 0x%04X }, // 0x%06X \n", + settings[i]->ambientClrR, settings[i]->ambientClrG, settings[i]->ambientClrB, + settings[i]->diffuseClrA_R, settings[i]->diffuseClrA_G, settings[i]->diffuseClrA_B, + settings[i]->diffuseDirA_X, settings[i]->diffuseDirA_Y, settings[i]->diffuseDirA_Z, + settings[i]->diffuseClrB_R, settings[i]->diffuseClrB_G, settings[i]->diffuseClrB_B, + settings[i]->diffuseDirB_X, settings[i]->diffuseDirB_Y, settings[i]->diffuseDirB_Z, + settings[i]->fogClrR, settings[i]->fogClrG, settings[i]->fogClrB, + settings[i]->unk, settings[i]->drawDistance, segmentOffset + (i * 22)); + } + + zRoom->parent->AddDeclarationArray(segmentOffset, DeclarationAlignment::None, DeclarationPadding::None, numLights * 22, "LightSettings", + StringHelper::Sprintf("%sLightSettings0x%06X", zRoom->GetName().c_str(), segmentOffset), numLights, declaration); + } +} + +string SetLightingSettings::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + return StringHelper::Sprintf("%s %i, (u32)&%sLightSettings0x%06X", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str(), settings.size(), zRoom->GetName().c_str(), segmentOffset); +} + +string SetLightingSettings::GenerateSourceCodePass2(string roomName, int baseAddress) +{ + return ""; +} + +string SetLightingSettings::GetCommandCName() +{ + return "SCmdLightSettingList"; +} + +string SetLightingSettings::GenerateExterns() +{ + return StringHelper::Sprintf("extern LightSettings %sLightSettings0x%06X[];\n", zRoom->GetName().c_str(), segmentOffset); +} + +RoomCommand SetLightingSettings::GetRoomCommand() +{ + return RoomCommand::SetLightingSettings; +} + +LightingSettings::LightingSettings(vector rawData, int rawDataIndex) +{ + uint8_t* data = rawData.data(); + + ambientClrR = data[rawDataIndex + 0]; + ambientClrG = data[rawDataIndex + 1]; + ambientClrB = data[rawDataIndex + 2]; + + diffuseClrA_R = data[rawDataIndex + 3]; + diffuseClrA_G = data[rawDataIndex + 4]; + diffuseClrA_B = data[rawDataIndex + 5]; + + diffuseDirA_X = data[rawDataIndex + 6]; + diffuseDirA_Y = data[rawDataIndex + 7]; + diffuseDirA_Z = data[rawDataIndex + 8]; + + diffuseClrB_R = data[rawDataIndex + 9]; + diffuseClrB_G = data[rawDataIndex + 10]; + diffuseClrB_B = data[rawDataIndex + 11]; + + diffuseDirB_X = data[rawDataIndex + 12]; + diffuseDirB_Y = data[rawDataIndex + 13]; + diffuseDirB_Z = data[rawDataIndex + 14]; + + fogClrR = data[rawDataIndex + 15]; + fogClrG = data[rawDataIndex + 16]; + fogClrB = data[rawDataIndex + 17]; + + unk = BitConverter::ToInt16BE(data, rawDataIndex + 18); + drawDistance = BitConverter::ToInt16BE(data, rawDataIndex + 20); +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetLightingSettings.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetLightingSettings.h new file mode 100644 index 0000000000..4b779d7158 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetLightingSettings.h @@ -0,0 +1,34 @@ +#pragma once + +#include "../ZRoomCommand.h" + +class LightingSettings +{ +public: + uint8_t ambientClrR, ambientClrG, ambientClrB; + uint8_t diffuseClrA_R, diffuseClrA_G, diffuseClrA_B; + uint8_t diffuseDirA_X, diffuseDirA_Y, diffuseDirA_Z; + uint8_t diffuseClrB_R, diffuseClrB_G, diffuseClrB_B; + uint8_t diffuseDirB_X, diffuseDirB_Y, diffuseDirB_Z; + uint8_t fogClrR, fogClrG, fogClrB; + uint16_t unk; + uint16_t drawDistance; + + LightingSettings(std::vector rawData, int rawDataIndex); +}; + +class SetLightingSettings : public ZRoomCommand +{ +public: + SetLightingSettings(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual std::string GenerateSourceCodePass2(std::string roomName, int baseAddress); + virtual std::string GetCommandCName(); + virtual std::string GenerateExterns(); + virtual RoomCommand GetRoomCommand(); + +private: + uint32_t segmentOffset; + std::vector settings; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.cpp new file mode 100644 index 0000000000..ba71cc67a8 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.cpp @@ -0,0 +1,443 @@ +#include "SetMesh.h" +#include "../../ZFile.h" +#include "../ZRoom.h" +#include "../../BitConverter.h" +#include "../../StringHelper.h" +#include +#include + +using namespace std; + +SetMesh::SetMesh(ZRoom* nZRoom, std::vector rawData, int rawDataIndex, int segAddressOffset) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ + data = rawData[rawDataIndex + 1]; + segmentOffset = SEG2FILESPACE(BitConverter::ToInt32BE(rawData, rawDataIndex + 4)); + + string declaration = ""; + char line[2048]; + + int8_t meshHeaderType = rawData[segmentOffset + 0]; + + if (meshHeaderType == 0) + { + MeshHeader0* meshHeader0 = new MeshHeader0(); + meshHeader0->headerType = 0; + meshHeader0->entries = vector(); + + meshHeader0->dListStart = BitConverter::ToInt32BE(rawData, segmentOffset + 4) & 0x00FFFFFF; + meshHeader0->dListEnd = BitConverter::ToInt32BE(rawData, segmentOffset + 8) & 0x00FFFFFF; + + int8_t numEntries = rawData[segmentOffset + 1]; + uint32_t currentPtr = meshHeader0->dListStart; + + // Hack for Syotes + for (int i = 0; i < abs(segAddressOffset); i++) + { + rawData.erase(rawData.begin()); + segmentOffset--; + } + + for (int i = 0; i < numEntries; i++) + { + MeshEntry0* entry = new MeshEntry0(); + entry->opaqueDListAddr = BitConverter::ToInt32BE(rawData, currentPtr + 0) & 0x00FFFFFF; + entry->translucentDListAddr = BitConverter::ToInt32BE(rawData, currentPtr + 4) & 0x00FFFFFF; + + if (entry->opaqueDListAddr != 0) + { + entry->opaqueDList = new ZDisplayList(rawData, entry->opaqueDListAddr, ZDisplayList::GetDListLength(rawData, entry->opaqueDListAddr)); + entry->opaqueDList->scene = zRoom->scene; + GenDListDeclarations(rawData, entry->opaqueDList); + } + + if (entry->translucentDListAddr != 0) + { + entry->translucentDList = new ZDisplayList(rawData, entry->translucentDListAddr, ZDisplayList::GetDListLength(rawData, entry->translucentDListAddr)); + entry->translucentDList->scene = zRoom->scene; + GenDListDeclarations(rawData, entry->translucentDList); + } + + meshHeader0->entries.push_back(entry); + + currentPtr += 8; + } + + //declaration += StringHelper::Sprintf("MeshHeader0 %sMeshHeade0x%06X = { { 0 }, 0x%02X, ", zRoom->GetName().c_str(), segmentOffset, meshHeader0->entries.size()); + declaration += StringHelper::Sprintf("{ 0 }, 0x%02X, ", meshHeader0->entries.size()); + + if (meshHeader0->dListStart != 0) + sprintf(line, "(u32)&%sMeshDListEntry0x%06X, ", zRoom->GetName().c_str(), meshHeader0->dListStart); + else + sprintf(line, "0, "); + + declaration += line; + + if (meshHeader0->dListEnd != 0) + sprintf(line, "(u32)&(%sMeshDListEntry0x%06X) + sizeof(%sMeshDListEntry0x%06X)", zRoom->GetName().c_str(), meshHeader0->dListStart, zRoom->GetName().c_str(), meshHeader0->dListStart); + else + sprintf(line, "0"); + + declaration += line; + + zRoom->parent->AddDeclaration(segmentOffset, DeclarationAlignment::Align16, 12, "MeshHeader0", StringHelper::Sprintf("%sMeshHeader0x%06X", zRoom->GetName().c_str(), segmentOffset), + declaration); + + declaration = ""; + + for (int i = 0; i < meshHeader0->entries.size(); i++) + { + if (meshHeader0->entries[i]->opaqueDListAddr != 0) + sprintf(line, "\t{ (u32)%sDlist0x%06X, ", zRoom->GetName().c_str(), meshHeader0->entries[i]->opaqueDListAddr); + else + sprintf(line, "\t{ 0, "); + + declaration += line; + + if (meshHeader0->entries[i]->translucentDListAddr != 0) + sprintf(line, "(u32)%sDlist0x%06X },\n", zRoom->GetName().c_str(), meshHeader0->entries[i]->translucentDListAddr); + else + sprintf(line, "0 },\n"); + + declaration += line; + } + + //declaration += "static u32 terminatorMaybe = 0x01000000; // This always appears after the mesh entries. Its purpose is not clear.\n"; + + zRoom->parent->AddDeclarationArray(meshHeader0->dListStart, DeclarationAlignment::None, DeclarationPadding::None, (meshHeader0->entries.size() * 8) + 0, "MeshEntry0", + StringHelper::Sprintf("%sMeshDListEntry0x%06X", zRoom->GetName().c_str(), meshHeader0->dListStart), meshHeader0->entries.size(), declaration); + + zRoom->parent->AddDeclaration(meshHeader0->dListStart + (meshHeader0->entries.size() * 8) + 0, DeclarationAlignment::None, DeclarationPadding::Pad16, 4, "static s32", + "terminatorMaybe", " 0x01000000 "); + + //zRoom->parent->declarations[meshHeader0->dListStart] = new Declaration(DeclarationAlignment::None, DeclarationPadding::Pad16, (meshHeader0->entries.size() * 8) + 4, declaration); + + meshHeader = meshHeader0; + } + else if (meshHeaderType == 1) + { + MeshHeader1Base* meshHeader1 = nullptr; + + uint8_t fmt = rawData[segmentOffset + 1]; + + if (fmt == 1) // Single Format + { + MeshHeader1Single* headerSingle = new MeshHeader1Single(); + + headerSingle->headerType = 1; + headerSingle->format = fmt; + headerSingle->entryRecord = BitConverter::ToInt32BE(rawData, segmentOffset + 4);// &0x00FFFFFF; + + headerSingle->imagePtr = BitConverter::ToInt32BE(rawData, segmentOffset + 8);// &0x00FFFFFF; + headerSingle->unknown = BitConverter::ToInt32BE(rawData, segmentOffset + 12); + headerSingle->unknown2 = BitConverter::ToInt32BE(rawData, segmentOffset + 16); + headerSingle->bgWidth = BitConverter::ToInt16BE(rawData, segmentOffset + 20); + headerSingle->bgHeight = BitConverter::ToInt16BE(rawData, segmentOffset + 22); + headerSingle->imageFormat = rawData[segmentOffset + 24]; + headerSingle->imageSize = rawData[segmentOffset + 25]; + headerSingle->imagePal = BitConverter::ToInt16BE(rawData, segmentOffset + 26); + headerSingle->imageFlip = BitConverter::ToInt16BE(rawData, segmentOffset + 28); + + declaration += StringHelper::Sprintf("{ { 1 }, 1, 0x%06X }, 0x%06X, ", + headerSingle->entryRecord, headerSingle->imagePtr); + + declaration += StringHelper::Sprintf("0x%06X, 0x%06X, %i, %i, %i, %i, %i, %i\n", + headerSingle->unknown, headerSingle->unknown2, headerSingle->bgWidth, headerSingle->bgHeight, headerSingle->imageFormat, headerSingle->imageSize, headerSingle->imagePal, headerSingle->imageFlip); + + zRoom->parent->AddDeclaration(segmentOffset, DeclarationAlignment::None, DeclarationPadding::Pad16, 0x1E, "MeshHeader1Single", + StringHelper::Sprintf("%sMeshHeader0x%06X", zRoom->GetName().c_str(), segmentOffset), declaration); + + //if (headerSingle->imagePtr != 0) + //{ + //zRoom->declarations[headerSingle->imagePtr] = new Declaration(DeclarationAlignment::None, DeclarationPadding::Pad16, 0x1E, declaration); + //} + + meshHeader1 = headerSingle; +; } + else if (fmt == 2) // Multi-Format + { + MeshHeader1Multi* headerMulti = new MeshHeader1Multi(); + + headerMulti->headerType = 1; + headerMulti->format = fmt; + headerMulti->entryRecord = BitConverter::ToInt32BE(rawData, segmentOffset + 4);// &0x00FFFFFF; + + headerMulti->bgCnt = rawData[segmentOffset + 8]; + headerMulti->bgRecordPtr = BitConverter::ToInt32BE(rawData, segmentOffset + 12); + + //zRoom->declarations[segmentOffset] = new Declaration(DeclarationAlignment::None, DeclarationPadding::Pad16, 12, ""); + + declaration += StringHelper::Sprintf("{ { 1 }, 2, 0x%06X }, 0x%06X, 0x%06X", + headerMulti->entryRecord, headerMulti->bgCnt, headerMulti->bgRecordPtr); + + zRoom->parent->AddDeclaration(segmentOffset, DeclarationAlignment::None, DeclarationPadding::Pad16, 16, "MeshHeader1Multi", + StringHelper::Sprintf("%sMeshHeader0x%06X", zRoom->GetName().c_str(), segmentOffset), declaration); + + //zRoom->parent->declarations[segmentOffset] = new Declaration(DeclarationAlignment::None, DeclarationPadding::Pad16, 16, declaration); + + meshHeader1 = headerMulti; + } + else // UH OH + { + int bp = 0; + } + + meshHeader1->headerType = 1; + meshHeader1->format = fmt; + meshHeader1->entryRecord = BitConverter::ToInt32BE(rawData, segmentOffset + 4) & 0x00FFFFFF; + + + meshHeader = meshHeader1; + } + else if (meshHeaderType == 2) + { + MeshHeader2* meshHeader2 = new MeshHeader2(); + meshHeader2->headerType = 2; + + meshHeader2->entries = vector(); + meshHeader2->dListStart = BitConverter::ToInt32BE(rawData, segmentOffset + 4) & 0x00FFFFFF; + meshHeader2->dListEnd = BitConverter::ToInt32BE(rawData, segmentOffset + 8) & 0x00FFFFFF; + + int8_t numEntries = rawData[segmentOffset + 1]; + uint32_t currentPtr = meshHeader2->dListStart; + + // HOTSPOT + for (int i = 0; i < numEntries; i++) + { + MeshEntry2* entry = new MeshEntry2(); + entry->playerXMax = BitConverter::ToInt16BE(rawData, currentPtr + 0); + entry->playerZMax = BitConverter::ToInt16BE(rawData, currentPtr + 2); + entry->playerXMin = BitConverter::ToInt16BE(rawData, currentPtr + 4); + entry->playerZMin = BitConverter::ToInt16BE(rawData, currentPtr + 6); + + entry->opaqueDListAddr = BitConverter::ToInt32BE(rawData, currentPtr + 8) & 0x00FFFFFF; + entry->translucentDListAddr = BitConverter::ToInt32BE(rawData, currentPtr + 12) & 0x00FFFFFF; + + if (entry->opaqueDListAddr != 0) + { + entry->opaqueDList = new ZDisplayList(rawData, entry->opaqueDListAddr, ZDisplayList::GetDListLength(rawData, entry->opaqueDListAddr)); + entry->opaqueDList->scene = zRoom->scene; + GenDListDeclarations(rawData, entry->opaqueDList); // HOTSPOT + } + + if (entry->translucentDListAddr != 0) + { + entry->translucentDList = new ZDisplayList(rawData, entry->translucentDListAddr, ZDisplayList::GetDListLength(rawData, entry->translucentDListAddr)); + entry->translucentDList->scene = zRoom->scene; + GenDListDeclarations(rawData, entry->translucentDList); // HOTSPOT + } + + meshHeader2->entries.push_back(entry); + + currentPtr += 16; + } + + sprintf(line, "{ 2 }, 0x%02lX, ", meshHeader2->entries.size()); + declaration += line; + + if (meshHeader2->dListStart != 0) + sprintf(line, "(u32)&%sMeshDListEntry0x%06X, ", zRoom->GetName().c_str(), meshHeader2->dListStart); + else + sprintf(line, "0, "); + + declaration += line; + + if (meshHeader2->dListEnd != 0) + sprintf(line, "(u32)&(%sMeshDListEntry0x%06X) + sizeof(%sMeshDListEntry0x%06X)", zRoom->GetName().c_str(), meshHeader2->dListStart, zRoom->GetName().c_str(), meshHeader2->dListStart); + else + sprintf(line, "0"); + + declaration += line; + + zRoom->parent->AddDeclaration(segmentOffset, DeclarationAlignment::None, 12, "MeshHeader2", + StringHelper::Sprintf("%sMeshHeader0x%06X", zRoom->GetName().c_str(), segmentOffset), declaration); + + declaration = ""; + + //sprintf(line, "MeshEntry2 %sMeshDListEntry0x%06X[%i] = \n{\n", zRoom->GetName().c_str(), meshHeader2->dListStart, meshHeader2->entries.size()); + //declaration += line; + + for (int i = 0; i < meshHeader2->entries.size(); i++) + { + sprintf(line, "\t{ %i, %i, %i, %i, ", meshHeader2->entries[i]->playerXMax, meshHeader2->entries[i]->playerZMax, meshHeader2->entries[i]->playerXMin, meshHeader2->entries[i]->playerZMin); + + declaration += line; + + if (meshHeader2->entries[i]->opaqueDListAddr != 0) + sprintf(line, "(u32)%sDlist0x%06X, ", zRoom->GetName().c_str(), meshHeader2->entries[i]->opaqueDListAddr); + else + sprintf(line, "0, "); + + declaration += line; + + if (meshHeader2->entries[i]->translucentDListAddr != 0) + sprintf(line, "(u32)%sDlist0x%06X },\n", zRoom->GetName().c_str(), meshHeader2->entries[i]->translucentDListAddr); + else + sprintf(line, "0 },\n"); + + declaration += line; + } + + //declaration += "};\n\n"; + //declaration += "static u32 terminatorMaybe = 0x01000000; // This always appears after the mesh entries. Its purpose is not clear.\n"; + + zRoom->parent->AddDeclarationArray(meshHeader2->dListStart, DeclarationAlignment::None, DeclarationPadding::None, (meshHeader2->entries.size() * 16) + 0, + "MeshEntry2", StringHelper::Sprintf("%sMeshDListEntry0x%06X", zRoom->GetName().c_str(), meshHeader2->dListStart, meshHeader2->entries.size()), meshHeader2->entries.size(), declaration); + + zRoom->parent->AddDeclaration(meshHeader2->dListStart + (meshHeader2->entries.size() * 16), DeclarationAlignment::None, DeclarationPadding::Pad16, 4, "static s32", + "terminatorMaybe", "0x01000000"); + + meshHeader = meshHeader2; + } +} + +void SetMesh::GenDListDeclarations(std::vector rawData, ZDisplayList* dList) +{ + string sourceOutput = dList->GetSourceOutputCode(zRoom->GetName()); // HOTSPOT + + string srcVarName = ""; + + if (Globals::Instance->includeFilePrefix) + srcVarName = StringHelper::Sprintf("%s%s", zRoom->GetName().c_str(), dList->GetName().c_str()); + else + srcVarName = StringHelper::Sprintf("%s", dList->GetName().c_str()); + + zRoom->parent->AddDeclarationArray(dList->GetRawDataIndex(), DeclarationAlignment::None, dList->GetRawDataSize(), "Gfx", srcVarName, 0, sourceOutput); + + for (ZDisplayList* otherDList : dList->otherDLists) + GenDListDeclarations(rawData, otherDList); + + for (pair vtxEntry : dList->vtxDeclarations) + { + zRoom->parent->AddDeclarationArray(vtxEntry.first, DeclarationAlignment::Align8, dList->vertices[vtxEntry.first].size() * 16, "Vtx", + StringHelper::Sprintf("%sVtx_%06X", zRoom->GetName().c_str(), vtxEntry.first), 0, vtxEntry.second); + + //zRoom->parent->declarations[vtxEntry.first] = new Declaration(DeclarationAlignment::Align8, dList->vertices[vtxEntry.first].size() * 16, vtxEntry.second); + } + + for (pair texEntry : dList->texDeclarations) + { + zRoom->textures[texEntry.first] = dList->textures[texEntry.first]; + + //zRoom->parent->AddDeclarationArray(texEntry.first, DeclarationAlignment::None, dList->textures[texEntry.first]->GetRawDataSize(), "u64", + //zRoom->textures[texEntry.first]->GetName(), 0, texEntry.second); + + if (Globals::Instance->debugMessages) + printf("SAVING IMAGE TO %s\n", Globals::Instance->outputPath.c_str()); + + zRoom->textures[texEntry.first]->Save(Globals::Instance->outputPath); + + zRoom->parent->AddDeclarationIncludeArray(texEntry.first, StringHelper::Sprintf("%s/%s.%s.inc.c", + Globals::Instance->outputPath.c_str(), Path::GetFileNameWithoutExtension(zRoom->textures[texEntry.first]->GetName()).c_str(), zRoom->textures[texEntry.first]->GetExternalExtension().c_str()), + zRoom->textures[texEntry.first]->GetRawDataSize(), "u64", StringHelper::Sprintf("%sTex_%06X", zRoom->textures[texEntry.first]->GetName().c_str(), texEntry.first), 0); + } +} + +std::string SetMesh::GenDListExterns(ZDisplayList* dList) +{ + string sourceOutput = ""; + + if (Globals::Instance->includeFilePrefix) + sourceOutput += StringHelper::Sprintf("extern Gfx %sDlist0x%06X[];\n", zRoom->GetName().c_str(), dList->GetRawDataIndex()); + else + sourceOutput += StringHelper::Sprintf("extern Gfx dlist0x%06X[];\n", dList->GetRawDataIndex()); + + for (ZDisplayList* otherDList : dList->otherDLists) + sourceOutput += GenDListExterns(otherDList); + + for (pair vtxEntry : dList->vtxDeclarations) + sourceOutput += StringHelper::Sprintf("extern Vtx %sVtx_%06X[%i];\n", zRoom->GetName().c_str(), vtxEntry.first, dList->vertices[vtxEntry.first].size()); + + for (pair texEntry : dList->texDeclarations) + sourceOutput += StringHelper::Sprintf("extern u64 %sTex_%06X[];\n", zRoom->GetName().c_str(), texEntry.first); + + sourceOutput += dList->defines; + + return sourceOutput; +} + +string SetMesh::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + string sourceOutput = ""; + + sourceOutput += StringHelper::Sprintf("%s %i, (u32)&%sMeshHeader0x%06X", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str(), data, zRoom->GetName().c_str(), segmentOffset); + + /*if (meshHeader->headerType == 0) + { + MeshHeader0* meshHeader0 = (MeshHeader0*)meshHeader; + + } + else + { + sourceOutput += "// SetMesh UNIMPLEMENTED HEADER TYPE!\n"; + } +*/ + return sourceOutput; +} + +string SetMesh::GenerateExterns() +{ + string sourceOutput = ""; + + if (meshHeader->headerType == 0) + { + MeshHeader0* meshHeader0 = (MeshHeader0*)meshHeader; + + sourceOutput += StringHelper::Sprintf("extern MeshHeader0 %sMeshHeader0x%06X;\n", zRoom->GetName().c_str(), segmentOffset); + sourceOutput += StringHelper::Sprintf("extern MeshEntry0 %sMeshDListEntry0x%06X[%i];\n", zRoom->GetName().c_str(), meshHeader0->dListStart, meshHeader0->entries.size()); + + for (MeshEntry0* entry : meshHeader0->entries) + { + if (entry->opaqueDList != nullptr) + sourceOutput += GenDListExterns(entry->opaqueDList); + + if (entry->translucentDList != nullptr) + sourceOutput += GenDListExterns(entry->translucentDList); + } + } + else if (meshHeader->headerType == 1) + { + MeshHeader1Base* meshHeader1 = (MeshHeader1Base*)meshHeader; + + if (meshHeader1->format == 1) + sourceOutput += StringHelper::Sprintf("extern MeshHeader1Single %sMeshHeader0x%06X;\n", zRoom->GetName().c_str(), segmentOffset); + else if (meshHeader1->format == 2) + sourceOutput += StringHelper::Sprintf("extern MeshHeader1Multi %sMeshHeader0x%06X;\n", zRoom->GetName().c_str(), segmentOffset); + } + else if (meshHeader->headerType == 2) + { + MeshHeader2* meshHeader2 = (MeshHeader2*)meshHeader; + + sourceOutput += StringHelper::Sprintf("extern MeshHeader2 %sMeshHeader0x%06X;\n", zRoom->GetName().c_str(), segmentOffset); + sourceOutput += StringHelper::Sprintf("extern MeshEntry2 %sMeshDListEntry0x%06X[%i];\n", zRoom->GetName().c_str(), meshHeader2->dListStart, meshHeader2->entries.size()); + + for (MeshEntry2* entry : meshHeader2->entries) + { + if (entry->opaqueDList != nullptr) + sourceOutput += GenDListExterns(entry->opaqueDList); + + if (entry->translucentDList != nullptr) + sourceOutput += GenDListExterns(entry->translucentDList); + } + } + else + { + //sourceOutput += "// SetMesh UNIMPLEMENTED HEADER TYPE!\n"; + } + + return sourceOutput; +} + +int32_t SetMesh::GetRawDataSize() +{ + return ZRoomCommand::GetRawDataSize(); +} + +string SetMesh::GetCommandCName() +{ + return "SCmdMesh"; +} + +RoomCommand SetMesh::GetRoomCommand() +{ + return RoomCommand::SetMesh; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.h new file mode 100644 index 0000000000..28899b068e --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.h @@ -0,0 +1,121 @@ +#pragma once + +#include "../ZRoomCommand.h" +#include "../../ZDisplayList.h" + +class MeshHeaderBase +{ +public: + int8_t headerType; // 0x00 +}; + +class MeshEntry0 +{ +public: + int32_t opaqueDListAddr; + int32_t translucentDListAddr; + + ZDisplayList* opaqueDList; + ZDisplayList* translucentDList; +}; + +class MeshHeader0 : public MeshHeaderBase +{ +public: + std::vector entries; + uint32_t dListStart; + uint32_t dListEnd; +}; + +class MeshHeader1Base : public MeshHeaderBase +{ +public: + int8_t format; // 0x01 + uint32_t entryRecord; // 0x04 +}; + +class MeshHeader1Single : public MeshHeader1Base +{ +public: + uint32_t imagePtr; // 0x08 + + uint32_t unknown; // 0x0C + uint32_t unknown2; // 0x10 + + uint16_t bgWidth; // 0x14 + uint16_t bgHeight; // 0x16 + + uint8_t imageFormat; // 0x18 + uint8_t imageSize; // 0x19 + uint16_t imagePal; // 0x1A + uint16_t imageFlip; // 0x1C +}; + +class MeshHeader1Multi : public MeshHeader1Base +{ +public: + uint8_t bgCnt; // 0x08 + uint32_t bgRecordPtr; // 0x0C +}; + +class BackgroundRecord +{ +public: + uint16_t unknown; // 0x00 + int8_t bgID; // 0x02 + + uint32_t imagePtr; // 0x04 + uint32_t unknown2; // 0x08 + uint32_t unknown3; // 0x0C + + uint16_t bgWidth; // 0x10 + uint16_t bgHeight; // 0x12 + + uint8_t imageFmt; // 0x14 + uint8_t imageSize; // 0x15 + uint16_t imagePal; // 0x16 + uint16_t imageFlip; // 0x18 +}; + +class MeshEntry2 +{ +public: + int16_t playerXMax, playerZMax; + int16_t playerXMin, playerZMin; + + int32_t opaqueDListAddr; + int32_t translucentDListAddr; + + ZDisplayList* opaqueDList; + ZDisplayList* translucentDList; +}; + +class MeshHeader2 : public MeshHeaderBase +{ +public: + std::vector entries; + uint32_t dListStart; + uint32_t dListEnd; +}; + +class SetMesh : public ZRoomCommand +{ +public: + SetMesh(ZRoom* nZRoom, std::vector rawData, int rawDataIndex, int segAddressOffset); + + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + //virtual std::string GenerateSourceCodePass2(std::string roomName, int baseAddress); + //virtual std::string GenerateSourceCodePass3(std::string roomName); + virtual std::string GenerateExterns(); + virtual std::string GetCommandCName(); + virtual RoomCommand GetRoomCommand(); + virtual int32_t GetRawDataSize(); + +private: + MeshHeaderBase* meshHeader; + uint32_t segmentOffset; + uint8_t data; + + void GenDListDeclarations(std::vector rawData, ZDisplayList* dList); + std::string GenDListExterns(ZDisplayList* dList); +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetObjectList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetObjectList.cpp new file mode 100644 index 0000000000..bec341fab9 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetObjectList.cpp @@ -0,0 +1,69 @@ +#include "SetObjectList.h" +#include "../ZRoom.h" +#include "../ObjectList.h" +#include "../../ZFile.h" +#include "../../BitConverter.h" +#include "../../StringHelper.h" + +using namespace std; + +SetObjectList::SetObjectList(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ + objects = vector(); + uint8_t objectCnt = rawData[rawDataIndex + 1]; + segmentOffset = SEG2FILESPACE(BitConverter::ToInt32BE(rawData, rawDataIndex + 4)); + uint32_t currentPtr = segmentOffset; + + for (int i = 0; i < objectCnt; i++) + { + uint16_t objectIndex = BitConverter::ToInt16BE(rawData, currentPtr); + objects.push_back(objectIndex); + currentPtr += 2; + } + + if (segmentOffset != 0) + zRoom->parent->AddDeclarationPlaceholder(segmentOffset); +} + +string SetObjectList::GenerateExterns() +{ + return StringHelper::Sprintf("s16 %sObjectList0x%06X[];\n", zRoom->GetName().c_str(), segmentOffset); +} + +string SetObjectList::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + string sourceOutput = ""; + + sourceOutput += StringHelper::Sprintf("%s 0x%02X, (u32)%sObjectList0x%06X", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str(), objects.size(), zRoom->GetName().c_str(), segmentOffset); + + string declaration = ""; + + for (int i = 0; i < objects.size(); i++) + { + uint16_t objectIndex = objects[i]; + declaration += StringHelper::Sprintf("\t%s,", ObjectList[objectIndex].c_str()); + + if (i < objects.size() - 1) + declaration += "\n"; + } + + zRoom->parent->AddDeclarationArray(segmentOffset, DeclarationAlignment::None, objects.size() * 2, "s16", + StringHelper::Sprintf("%sObjectList0x%06X", zRoom->GetName().c_str(), segmentOffset), objects.size(), declaration); + + return sourceOutput; +} + +int32_t SetObjectList::GetRawDataSize() +{ + return ZRoomCommand::GetRawDataSize() + (objects.size() * 2); +} + +string SetObjectList::GetCommandCName() +{ + return "SCmdObjectList"; +} + +RoomCommand SetObjectList::GetRoomCommand() +{ + return RoomCommand::SetObjectList; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetObjectList.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetObjectList.h new file mode 100644 index 0000000000..0c43eb6ec1 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetObjectList.h @@ -0,0 +1,19 @@ +#pragma once + +#include "../ZRoomCommand.h" + +class SetObjectList : public ZRoomCommand +{ +public: + SetObjectList(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual std::string GetCommandCName(); + virtual RoomCommand GetRoomCommand(); + virtual int32_t GetRawDataSize(); + virtual std::string GenerateExterns(); + +private: + std::vector objects; + uint32_t segmentOffset; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetPathways.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetPathways.cpp new file mode 100644 index 0000000000..059b468494 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetPathways.cpp @@ -0,0 +1,111 @@ +#include "SetPathways.h" +#include "../ZRoom.h" +#include "../../ZFile.h" +#include "../../BitConverter.h" +#include "../../StringHelper.h" + +using namespace std; + +SetPathways::SetPathways(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ + _rawData = rawData; + _rawDataIndex = rawDataIndex; + + segmentOffset = 0; + listSegmentOffset = 0; + + InitList(SEG2FILESPACE(BitConverter::ToInt32BE(rawData, rawDataIndex + 4))); + + uint32_t currentPtr = listSegmentOffset; + + if (segmentOffset != 0) + zRoom->parent->declarations[segmentOffset] = new Declaration(DeclarationAlignment::None, 0, "", "", false, ""); + + //if (listSegmentOffset != 0) + //zRoom->declarations[listSegmentOffset] = new Declaration(DeclarationAlignment::None, 0, ""); +} + +void SetPathways::InitList(uint32_t address) +{ + segmentOffset = address; + listSegmentOffset = SEG2FILESPACE(BitConverter::ToInt32BE(_rawData, address + 4)); + numPoints = _rawData[address + 0]; +} + +string SetPathways::GetSourceOutputCode(std::string prefix) +{ + return ""; +} + +string SetPathways::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + //int numPathsReal = zRoom->GetDeclarationSizeFromNeighbor(listSegmentOffset) / 6; + uint32_t currentPtr = listSegmentOffset; + + uint8_t* data = _rawData.data(); + + for (int i = 0; i < numPoints; i++) + { + PathwayEntry* entry = new PathwayEntry(); + entry->x = BitConverter::ToInt16BE(data, currentPtr + 0); + entry->y = BitConverter::ToInt16BE(data, currentPtr + 2); + entry->z = BitConverter::ToInt16BE(data, currentPtr + 4); + + pathways.push_back(entry); + + currentPtr += 6; + } + + return ""; +} + + +string SetPathways::GenerateSourceCodePass2(string roomName, int baseAddress) +{ + string sourceOutput = ""; + + sourceOutput += StringHelper::Sprintf("%s 0, (u32)&%sPathway0x%06X };", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str(), roomName.c_str(), segmentOffset); + + { + string declaration = StringHelper::Sprintf("%i, (u32)%sPathwayList0x%06X", numPoints, roomName.c_str(), listSegmentOffset); + + zRoom->parent->AddDeclaration(segmentOffset, DeclarationAlignment::None, DeclarationPadding::None, 8, "Path", + StringHelper::Sprintf("%sPathway0x%06X", roomName.c_str(), segmentOffset), declaration); + } + + { + string declaration = ""; + + int index = 0; + for (PathwayEntry* entry : pathways) + { + declaration += StringHelper::Sprintf("{ %i, %i, %i }, //0x%06X \n", entry->x, entry->y, entry->z, listSegmentOffset + (index * 6)); + index++; + } + + zRoom->parent->AddDeclarationArray(listSegmentOffset, DeclarationAlignment::None, DeclarationPadding::None, pathways.size() * 6, + "Vec3s", StringHelper::Sprintf("%sPathwayList0x%06X", roomName.c_str(), listSegmentOffset), pathways.size(), declaration); + } + + return sourceOutput; +} + +int32_t SetPathways::GetRawDataSize() +{ + return ZRoomCommand::GetRawDataSize() + (pathways.size() * 6); +} + +string SetPathways::GenerateExterns() +{ + return StringHelper::Sprintf("extern Vec3s %sPathwayList0x%06X[];\n", zRoom->GetName().c_str(), segmentOffset); +} + +string SetPathways::GetCommandCName() +{ + return "SCmdPathList"; +} + +RoomCommand SetPathways::GetRoomCommand() +{ + return RoomCommand::SetPathways; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetPathways.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetPathways.h new file mode 100644 index 0000000000..b24ca9dbd7 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetPathways.h @@ -0,0 +1,33 @@ +#pragma once + +#include "../ZRoomCommand.h" +#include "../../Vec3s.h" + +class PathwayEntry +{ +public: + int16_t x, y, z; +}; + +class SetPathways : public ZRoomCommand +{ +public: + SetPathways(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + std::string GetSourceOutputCode(std::string prefix); + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual std::string GenerateSourceCodePass2(std::string roomName, int baseAddress); + virtual RoomCommand GetRoomCommand(); + virtual int32_t GetRawDataSize(); + virtual std::string GetCommandCName(); + virtual std::string GenerateExterns(); + void InitList(uint32_t address); + +private: + uint32_t segmentOffset; + uint32_t listSegmentOffset; + int numPoints; + std::vector pathways; + std::vector _rawData; + int _rawDataIndex; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomBehavior.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomBehavior.cpp new file mode 100644 index 0000000000..b73335ca6c --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomBehavior.cpp @@ -0,0 +1,26 @@ +#include "SetRoomBehavior.h" +#include "../../BitConverter.h" +#include "../../StringHelper.h" + +using namespace std; + +SetRoomBehavior::SetRoomBehavior(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ + gameplayFlags = rawData[rawDataIndex + 0x01]; + gameplayFlags2 = BitConverter::ToInt32BE(rawData, rawDataIndex + 0x04); +} + +string SetRoomBehavior::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + return StringHelper::Sprintf("%s 0x%02X, 0x%08X", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str(), gameplayFlags, gameplayFlags2);; +} + +string SetRoomBehavior::GetCommandCName() +{ + return "SCmdRoomBehavior"; +} + +RoomCommand SetRoomBehavior::GetRoomCommand() +{ + return RoomCommand::SetRoomBehavior; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomBehavior.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomBehavior.h new file mode 100644 index 0000000000..9f21662d48 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomBehavior.h @@ -0,0 +1,17 @@ +#pragma once + +#include "../ZRoomCommand.h" + +class SetRoomBehavior : public ZRoomCommand +{ +public: + SetRoomBehavior(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual std::string GetCommandCName(); + virtual RoomCommand GetRoomCommand(); + +private: + uint8_t gameplayFlags; + uint32_t gameplayFlags2; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.cpp new file mode 100644 index 0000000000..7adefd4188 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.cpp @@ -0,0 +1,101 @@ +#include "SetRoomList.h" +#include "../ZRoom.h" +#include "../../ZFile.h" +#include "../../Globals.h" +#include "../../BitConverter.h" +#include "../../StringHelper.h" + +using namespace std; + +SetRoomList::SetRoomList(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ + int numRooms = rawData[rawDataIndex + 1]; + segmentOffset = BitConverter::ToInt32BE(rawData, rawDataIndex + 4) & 0x00FFFFFF; + + rooms = vector(); + + int32_t currentPtr = segmentOffset; + + for (int i = 0; i < numRooms; i++) + { + RoomEntry* entry = new RoomEntry(rawData, currentPtr); + rooms.push_back(entry); + + currentPtr += 8; + } + + //string declaration = ""; + + /*for (int i = 0; i < rooms.size(); i++) + { + RoomEntry* entry = rooms[i]; + + string roomName = StringHelper::Sprintf("%sRoom%i", StringHelper::Split(zRoom->GetName(), "_scene")[0].c_str(), i); + declaration += StringHelper::Sprintf("\t{ (u32)%sSegmentRomStart, (u32)%sSegmentRomEnd },\n", roomName.c_str(), roomName.c_str()); + }*/ + + //zRoom->parent->declarations[segmentOffset] = new Declaration(DeclarationAlignment::None, rooms.size() * 8, + //"RomFile", StringHelper::Sprintf("%sRoomList0x%06X", zRoom->GetName().c_str(), segmentOffset), true, declaration); +} + +string SetRoomList::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + return StringHelper::Sprintf("%s 0x%02X, (u32)&%sRoomList0x%06X", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str(), rooms.size(), zRoom->GetName().c_str(), segmentOffset); +} + +string SetRoomList::GenerateSourceCodePass2(string roomName, int baseAddress) +{ + return ""; +} + +string SetRoomList::GenerateExterns() +{ + return StringHelper::Sprintf("extern RomFile %sRoomList0x%06X[];\n", zRoom->GetName().c_str(), segmentOffset); +} + +string SetRoomList::GetCommandCName() +{ + return "SCmdRoomList"; +} + +RoomCommand SetRoomList::GetRoomCommand() +{ + return RoomCommand::SetRoomList; +} + +std::string SetRoomList::PreGenSourceFiles() +{ + string declaration = ""; + + for (ZFile* file : Globals::Instance->files) + { + for (ZResource* res : file->resources) + { + if (res->GetResourceType() == ZResourceType::Room && res != zRoom) + { + string roomName = res->GetName(); + declaration += StringHelper::Sprintf("\t{ (u32)_%sSegmentRomStart, (u32)_%sSegmentRomEnd },\n", roomName.c_str(), roomName.c_str()); + } + } + } + + zRoom->parent->declarations[segmentOffset] = new Declaration(DeclarationAlignment::None, rooms.size() * 8, + "RomFile", StringHelper::Sprintf("%sRoomList0x%06X", zRoom->GetName().c_str(), segmentOffset), true, declaration); + + return std::string(); +} + +std::string SetRoomList::Save() +{ + return std::string(); +} + +RoomEntry::RoomEntry(int32_t nVAS, int32_t nVAE) +{ + virtualAddressStart = nVAS; + virtualAddressEnd = nVAE; +} + +RoomEntry::RoomEntry(std::vector rawData, int rawDataIndex) : RoomEntry(BitConverter::ToInt32BE(rawData, rawDataIndex + 0), BitConverter::ToInt32BE(rawData, rawDataIndex + 4)) +{ +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.h new file mode 100644 index 0000000000..6fda993a4a --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.h @@ -0,0 +1,31 @@ +#pragma once + +#include "../ZRoomCommand.h" + +class RoomEntry +{ +public: + int32_t virtualAddressStart; + int32_t virtualAddressEnd; + + RoomEntry(int32_t nVAS, int32_t nVAE); + RoomEntry(std::vector rawData, int rawDataIndex); +}; + +class SetRoomList : public ZRoomCommand +{ +public: + SetRoomList(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual std::string GenerateSourceCodePass2(std::string roomName, int baseAddress); + virtual std::string GetCommandCName(); + virtual std::string GenerateExterns(); + virtual RoomCommand GetRoomCommand(); + virtual std::string PreGenSourceFiles(); + virtual std::string Save(); + +private: + std::vector rooms; + uint32_t segmentOffset; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetSkyboxModifier.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetSkyboxModifier.cpp new file mode 100644 index 0000000000..08f50c1844 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetSkyboxModifier.cpp @@ -0,0 +1,25 @@ +#include "SetSkyboxModifier.h" +#include "../../StringHelper.h" + +using namespace std; + +SetSkyboxModifier::SetSkyboxModifier(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ + disableSky = rawData[rawDataIndex + 0x04]; + disableSunMoon = rawData[rawDataIndex + 0x05]; +} + +string SetSkyboxModifier::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + return StringHelper::Sprintf("%s 0, 0, 0, 0x%02X, 0x%02X", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str(), disableSky, disableSunMoon);; +} + +string SetSkyboxModifier::GetCommandCName() +{ + return "SCmdSkyboxDisables"; +} + +RoomCommand SetSkyboxModifier::GetRoomCommand() +{ + return RoomCommand::SetSkyboxModifier; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetSkyboxModifier.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetSkyboxModifier.h new file mode 100644 index 0000000000..9d4262fcbb --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetSkyboxModifier.h @@ -0,0 +1,17 @@ +#pragma once + +#include "../ZRoomCommand.h" + +class SetSkyboxModifier : public ZRoomCommand +{ +public: + SetSkyboxModifier(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual std::string GetCommandCName(); + virtual RoomCommand GetRoomCommand(); + +private: + uint8_t disableSky; + uint8_t disableSunMoon; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetSkyboxSettings.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetSkyboxSettings.cpp new file mode 100644 index 0000000000..18c16365b0 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetSkyboxSettings.cpp @@ -0,0 +1,27 @@ +#include "SetSkyboxSettings.h" +#include "../../StringHelper.h" + +using namespace std; + +SetSkyboxSettings::SetSkyboxSettings(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ + skyboxNumber = rawData[rawDataIndex + 0x04]; + cloudsType = rawData[rawDataIndex + 0x05]; + lightingSettingsControl = rawData[rawDataIndex + 0x06]; +} + +string SetSkyboxSettings::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + return StringHelper::Sprintf("%s 0x00, 0x00, 0x00, 0x%02X, 0x%02X, 0x%02X", + ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str(), skyboxNumber, cloudsType, lightingSettingsControl); +} + +string SetSkyboxSettings::GetCommandCName() +{ + return "SCmdSkyboxSettings"; +} + +RoomCommand SetSkyboxSettings::GetRoomCommand() +{ + return RoomCommand::SetSkyboxSettings; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetSkyboxSettings.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetSkyboxSettings.h new file mode 100644 index 0000000000..de23c2a88a --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetSkyboxSettings.h @@ -0,0 +1,18 @@ +#pragma once + +#include "../ZRoomCommand.h" + +class SetSkyboxSettings : public ZRoomCommand +{ +public: + SetSkyboxSettings(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual std::string GetCommandCName(); + virtual RoomCommand GetRoomCommand(); + +private: + uint8_t skyboxNumber; + uint8_t cloudsType; + uint8_t lightingSettingsControl; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetSoundSettings.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetSoundSettings.cpp new file mode 100644 index 0000000000..3fc1985d95 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetSoundSettings.cpp @@ -0,0 +1,26 @@ +#include "SetSoundSettings.h" +#include "../../StringHelper.h" + +using namespace std; + +SetSoundSettings::SetSoundSettings(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ + reverb = rawData[rawDataIndex + 0x01]; + nightTimeSFX = rawData[rawDataIndex + 0x06]; + musicSequence = rawData[rawDataIndex + 0x07]; +} + +string SetSoundSettings::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + return StringHelper::Sprintf("%s 0x%02X, 0x00, 0x00, 0x00, 0x00, 0x%02X, 0x%02X", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str(), reverb, nightTimeSFX, musicSequence); +} + +string SetSoundSettings::GetCommandCName() +{ + return "SCmdSoundSettings"; +} + +RoomCommand SetSoundSettings::GetRoomCommand() +{ + return RoomCommand::SetSoundSettings; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetSoundSettings.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetSoundSettings.h new file mode 100644 index 0000000000..78851affde --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetSoundSettings.h @@ -0,0 +1,18 @@ +#pragma once + +#include "../ZRoomCommand.h" + +class SetSoundSettings : public ZRoomCommand +{ +public: + SetSoundSettings(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual std::string GetCommandCName(); + virtual RoomCommand GetRoomCommand(); + +private: + uint8_t reverb; + uint8_t nightTimeSFX; + uint8_t musicSequence; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetSpecialObjects.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetSpecialObjects.cpp new file mode 100644 index 0000000000..e22f6179e3 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetSpecialObjects.cpp @@ -0,0 +1,26 @@ +#include "SetSpecialObjects.h" +#include "../../BitConverter.h" +#include "../../StringHelper.h" + +using namespace std; + +SetSpecialObjects::SetSpecialObjects(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ + elfMessage = rawData[rawDataIndex + 0x01]; + globalObject = BitConverter::ToInt16BE(rawData, rawDataIndex + 6); +} + +string SetSpecialObjects::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + return StringHelper::Sprintf("%s 0x%02X, 0x%04X", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str(), elfMessage, globalObject); +} + +string SetSpecialObjects::GetCommandCName() +{ + return "SCmdSpecialFiles"; +} + +RoomCommand SetSpecialObjects::GetRoomCommand() +{ + return RoomCommand::SetSpecialObjects; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetSpecialObjects.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetSpecialObjects.h new file mode 100644 index 0000000000..c455fd8e5a --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetSpecialObjects.h @@ -0,0 +1,17 @@ +#pragma once + +#include "../ZRoomCommand.h" + +class SetSpecialObjects : public ZRoomCommand +{ +public: + SetSpecialObjects(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual std::string GetCommandCName(); + virtual RoomCommand GetRoomCommand(); + +private: + uint8_t elfMessage; + uint16_t globalObject; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetStartPositionList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetStartPositionList.cpp new file mode 100644 index 0000000000..0bbbff261c --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetStartPositionList.cpp @@ -0,0 +1,68 @@ +#include "SetStartPositionList.h" +#include "../ZRoom.h" +#include "../ActorList.h" +#include "../../ZFile.h" +#include "../../BitConverter.h" +#include "../../StringHelper.h" + +using namespace std; + +SetStartPositionList::SetStartPositionList(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ + int numActors = rawData[rawDataIndex + 1]; + segmentOffset = SEG2FILESPACE(BitConverter::ToInt32BE(rawData, rawDataIndex + 4)); + + if (segmentOffset != 0) + zRoom->parent->AddDeclarationPlaceholder(segmentOffset); + + actors = vector(); + + uint32_t currentPtr = segmentOffset; + + for (int i = 0; i < numActors; i++) + { + actors.push_back(new ActorSpawnEntry(rawData, currentPtr)); + currentPtr += 16; + } +} + +string SetStartPositionList::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + string sourceOutput = ""; + char line[2048]; + + sourceOutput += StringHelper::Sprintf("%s 0x%02X, (u32)&%sStartPositionList0x%06X", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str(), actors.size(), zRoom->GetName().c_str(), segmentOffset); + + string declaration = ""; + + for (ActorSpawnEntry* entry : actors) + { + declaration += StringHelper::Sprintf("\t{ %s, %i, %i, %i, %i, %i, %i, 0x%04X },\n", ActorList[entry->actorNum].c_str(), entry->posX, entry->posY, entry->posZ, + entry->rotX, entry->rotY, entry->rotZ, entry->initVar); + } + + zRoom->parent->AddDeclarationArray(segmentOffset, DeclarationAlignment::None, actors.size() * 16, "ActorEntry", + StringHelper::Sprintf("%sStartPositionList0x%06X", zRoom->GetName().c_str(), segmentOffset), 0, declaration); + + return sourceOutput; +} + +string SetStartPositionList::GenerateSourceCodePass2(string roomName, int baseAddress) +{ + return ""; +} + +string SetStartPositionList::GenerateExterns() +{ + return StringHelper::Sprintf("extern ActorEntry %sStartPositionList0x%06X[];\n", zRoom->GetName().c_str(), segmentOffset); +} + +string SetStartPositionList::GetCommandCName() +{ + return "SCmdSpawnList"; +} + +RoomCommand SetStartPositionList::GetRoomCommand() +{ + return RoomCommand::SetStartPositionList; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetStartPositionList.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetStartPositionList.h new file mode 100644 index 0000000000..63820150bf --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetStartPositionList.h @@ -0,0 +1,22 @@ +#pragma once + +#include "../ZRoomCommand.h" +#include "SetActorList.h" + + +class SetStartPositionList : public ZRoomCommand +{ +public: + std::vector actors; + + SetStartPositionList(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual std::string GenerateSourceCodePass2(std::string roomName, int baseAddress); + virtual std::string GetCommandCName(); + virtual std::string GenerateExterns(); + virtual RoomCommand GetRoomCommand(); +private: + + uint32_t segmentOffset; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetTimeSettings.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetTimeSettings.cpp new file mode 100644 index 0000000000..97e752a973 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetTimeSettings.cpp @@ -0,0 +1,27 @@ +#include "SetTimeSettings.h" +#include "../../BitConverter.h" +#include "../../StringHelper.h" + +using namespace std; + +SetTimeSettings::SetTimeSettings(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ + hour = rawData[rawDataIndex + 4]; + min = rawData[rawDataIndex + 5]; + unk = rawData[rawDataIndex + 6]; +} + +string SetTimeSettings::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + return StringHelper::Sprintf("%s 0x00, 0x00, 0x00, 0x%02X, 0x%02X, 0x%02X", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str(), hour, min, unk); +} + +string SetTimeSettings::GetCommandCName() +{ + return "SCmdTimeSettings"; +} + +RoomCommand SetTimeSettings::GetRoomCommand() +{ + return RoomCommand::SetTimeSettings; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetTimeSettings.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetTimeSettings.h new file mode 100644 index 0000000000..fbdfc23335 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetTimeSettings.h @@ -0,0 +1,21 @@ +#pragma once + +#include "../ZRoomCommand.h" + +class SetTimeSettings : public ZRoomCommand +{ +public: + SetTimeSettings(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual std::string GetCommandCName(); + virtual RoomCommand GetRoomCommand(); + +private: + //uint16_t time; + //int8_t speed; + + uint8_t hour; + uint8_t min; + uint8_t unk; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetTransitionActorList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetTransitionActorList.cpp new file mode 100644 index 0000000000..9173769572 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetTransitionActorList.cpp @@ -0,0 +1,85 @@ +#include "SetTransitionActorList.h" +#include "../ZRoom.h" +#include "../ActorList.h" +#include "../../ZFile.h" +#include "../../BitConverter.h" +#include "../../StringHelper.h" + +using namespace std; + +SetTransitionActorList::SetTransitionActorList(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ + int numActors = rawData[rawDataIndex + 1]; + segmentOffset = BitConverter::ToInt32BE(rawData, rawDataIndex + 4) & 0x00FFFFFF; + + transitionActors = vector(); + + uint32_t currentPtr = segmentOffset; + + for (int i = 0; i < numActors; i++) + { + TransitionActorEntry* entry = new TransitionActorEntry(rawData, currentPtr); + transitionActors.push_back(entry); + + currentPtr += 16; + } +} + +string SetTransitionActorList::GetSourceOutputCode(std::string prefix) +{ + return ""; +} + +string SetTransitionActorList::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + string sourceOutput = StringHelper::Sprintf("%s 0x%02X, (u32)%sTransitionActorList0x%06X", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str(), transitionActors.size(), roomName.c_str(), segmentOffset); + string declaration = ""; + + for (TransitionActorEntry* entry : transitionActors) + declaration += StringHelper::Sprintf("\t{ %i, %i, %i, %i, %s, %i, %i, %i, %i, 0x%04X }, \n", entry->frontObjectRoom, entry->frontTransitionReaction, entry->backObjectRoom, entry->backTransitionReaction, ActorList[entry->actorNum].c_str(), entry->posX, entry->posY, entry->posZ, entry->rotY, (uint16_t)entry->initVar); + + zRoom->parent->declarations[segmentOffset] = new Declaration(DeclarationAlignment::None, transitionActors.size() * 16, "TransitionActorEntry", + StringHelper::Sprintf("%sTransitionActorList0x%06X", roomName.c_str(), segmentOffset), true, declaration); + + return sourceOutput; +} + + +string SetTransitionActorList::GenerateSourceCodePass2(string roomName, int baseAddress) +{ + return ""; +} + +int32_t SetTransitionActorList::GetRawDataSize() +{ + return ZRoomCommand::GetRawDataSize() + (transitionActors.size() * 16); +} + +string SetTransitionActorList::GenerateExterns() +{ + return StringHelper::Sprintf("extern TransitionActorEntry %sTransitionActorList0x%06X[];\n", zRoom->GetName().c_str(), segmentOffset); +} + +string SetTransitionActorList::GetCommandCName() +{ + return "SCmdTransiActorList"; +} + +RoomCommand SetTransitionActorList::GetRoomCommand() +{ + return RoomCommand::SetTransitionActorList; +} + +TransitionActorEntry::TransitionActorEntry(std::vector rawData, int rawDataIndex) +{ + frontObjectRoom = rawData[rawDataIndex + 0]; + frontTransitionReaction = rawData[rawDataIndex + 1]; + backObjectRoom = rawData[rawDataIndex + 2]; + backTransitionReaction = rawData[rawDataIndex + 3]; + actorNum = BitConverter::ToInt16BE(rawData, rawDataIndex + 4); + posX = BitConverter::ToInt16BE(rawData, rawDataIndex + 6); + posY = BitConverter::ToInt16BE(rawData, rawDataIndex + 8); + posZ = BitConverter::ToInt16BE(rawData, rawDataIndex + 10); + rotY = BitConverter::ToInt16BE(rawData, rawDataIndex + 12); + initVar = BitConverter::ToInt16BE(rawData, rawDataIndex + 14); +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetTransitionActorList.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetTransitionActorList.h new file mode 100644 index 0000000000..360b7209fc --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetTransitionActorList.h @@ -0,0 +1,36 @@ +#pragma once + +#include "../ZRoomCommand.h" + +class TransitionActorEntry +{ +public: + uint8_t frontObjectRoom; + uint8_t frontTransitionReaction; + uint8_t backObjectRoom; + uint8_t backTransitionReaction; + uint16_t actorNum; + int16_t posX, posY, posZ; + int16_t rotY; + uint16_t initVar; + + TransitionActorEntry(std::vector rawData, int rawDataIndex); +}; + +class SetTransitionActorList : public ZRoomCommand +{ +public: + SetTransitionActorList(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + std::string GetSourceOutputCode(std::string prefix); + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual std::string GenerateSourceCodePass2(std::string roomName, int baseAddress); + virtual RoomCommand GetRoomCommand(); + virtual int32_t GetRawDataSize(); + virtual std::string GetCommandCName(); + virtual std::string GenerateExterns(); + +private: + std::vector transitionActors; + uint32_t segmentOffset; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetWind.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetWind.cpp new file mode 100644 index 0000000000..88f12667da --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetWind.cpp @@ -0,0 +1,27 @@ +#include "SetWind.h" +#include "../../StringHelper.h" + +using namespace std; + +SetWind::SetWind(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ + windWest = rawData[rawDataIndex + 0x04]; + windVertical = rawData[rawDataIndex + 0x05]; + windSouth = rawData[rawDataIndex + 0x06]; + clothFlappingStrength = rawData[rawDataIndex + 0x07]; +} + +string SetWind::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + return StringHelper::Sprintf("%s 0x00, 0x00, 0x00, 0x%02X, 0x%02X, 0x%02X, 0x%02X", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str(), windWest, windVertical, windSouth, clothFlappingStrength); +} + +string SetWind::GetCommandCName() +{ + return "SCmdWindSettings"; +} + +RoomCommand SetWind::GetRoomCommand() +{ + return RoomCommand::SetWind; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetWind.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetWind.h new file mode 100644 index 0000000000..b7ab2169ea --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetWind.h @@ -0,0 +1,19 @@ +#pragma once + +#include "../ZRoomCommand.h" + +class SetWind : public ZRoomCommand +{ +public: + SetWind(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual std::string GetCommandCName(); + virtual RoomCommand GetRoomCommand(); + +private: + uint8_t windWest; + uint8_t windVertical; + uint8_t windSouth; + uint8_t clothFlappingStrength; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/Unused09.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/Unused09.cpp new file mode 100644 index 0000000000..d8b5a45fa9 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/Unused09.cpp @@ -0,0 +1,23 @@ +#include "Unused09.h" +#include "../../StringHelper.h" + +using namespace std; + +Unused09::Unused09(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ +} + +string Unused09::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + return StringHelper::Sprintf("%s 0x00, 0x00", ZRoomCommand::GenerateSourceCodePass1(roomName, baseAddress).c_str()); +} + +string Unused09::GetCommandCName() +{ + return "SCmdBase"; +} + +RoomCommand Unused09::GetRoomCommand() +{ + return RoomCommand::Unused09; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/Unused09.h b/tools/ZAPD/ZAPD/ZRoom/Commands/Unused09.h new file mode 100644 index 0000000000..4a4ee4840b --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/Unused09.h @@ -0,0 +1,15 @@ +#pragma once + +#include "../ZRoomCommand.h" + +class Unused09 : public ZRoomCommand +{ +public: + Unused09(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual std::string GetCommandCName(); + virtual RoomCommand GetRoomCommand(); + +private: +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/ZRoomCommandUnk.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/ZRoomCommandUnk.cpp new file mode 100644 index 0000000000..c536169654 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/ZRoomCommandUnk.cpp @@ -0,0 +1,50 @@ +#include "ZRoomCommandUnk.h" +#include "BitConverter.h" +#include "../../StringHelper.h" + +using namespace std; + +ZRoomCommandUnk::ZRoomCommandUnk(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) +{ + cmdID = (RoomCommand)rawData[rawDataIndex]; + cmdAddress = rawDataIndex; + zRoom = nZRoom; + + data1 = rawData[rawDataIndex + 1]; + data2 = BitConverter::ToInt32BE(rawData, rawDataIndex + 4); +} + +string ZRoomCommandUnk::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + return StringHelper::Sprintf("%s %sSet%04XCmd%02X = { 0x%02X, 0x%02X, 0x%06X }; /* WARNING: UNIMPLEMENTED ROOM COMMAND */", GetCommandCName().c_str(), roomName.c_str(), baseAddress, data2, cmdID, data1, data2); +} + +string ZRoomCommandUnk::GenerateSourceCodePass2(string roomName, int baseAddress) +{ + return ""; +} + +string ZRoomCommandUnk::GenerateSourceCodePass3(string roomName) +{ + return ""; +} + +string ZRoomCommandUnk::GenerateExterns() +{ + return ""; +} + +int32_t ZRoomCommandUnk::GetRawDataSize() +{ + return 8; +} + +string ZRoomCommandUnk::GetCommandCName() +{ + return "SCmdBase"; +} + +RoomCommand ZRoomCommandUnk::GetRoomCommand() +{ + return RoomCommand::Error; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/ZRoomCommandUnk.h b/tools/ZAPD/ZAPD/ZRoom/Commands/ZRoomCommandUnk.h new file mode 100644 index 0000000000..53e0929340 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/ZRoomCommandUnk.h @@ -0,0 +1,27 @@ +#pragma once +#include "../ZRoomCommand.h" + +class ZRoomCommandUnk : public ZRoomCommand +{ +public: + RoomCommand cmdID; + int32_t cmdAddress; + int32_t cmdIndex; + int32_t cmdSet; + uint32_t commandSet; + uint8_t data1; + uint32_t data2; + + ZRoomCommandUnk(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual std::string GenerateSourceCodePass2(std::string roomName, int baseAddress); + virtual std::string GenerateSourceCodePass3(std::string roomName); + virtual RoomCommand GetRoomCommand(); + virtual int32_t GetRawDataSize(); + virtual std::string GetCommandCName(); + virtual std::string GenerateExterns(); + +protected: + ZRoom* zRoom; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/ObjectList.h b/tools/ZAPD/ZAPD/ZRoom/ObjectList.h new file mode 100644 index 0000000000..4265f1dd51 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/ObjectList.h @@ -0,0 +1,409 @@ +#pragma once + +#include + +static const std::string ObjectList[] = +{ + "OBJ_0000", + "GAMEPLAY_KEEP", + "GAMEPLAY_FIELD_KEEP", + "GAMEPLAY_DANGEON_KEEP", + "OBJ_0004", + "OBJ_0005", + "OBJECT_HUMAN", + "OBJECT_OKUTA", + "OBJECT_CROW", + "OBJECT_POH", + "OBJECT_DY_OBJ", + "OBJECT_WALLMASTER", + "OBJECT_DODONGO", + "OBJECT_FIREFLY", + "OBJECT_BOX", + "OBJECT_FIRE", + "OBJ_0010", + "OBJ_0011", + "OBJECT_BUBBLE", + "OBJECT_NIW", + "OBJECT_LINK_BOY", + "OBJECT_LINK_CHILD", + "OBJECT_TITE", + "OBJECT_REEBA", + "OBJECT_PEEHAT", + "OBJECT_KINGDODONGO", + "OBJECT_HORSE", + "OBJECT_ZF", + "OBJECT_GOMA", + "OBJECT_ZL1", + "OBJECT_GOL", + "OBJECT_DODOJR", + "OBJECT_TORCH2", + "OBJECT_BL", + "OBJECT_TP", + "OBJECT_OA1", + "OBJECT_ST", + "OBJECT_BW", + "OBJECT_EI", + "OBJECT_HORSE_NORMAL", + "OBJECT_OB1", + "OBJECT_O_ANIME", + "OBJECT_SPOT04_OBJECTS", + "OBJECT_DDAN_OBJECTS", + "OBJECT_HIDAN_OBJECTS", + "OBJECT_HORSE_GANON", + "OBJECT_OA2", + "OBJECT_SPOT00_OBJECTS", + "OBJECT_MB", + "OBJECT_BOMBF", + "OBJECT_SK2", + "OBJECT_OE1", + "OBJECT_OE_ANIME", + "OBJECT_OE2", + "OBJECT_YDAN_OBJECTS", + "OBJECT_GND", + "OBJECT_AM", + "OBJECT_DEKUBABA", + "OBJECT_003A", + "OBJECT_OA3", + "OBJECT_OA4", + "OBJECT_OA5", + "OBJECT_OA6", + "OBJECT_OA7", + "OBJECT_JJ", + "OBJECT_OA8", + "OBJECT_OA9", + "OBJECT_OB2", + "OBJECT_OB3", + "OBJECT_OB4", + "OBJECT_HORSE_ZELDA", + "OBJECT_OPENING_DEMO1", + "OBJECT_WARP1", + "OBJECT_B_HEART", + "OBJECT_DEKUNUTS", + "OBJECT_OE3", + "OBJECT_OE4", + "OBJECT_MENKURI_OBJECTS", + "OBJECT_OE5", + "OBJECT_OE6", + "OBJECT_OE7", + "OBJECT_OE8", + "OBJECT_OE9", + "OBJECT_OE10", + "OBJECT_OE11", + "OBJECT_OE12", + "OBJECT_VALI", + "OBJECT_OA10", + "OBJECT_OA11", + "OBJECT_MIZU_OBJECTS", + "OBJECT_FHG", + "OBJECT_OSSAN", + "OBJECT_MORI_HINERI1", + "OBJECT_BB", + "OBJECT_TOKI_OBJECTS", + "OBJECT_YUKABYUN", + "OBJECT_ZL2", + "OBJECT_MJIN", + "OBJECT_MJIN_FLASH", + "OBJECT_MJIN_DARK", + "OBJECT_MJIN_FLAME", + "OBJECT_MJIN_ICE", + "OBJECT_MJIN_SOUL", + "OBJECT_MJIN_WIND", + "OBJECT_MJIN_OKA", + "OBJECT_HAKA_OBJECTS", + "OBJECT_SPOT06_OBJECTS", + "OBJECT_ICE_OBJECTS", + "OBJECT_RELAY_OBJECTS", + "OBJECT_PO_FIELD", + "OBJECT_PO_COMPOSER", + "OBJECT_MORI_HINERI1A", + "OBJECT_MORI_HINERI2", + "OBJECT_MORI_HINERI2A", + "OBJECT_MORI_OBJECTS", + "OBJECT_MORI_TEX", + "OBJECT_SPOT08_OBJ", + "OBJECT_WARP2", + "OBJECT_HATA", + "OBJECT_BIRD", + "OBJ_0078", + "OBJ_0079", + "OBJ_007A", + "OBJ_007B", + "OBJECT_WOOD02", + "OBJ_007D", + "OBJ_007E", + "OBJ_007F", + "OBJ_0080", + "OBJECT_LIGHTBOX", + "OBJECT_PU_BOX", + "OBJ_0083", + "OBJ_0084", + "OBJECT_TRAP", + "OBJECT_VASE", + "OBJECT_IM", + "OBJECT_TA", + "OBJECT_TK", + "OBJECT_XC", + "OBJECT_VM", + "OBJECT_BV", + "OBJECT_HAKACH_OBJECTS", + "OBJECT_EFC_CRYSTAL_LIGHT", + "OBJECT_EFC_FIRE_BALL", + "OBJECT_EFC_FLASH", + "OBJECT_EFC_LGT_SHOWER", + "OBJECT_EFC_STAR_FIELD", + "OBJECT_GOD_LGT", + "OBJECT_LIGHT_RING", + "OBJECT_TRIFORCE_SPOT", + "OBJECT_BDAN_OBJECTS", + "OBJECT_SD", + "OBJECT_RD", + "OBJECT_PO_SISTERS", + "OBJECT_HEAVY_OBJECT", + "OBJECT_GNDD", + "OBJECT_FD", + "OBJECT_DU", + "OBJECT_FW", + "OBJECT_MEDAL", + "OBJECT_HORSE_LINK_CHILD", + "OBJECT_SPOT02_OBJECTS", + "OBJECT_HAKA", + "OBJECT_RU1", + "OBJECT_SYOKUDAI", + "OBJECT_FD2", + "OBJECT_DH", + "OBJECT_RL", + "OBJECT_EFC_TW", + "OBJECT_DEMO_TRE_LGT", + "OBJECT_GI_KEY", + "OBJECT_MIR_RAY", + "OBJECT_BROB", + "OBJECT_GI_JEWEL", + "OBJECT_SPOT09_OBJ", + "OBJECT_SPOT18_OBJ", + "OBJECT_BDOOR", + "OBJECT_SPOT17_OBJ", + "OBJECT_SHOP_DUNGEN", + "OBJECT_NB", + "OBJECT_MO", + "OBJECT_SB", + "OBJECT_GI_MELODY", + "OBJECT_GI_HEART", + "OBJECT_GI_COMPASS", + "OBJECT_GI_BOSSKEY", + "OBJECT_GI_MEDAL", + "OBJECT_GI_NUTS", + "OBJECT_SA", + "OBJECT_GI_HEARTS", + "OBJECT_GI_ARROWCASE", + "OBJECT_GI_BOMBPOUCH", + "OBJECT_IN", + "OBJECT_TR", + "OBJECT_SPOT16_OBJ", + "OBJECT_OE1S", + "OBJECT_OE4S", + "OBJECT_OS_ANIME", + "OBJECT_GI_BOTTLE", + "OBJECT_GI_STICK", + "OBJECT_GI_MAP", + "OBJECT_OF1D_MAP", + "OBJECT_RU2", + "OBJECT_GI_SHIELD_1", + "OBJECT_DEKUJR", + "OBJECT_GI_MAGICPOT", + "OBJECT_GI_BOMB_1", + "OBJECT_OF1S", + "OBJECT_MA2", + "OBJECT_GI_PURSE", + "OBJECT_HNI", + "OBJECT_TW", + "OBJECT_RR", + "OBJECT_BXA", + "OBJECT_ANUBICE", + "OBJECT_GI_GERUDO", + "OBJECT_GI_ARROW", + "OBJECT_GI_BOMB_2", + "OBJECT_GI_EGG", + "OBJECT_GI_SCALE", + "OBJECT_GI_SHIELD_2", + "OBJEFCT_GI_HOOKSHOT", + "OBJECT_GI_OCARINA", + "OBJECT_GI_MILK", + "OBJECT_MA1", + "OBJECT_GANON", + "OBJECT_SST", + "OBJECT_NY", + "OBJ_00E4", + "OBJECT_NY", + "OBJECT_FR", + "OBJECT_GI_PACHINKO", + "OBJECT_GI_BOOMERANG", + "OBJECT_GI_BOW", + "OBJECT_GI_GLASSES", + "OBJECT_GI_LIQUID", + "OBJECT_ANI", + "OBJECT_DEMO_6K", + "OBJECT_GI_SHIELD_3", + "OBJECT_GI_LETTER", + "OBJECT_SPOT15_OBJ", + "OBJECT_JYA_OBJ", + "OBJECT_GI_CLOTHES", + "OBJECT_GI_BEAN", + "OBJECT_GI_FISH", + "OBJECT_GI_SAW", + "OBJECT_GI_HAMMER", + "OBJECT_GI_GRASS", + "OBJECT_GI_LONGSWORD", + "OBJECT_SPOT01_OBJECTS", + "OBJECT_MD", + "OBJECT_MD", + "OBJECT_KM1", + "OBJECT_KW1", + "OBJECT_ZO", + "OBJECT_KZ", + "OBJECT_UMAJUMP", + "OBJECT_MASTERKOKIRI", + "OBJECT_MASTERKOKIRIHEAD", + "OBJECT_MASTERGOLON", + "OBJECT_MASTERZOORA", + "OBJECT_AOB", + "OBJECT_IK", + "OBJECT_AHG", + "OBJECT_CNE", + "OBJECT_GI_NIWATORI", + "OBJECT_SKJ", + "OBJECT_GI_BOTTLE_LETTER", + "OBJECT_BJI", + "OBJECT_BBA", + "OBJECT_GI_OCARINA_0", + "OBJECT_DS", + "OBJECT_ANE", + "OBJECT_BOJ", + "OBJECT_SPOT03_OBJECT", + "OBJECT_SPOT07_OBJECT", + "OBJECT_FZ", + "OBJECT_BOB", + "OBJECT_GE1", + "OBJECT_YABUSAME_POINT", + "OBJECT_GI_BOOTS_2", + "OBJECT_GI_SEED", + "OBJECT_GND_MAGIC", + "OBJECT_D_ELEVATOR", + "OBJECT_D_HSBLOCK", + "OBJECT_D_LIFT", + "OBJECT_MAMENOKI", + "OBJECT_GOROIWA", + "OBJ_0120", + "OBJECT_TORYO", + "OBJECT_DAIKU", + "OBJ_0123", + "OBJECT_NWC", + "OBJECT_BLKOBJ", + "OBJECT_GM", + "OBJECT_MS", + "OBJECT_HS", + "OBJECT_INGATE", + "OBJECT_LIGHTSWITCH", + "OBJECT_KUSA", + "OBJECT_TSUBO", + "OBJECT_GI_GLOVES", + "OBJECT_GI_COIN", + "OBJECT_KANBAN", + "OBJECT_GJYO_OBJECTS", + "OBJECT_OWL", + "OBJECT_MK", + "OBJECT_FU", + "OBJECT_GI_KI_TAN_MASK", + "OBJECT_GI_REDEAD_MASK", + "OBJECT_GI_SKJ_MASK", + "OBJECT_GI_RABIT_MASK", + "OBJECT_GI_TRUTH_MASK", + "OBJECT_GANON_OBJECTS", + "OBJECT_SIOFUKI", + "OBJECT_STREAM", + "OBJECT_MM", + "OBJECT_FA", + "OBJECT_OS", + "OBJECT_GI_EYE_LOTION", + "OBJECT_GI_POWDER", + "OBJECT_GI_MUSHROOM", + "OBJECT_GI_TICKETSTONE", + "OBJECT_GI_BROKENSWORD", + "OBJECT_JS", + "OBJECT_CS", + "OBJECT_GI_PRESCRIPTION", + "OBJECT_GI_BRACELET", + "OBJECT_GI_SOLDOUT", + "OBJECT_GI_FROG", + "OBJECT_MAG", + "OBJECT_DOOR_GERUDO", + "OBJECT_GT", + "OBJECT_EFC_ERUPC", + "OBJECT_ZL2_ANIME1", + "OBJECT_ZL2_ANIME2", + "OBJECT_GI_GOLONMASK", + "OBJECT_GI_ZORAMASK", + "OBJECT_GI_GERUDOMASK", + "OBJECT_GANON2", + "OBJECT_KA", + "OBJECT_TS", + "OBJECT_ZG", + "OBJECT_GI_HOVERBOOTS", + "OBJECT_GI_M_ARROW", + "OBJECT_DS2", + "OBJECT_EC", + "OBJECT_FISH", + "OBJECT_GI_SUTARU", + "OBJECT_GI_GODDESS", + "OBJECT_SSH", + "OBJECT_BIGOKUTA", + "OBJECT_BG", + "OBJECT_SPOT05_OBJECTS", + "OBJECT_SPOT12_OBJ", + "OBJECT_BOMBIWA", + "OBJECT_HINTNUTS", + "OBJECT_RS", + "OBJECT_SPOT00_BREAK", + "OBJECT_GLA", + "OBJECT_SHOPNUTS", + "OBJECT_GELDB", + "OBJECT_GR", + "OBJECT_DOG", + "OBJECT_JYA_IRON", + "OBJECT_JYA_DOOR", + "OBJ_016E", + "OBJECT_SPOT11_OBJ", + "OBJECT_KIBAKO2", + "OBJECT_DNS", + "OBJECT_DNK", + "OBJECT_GI_FIRE", + "OBJECT_GI_INSECT", + "OBJECT_GI_BUTTERFLY", + "OBJECT_GI_GHOST", + "OBJECT_GI_SOUL", + "OBJECT_BOWL", + "OBJECT_DEMO_KEKKAI", + "OBJECT_EFC_DOUGHNUT", + "OBJECT_GI_DEKUPOUCH", + "OBJECT_GANON_ANIME1", + "OBJECT_GANON_ANIME2", + "OBJECT_GANON_ANIME3", + "OBJECT_GI_RUPY", + "OBJECT_SPOT01_MATOYA", + "OBJECT_SPOT01_MATOYAB", + "OBJECT_MU", + "OBJECT_WF", + "OBJECT_SKB", + "OBJECT_GJ", + "OBJECT_GEFF", + "OBJECT_HAKA_DOOR", + "OBJECT_GS", + "OBJECT_PS", + "OBJECT_BWALL", + "OBJECT_COW", + "OBJECT_COB", + "OBJECT_GI_SWORD_1", + "OBJECT_DOOR_KILLER", + "OBJECT_OUKE_HAKA", + "OBJECT_TIMEBLOCK", + "OBJECT_ZL4", +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/ZRoom.cpp b/tools/ZAPD/ZAPD/ZRoom/ZRoom.cpp new file mode 100644 index 0000000000..9396f0760b --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/ZRoom.cpp @@ -0,0 +1,581 @@ +#include +#include +#include "ZRoom.h" +#include "ZFile.h" +#include "ZCutscene.h" +#include "../ZBlob.h" +#include "ObjectList.h" +#include "../File.h" +#include "../StringHelper.h" +#include "../Globals.h" +#include "Commands/SetRoomList.h" +#include "Commands/SetEchoSettings.h" +#include "Commands/SetSoundSettings.h" +#include "Commands/SetWind.h" +#include "Commands/SetTimeSettings.h" +#include "Commands/SetSpecialObjects.h" +#include "Commands/SetSkyboxSettings.h" +#include "Commands/SetSkyboxModifier.h" +#include "Commands/SetRoomBehavior.h" +#include "Commands/SetCameraSettings.h" +#include "Commands/SetStartPositionList.h" +#include "Commands/SetActorList.h" +#include "Commands/SetTransitionActorList.h" +#include "Commands/SetEntranceList.h" +#include "Commands/SetExitList.h" +#include "Commands/SetAlternateHeaders.h" +#include "Commands/SetCollisionHeader.h" +#include "Commands/SetObjectList.h" +#include "Commands/SetMesh.h" +#include "Commands/SetLightingSettings.h" +#include "Commands/SetPathways.h" +#include "Commands/Unused09.h" +#include "Commands/SetCutscenes.h" +#include "Commands/EndMarker.h" +#include "Commands/SetLightList.h" +#include "Commands/ZRoomCommandUnk.h" +#include + +using namespace std; +using namespace tinyxml2; + +ZRoom::ZRoom() : ZResource() +{ + textures = map(); + commands = vector(); + commandSets = vector(); + extDefines = ""; + scene = nullptr; +} + +ZRoom* ZRoom::ExtractFromXML(XMLElement* reader, vector nRawData, int rawDataIndex, string nRelPath, ZFile* nParent, ZRoom* nScene) +{ + ZRoom* room = new ZRoom(); + + room->parent = nParent; + room->rawData = nRawData; + room->name = reader->Attribute("Name"); + + //printf("ZRoom: %s\n", name.c_str()); + + room->scene = nScene; + + Globals::Instance->AddSegment(SEGMENT_ROOM); + Globals::Instance->AddSegment(SEGMENT_SCENE); + + //GenDefinitions(); + + int cmdCount = 999999; + + if (room->name == "syotes_room_0") + { + room->SyotesRoomHack(); + cmdCount = 0; + } + + for (XMLElement* child = reader->FirstChildElement(); child != NULL; child = child->NextSiblingElement()) + { + if (string(child->Name()) == "DListHint") + { + string comment = ""; + + if (child->Attribute("Comment") != NULL) + comment = "// " + string(child->Attribute("Comment")) + "\n"; + + string addressStr = child->Attribute("Offset"); + int address = strtol(StringHelper::Split(addressStr, "0x")[1].c_str(), NULL, 16); + + ZDisplayList* dList = new ZDisplayList(room->rawData, address, ZDisplayList::GetDListLength(room->rawData, address)); + //room->parent->declarations[address] = new Declaration(DeclarationAlignment::None, dList->GetRawDataSize(), comment + dList->GetSourceOutputCode(room->name)); + //room->parent->AddDeclarationArray(address, DeclarationAlignment::None, dList->GetRawDataSize(), "Gfx", "", 0, comment + dList->GetSourceOutputCode(room->name)); + + dList->GetSourceOutputCode(room->name); + } + else if (string(child->Name()) == "BlobHint") + { + string comment = ""; + + if (child->Attribute("Comment") != NULL) + comment = "// " + string(child->Attribute("Comment")) + "\n"; + + string addressStr = child->Attribute("Offset"); + int address = strtol(StringHelper::Split(addressStr, "0x")[1].c_str(), NULL, 16); + + string sizeStr = child->Attribute("Size"); + int size = strtol(StringHelper::Split(sizeStr, "0x")[1].c_str(), NULL, 16); + + ZBlob* blob = new ZBlob(room->rawData, address, size, StringHelper::Sprintf("%sBlob0x%06X", room->name.c_str(), address)); + room->parent->AddDeclarationArray(address, DeclarationAlignment::None, blob->GetRawDataSize(), "u8", StringHelper::Sprintf("%s_%s", room->name.c_str(), blob->GetName().c_str()), 0, blob->GetSourceOutputCode(room->name)); + } + else if (string(child->Name()) == "CutsceneHint") + { + string comment = ""; + + if (child->Attribute("Comment") != NULL) + comment = "// " + string(child->Attribute("Comment")) + "\n"; + + string addressStr = child->Attribute("Offset"); + int address = strtol(StringHelper::Split(addressStr, "0x")[1].c_str(), NULL, 16); + + ZCutscene* cutscene = new ZCutscene(room->rawData, address, 9999); + + room->parent->AddDeclarationArray(address, DeclarationAlignment::None, DeclarationPadding::Pad16, cutscene->GetRawDataSize(), "s32", + StringHelper::Sprintf("%sCutsceneData0x%06X", room->name.c_str(), cutscene->segmentOffset), 0, cutscene->GetSourceOutputCode(room->name)); + } + else if (string(child->Name()) == "AltHeaderHint") + { + string comment = ""; + + if (child->Attribute("Comment") != NULL) + comment = "// " + string(child->Attribute("Comment")) + "\n"; + + string addressStr = child->Attribute("Offset"); + int address = strtol(StringHelper::Split(addressStr, "0x")[1].c_str(), NULL, 16); + + int commandsCount = 99999999; + + if (child->FindAttribute("Count") != NULL) + { + string commandCountStr = child->Attribute("Count"); + commandsCount = strtol(commandCountStr.c_str(), NULL, 10); + } + + room->commandSets.push_back(CommandSet(address, commandsCount)); + } + else if (string(child->Name()) == "PathHint") + { + string comment = ""; + + if (child->Attribute("Comment") != NULL) + comment = "// " + string(child->Attribute("Comment")) + "\n"; + + string addressStr = child->Attribute("Offset"); + int address = strtol(StringHelper::Split(addressStr, "0x")[1].c_str(), NULL, 16); + + SetPathways* pathway = new SetPathways(room, room->rawData, address); + pathway->InitList(address); + pathway->GenerateSourceCodePass1(room->name, 0); + pathway->GenerateSourceCodePass2(room->name, 0); + + delete pathway; + } + else if (string(child->Name()) == "TextureHint") + { + string comment = ""; + + if (child->Attribute("Comment") != NULL) + comment = "// " + string(child->Attribute("Comment")) + "\n"; + + string addressStr = child->Attribute("Offset"); + int address = strtol(StringHelper::Split(addressStr, "0x")[1].c_str(), NULL, 16); + + string typeStr = child->Attribute("Type"); + int width = strtol(string(child->Attribute("Width")).c_str(), NULL, 10); + int height = strtol(string(child->Attribute("Height")).c_str(), NULL, 10); + + ZTexture* tex = ZTexture::FromBinary(ZTexture::GetTextureTypeFromString(typeStr), room->rawData, address, StringHelper::Sprintf("%sTex_%06X", room->name.c_str(), address), width, height); + room->parent->AddDeclarationArray(address, DeclarationAlignment::None, tex->GetRawDataSize(), "u64", StringHelper::Sprintf("%s", tex->GetName().c_str()), 0, + tex->GetSourceOutputCode(room->name)); + } + } + + //ParseCommands(rawDataIndex); + room->commandSets.push_back(CommandSet(rawDataIndex, cmdCount)); + room->ProcessCommandSets(); + + return room; +} + +void ZRoom::ParseCommands(std::vector& commandList, CommandSet commandSet) +{ + bool shouldContinue = true; + int currentIndex = 0; + int rawDataIndex = commandSet.address; + int8_t segmentNumber = rawDataIndex >> 24; + + rawDataIndex &= 0x00FFFFFF; + int32_t commandsLeft = commandSet.commandCount; + + while (shouldContinue) + { + if (commandsLeft <= 0) + break; + + RoomCommand opcode = (RoomCommand)rawData[rawDataIndex]; + + ZRoomCommand* cmd = nullptr; + + auto start = chrono::steady_clock::now(); + + switch (opcode) + { + case RoomCommand::SetStartPositionList: cmd = new SetStartPositionList(this, rawData, rawDataIndex); break; // 0x00 + case RoomCommand::SetActorList: cmd = new SetActorList(this, rawData, rawDataIndex); break; // 0x01 + case RoomCommand::SetCollisionHeader: cmd = new SetCollisionHeader(this, rawData, rawDataIndex); break; // 0x03 + case RoomCommand::SetRoomList: cmd = new SetRoomList(this, rawData, rawDataIndex); break; // 0x04 + case RoomCommand::SetWind: cmd = new SetWind(this, rawData, rawDataIndex); break; // 0x05 + case RoomCommand::SetEntranceList: cmd = new SetEntranceList(this, rawData, rawDataIndex); break; // 0x06 + case RoomCommand::SetSpecialObjects: cmd = new SetSpecialObjects(this, rawData, rawDataIndex); break; // 0x07 + case RoomCommand::SetRoomBehavior: cmd = new SetRoomBehavior(this, rawData, rawDataIndex); break; // 0x08 + case RoomCommand::Unused09: cmd = new Unused09(this, rawData, rawDataIndex); break; // 0x09 + case RoomCommand::SetMesh: cmd = new SetMesh(this, rawData, rawDataIndex, 0); break; // 0x0A + case RoomCommand::SetObjectList: cmd = new SetObjectList(this, rawData, rawDataIndex); break; // 0x0B + case RoomCommand::SetLightList: cmd = new SetLightList(this, rawData, rawDataIndex); break; // 0x0C (MM-ONLY) + case RoomCommand::SetPathways: cmd = new SetPathways(this, rawData, rawDataIndex); break; // 0x0D + case RoomCommand::SetTransitionActorList: cmd = new SetTransitionActorList(this, rawData, rawDataIndex); break; // 0x0E + case RoomCommand::SetLightingSettings: cmd = new SetLightingSettings(this, rawData, rawDataIndex); break; // 0x0F + case RoomCommand::SetTimeSettings: cmd = new SetTimeSettings(this, rawData, rawDataIndex); break; // 0x10 + case RoomCommand::SetSkyboxSettings: cmd = new SetSkyboxSettings(this, rawData, rawDataIndex); break; // 0x11 + case RoomCommand::SetSkyboxModifier: cmd = new SetSkyboxModifier(this, rawData, rawDataIndex); break; // 0x12 + case RoomCommand::SetExitList: cmd = new SetExitList(this, rawData, rawDataIndex); break; // 0x13 + case RoomCommand::EndMarker: cmd = new EndMarker(this, rawData, rawDataIndex); break; // 0x14 + case RoomCommand::SetSoundSettings: cmd = new SetSoundSettings(this, rawData, rawDataIndex); break; // 0x15 + case RoomCommand::SetEchoSettings: cmd = new SetEchoSettings(this, rawData, rawDataIndex); break; // 0x16 + case RoomCommand::SetCutscenes: cmd = new SetCutscenes(this, rawData, rawDataIndex); break; // 0x17 + case RoomCommand::SetAlternateHeaders: cmd = new SetAlternateHeaders(this, rawData, rawDataIndex); break; // 0x18 + case RoomCommand::SetCameraSettings: cmd = new SetCameraSettings(this, rawData, rawDataIndex); break; // 0x19 + default: cmd = new ZRoomCommandUnk(this, rawData, rawDataIndex); + } + + auto end = chrono::steady_clock::now(); + auto diff = chrono::duration_cast(end - start).count(); + + if (Globals::Instance->profile) + { + if (diff > 50) + printf("OP: %s, TIME: %lims\n", cmd->GetCommandCName().c_str(), diff); + } + + //printf("OP: %s\n", cmd->GetCommandCName().c_str()); + + cmd->cmdIndex = currentIndex; + cmd->cmdSet = rawDataIndex; + + commandList.push_back(cmd); + + if (opcode == RoomCommand::EndMarker) + shouldContinue = false; + + rawDataIndex += 8; + currentIndex++; + + commandsLeft--; + } +} + +void ZRoom::ProcessCommandSets() +{ + while (commandSets.size() > 0) + { + std::vector setCommands = std::vector(); + + int32_t commandSet = commandSets[0].address; + int8_t segmentNumber = commandSet >> 24; + ParseCommands(setCommands, commandSets[0]); + commandSets.erase(commandSets.begin()); + + for (int i = 0; i < setCommands.size(); i++) + { + ZRoomCommand* cmd = setCommands[i]; + cmd->commandSet = commandSet & 0x00FFFFFF; + string pass1 = cmd->GenerateSourceCodePass1(name, cmd->commandSet); + + Declaration* decl = parent->AddDeclaration(cmd->cmdAddress, i == 0 ? DeclarationAlignment::Align16 : DeclarationAlignment::None, 8, cmd->GetCommandCName(), + StringHelper::Sprintf("%sSet%04XCmd%02X", name.c_str(), commandSet & 0x00FFFFFF, cmd->cmdIndex, cmd->cmdID), + StringHelper::Sprintf("%s", pass1.c_str())); + + decl->rightText = StringHelper::Sprintf("// 0x%04X", cmd->cmdAddress); + } + + sourceOutput += "\n"; + + for (ZRoomCommand* cmd : setCommands) + commands.push_back(cmd); + } + + for (ZRoomCommand* cmd : commands) + { + string pass2 = cmd->GenerateSourceCodePass2(name, cmd->commandSet); + + if (pass2 != "") + parent->AddDeclaration(cmd->cmdAddress, DeclarationAlignment::None, 8, cmd->GetCommandCName(), StringHelper::Sprintf("%sSet%04XCmd%02X", name.c_str(), cmd->commandSet & 0x00FFFFFF, cmd->cmdIndex, cmd->cmdID), StringHelper::Sprintf("%s // 0x%04X", pass2.c_str(), cmd->cmdAddress)); + } +} + +/* + * There is one room in Ocarina of Time that lacks a header. Room 120, "Syotes", dates back to very early in the game's development. + * Since this room is a special case, this hack adds back a header so that the room can be processed properly. + */ +void ZRoom::SyotesRoomHack() +{ + char headerData[] = + { + 0x0A, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08 + }; + + for (int i = 0; i < sizeof(headerData); i++) + rawData.insert(rawData.begin() + i, headerData[i]); + + SetMesh* cmdSetMesh = new SetMesh(this, rawData, 0, -8); + + for (int i = 0; i < sizeof(headerData); i++) + rawData.erase(rawData.begin()); + + cmdSetMesh->cmdIndex = 0; + cmdSetMesh->cmdSet = 0; + + commands.push_back(cmdSetMesh); +} + +ZRoomCommand* ZRoom::FindCommandOfType(RoomCommand cmdType) +{ + for (int i = 0; i < commands.size(); i++) + { + if (commands[i]->cmdID == cmdType) + return commands[i]; + } + + return nullptr; +} + +size_t ZRoom::GetDeclarationSizeFromNeighbor(int declarationAddress) +{ + int declarationIndex = -1; + + // Copy it into a vector. + vector> declarationKeysSorted(parent->declarations.begin(), parent->declarations.end()); + + // Sort the vector according to the word count in descending order. + sort(declarationKeysSorted.begin(), declarationKeysSorted.end(), [](const auto& lhs, const auto& rhs) { return lhs.first < rhs.first; }); + + for (int i = 0; i < declarationKeysSorted.size(); i++) + { + if (declarationKeysSorted[i].first == declarationAddress) + { + declarationIndex = i; + break; + } + } + + if (declarationIndex != -1) + { + if (declarationIndex + 1 < declarationKeysSorted.size()) + return declarationKeysSorted[declarationIndex + 1].first - declarationKeysSorted[declarationIndex].first; + else + return rawData.size() - declarationKeysSorted[declarationIndex].first; + } + + return 0; +} + +size_t ZRoom::GetCommandSizeFromNeighbor(ZRoomCommand* cmd) +{ + int cmdIndex = -1; + + for (int i = 0; i < commands.size(); i++) + { + if (commands[i] == cmd) + { + cmdIndex = i; + break; + } + } + + if (cmdIndex != -1) + { + if (cmdIndex + 1 < commands.size()) + return commands[cmdIndex + 1]->cmdAddress - commands[cmdIndex]->cmdAddress; + else + return rawData.size() - commands[cmdIndex]->cmdAddress; + } + + return 0; +} + +string ZRoom::GetSourceOutputHeader(string prefix) +{ + sourceOutput = ""; + + for (ZRoomCommand* cmd : commands) + sourceOutput += cmd->GenerateExterns(); + + sourceOutput += "\n"; + + sourceOutput += "\n" + extDefines + "\n"; + sourceOutput += "\n"; + + return sourceOutput; +} + +string ZRoom::GetSourceOutputCode(std::string prefix) +{ + sourceOutput = ""; + + //sourceOutput += "#include \n"; + sourceOutput += "#include \"segment_symbols.h\"\n"; + sourceOutput += "#include \"command_macros_base.h\"\n"; + sourceOutput += "#include \"z64cutscene_commands.h\"\n"; + sourceOutput += "#include \"variables.h\"\n"; + + if (scene != nullptr) + sourceOutput += scene->parent->GetHeaderInclude(); + + //sourceOutput += "\n"; + + ProcessCommandSets(); + + // Check for texture intersections + { + string defines = ""; + if (textures.size() != 0) + { + vector> texturesSorted(textures.begin(), textures.end()); + + sort(texturesSorted.begin(), texturesSorted.end(), [](const auto& lhs, const auto& rhs) + { + return lhs.first < rhs.first; + }); + + for (int i = 0; i < texturesSorted.size() - 1; i++) + { + int texSize = textures[texturesSorted[i].first]->GetRawDataSize(); + + if ((texturesSorted[i].first + texSize) > texturesSorted[i + 1].first) + { + int intersectAmt = (texturesSorted[i].first + texSize) - texturesSorted[i + 1].first; + + defines += StringHelper::Sprintf("#define %sTex_%06X ((u32)%sTex_%06X + 0x%06X)\n", prefix.c_str(), texturesSorted[i + 1].first, prefix.c_str(), + texturesSorted[i].first, texturesSorted[i + 1].first - texturesSorted[i].first); + + parent->declarations.erase(texturesSorted[i + 1].first); + textures.erase(texturesSorted[i + 1].first); + texturesSorted.erase(texturesSorted.begin() + i + 1); + + i--; + } + } + } + + parent->defines += defines; + //parent->externs[0xFFFFFFFF] = defines; + } + + for (pair item : textures) + { + string declaration = ""; + + declaration += item.second->GetSourceOutputCode(prefix); + + if (Globals::Instance->debugMessages) + printf("SAVING IMAGE TO %s\n", Globals::Instance->outputPath.c_str()); + + item.second->Save(Globals::Instance->outputPath); + + parent->AddDeclarationIncludeArray(item.first, StringHelper::Sprintf("%s/%s.%s.inc.c", + Globals::Instance->outputPath.c_str(), Path::GetFileNameWithoutExtension(item.second->GetName()).c_str(), item.second->GetExternalExtension().c_str()), item.second->GetRawDataSize(), + "u64", StringHelper::Sprintf("%sTex_%06X", prefix.c_str(), item.first), 0); + } + + //sourceOutput += "\n"; + + return sourceOutput; +} + +vector ZRoom::GetRawData() +{ + return rawData; +} + +int ZRoom::GetRawDataSize() +{ + int32_t size = 0; + + for (ZRoomCommand* cmd : commands) + size += cmd->GetRawDataSize(); + + return size; +} + +ZResourceType ZRoom::GetResourceType() +{ + return ZResourceType::Room; +} + +void ZRoom::Save(string outFolder) +{ + for (ZRoomCommand* cmd : commands) + cmd->Save(); +} + +void ZRoom::PreGenSourceFiles() +{ + for (ZRoomCommand* cmd : commands) + cmd->PreGenSourceFiles(); +} + +Declaration::Declaration(DeclarationAlignment nAlignment, DeclarationPadding nPadding, uint32_t nSize, string nText) +{ + alignment = nAlignment; + padding = nPadding; + size = nSize; + preText = ""; + text = nText; + rightText = ""; + postText = ""; + preComment = ""; + postComment = ""; + varType = ""; + varName = ""; + isArray = false; + arrayItemCnt = 0; + includePath = ""; +} + +Declaration::Declaration(DeclarationAlignment nAlignment, uint32_t nSize, string nVarType, string nVarName, bool nIsArray, string nText) : Declaration(nAlignment, DeclarationPadding::None, nSize, nText) +{ + varType = nVarType; + varName = nVarName; + isArray = nIsArray; +} + +Declaration::Declaration(DeclarationAlignment nAlignment, DeclarationPadding nPadding, uint32_t nSize, string nVarType, string nVarName, bool nIsArray, string nText) : Declaration(nAlignment, nPadding, nSize, nText) +{ + varType = nVarType; + varName = nVarName; + isArray = nIsArray; +} + +Declaration::Declaration(DeclarationAlignment nAlignment, uint32_t nSize, string nVarType, string nVarName, bool nIsArray, int nArrayItemCnt, string nText) : Declaration(nAlignment, DeclarationPadding::None, nSize, nText) +{ + varType = nVarType; + varName = nVarName; + isArray = nIsArray; + arrayItemCnt = nArrayItemCnt; +} + +Declaration::Declaration(DeclarationAlignment nAlignment, DeclarationPadding nPadding, uint32_t nSize, string nVarType, string nVarName, bool nIsArray, int nArrayItemCnt, string nText) : Declaration(nAlignment, nPadding, nSize, nText) +{ + varType = nVarType; + varName = nVarName; + isArray = nIsArray; + arrayItemCnt = nArrayItemCnt; +} + +Declaration::Declaration(std::string nIncludePath, uint32_t nSize, string nVarType, string nVarName) : Declaration(DeclarationAlignment::None, DeclarationPadding::None, nSize, "") +{ + includePath = nIncludePath; + varType = nVarType; + varName = nVarName; +} + +CommandSet::CommandSet(int32_t nAddress) +{ + address = nAddress; + commandCount = 9999999; +} + +CommandSet::CommandSet(int32_t nAddress, int32_t nCommandCount) +{ + address = nAddress; + commandCount = nCommandCount; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/ZRoom.h b/tools/ZAPD/ZAPD/ZRoom/ZRoom.h new file mode 100644 index 0000000000..7e6b19ac7c --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/ZRoom.h @@ -0,0 +1,50 @@ +#pragma once + +#include "../ZResource.h" +#include "ZRoomCommand.h" +#include "ZTexture.h" +#include "../tinyxml2.h" + +#include +#include +#include + +class ZRoom : public ZResource +{ +protected: + std::vector commands; + + std::string GetSourceOutputHeader(std::string prefix); + std::string GetSourceOutputCode(std::string prefix); + void ProcessCommandSets(); + void SyotesRoomHack(); + + ZRoom(); + +public: + ZRoom* scene; + std::map textures; + std::vector commandSets; + + std::string extDefines; + + static ZRoom* ExtractFromXML(tinyxml2::XMLElement* reader, std::vector nRawData, int rawDataIndex, std::string nRelPath, ZFile* nParent, ZRoom* nScene); + void ParseCommands(std::vector& commandList, CommandSet commandSet); + size_t GetDeclarationSizeFromNeighbor(int declarationAddress); + size_t GetCommandSizeFromNeighbor(ZRoomCommand* cmd); + ZRoomCommand* FindCommandOfType(RoomCommand cmdType); + std::vector GetRawData(); + int GetRawDataSize(); + virtual ZResourceType GetResourceType(); + virtual void Save(std::string outFolder); + virtual void PreGenSourceFiles(); +}; + +struct CommandSet +{ + int32_t address; + int32_t commandCount; // Only used if explicitly specified in the XML + + CommandSet(int32_t nAddress); + CommandSet(int32_t nAddress, int32_t nCommandCount); +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/ZRoomCommand.cpp b/tools/ZAPD/ZAPD/ZRoom/ZRoomCommand.cpp new file mode 100644 index 0000000000..6b42adec94 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/ZRoomCommand.cpp @@ -0,0 +1,60 @@ +#include "ZRoomCommand.h" + +using namespace std; + +ZRoomCommand::ZRoomCommand(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) +{ + cmdID = (RoomCommand)rawData[rawDataIndex]; + cmdAddress = rawDataIndex; + zRoom = nZRoom; +} + +string ZRoomCommand::GenerateSourceCodePass1(string roomName, int baseAddress) +{ + char line[2048]; + + //sprintf(line, "%s _%s_set%04X_cmd%02X = { 0x%02X,", GetCommandCName().c_str(), roomName.c_str(), baseAddress, cmdIndex, cmdID); + sprintf(line, " 0x%02X,", (uint8_t)cmdID); + + return string(line); +} + +string ZRoomCommand::GenerateSourceCodePass2(string roomName, int baseAddress) +{ + return ""; +} + +string ZRoomCommand::GenerateSourceCodePass3(string roomName) +{ + return ""; +} + +string ZRoomCommand::GenerateExterns() +{ + return ""; +} + +std::string ZRoomCommand::Save() +{ + return std::string(); +} + +std::string ZRoomCommand::PreGenSourceFiles() +{ + return std::string(); +} + +int32_t ZRoomCommand::GetRawDataSize() +{ + return 8; +} + +string ZRoomCommand::GetCommandCName() +{ + return "SCmdBase"; +} + +RoomCommand ZRoomCommand::GetRoomCommand() +{ + return RoomCommand::Error; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoom/ZRoomCommand.h b/tools/ZAPD/ZAPD/ZRoom/ZRoomCommand.h new file mode 100644 index 0000000000..e7c9be7072 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoom/ZRoomCommand.h @@ -0,0 +1,65 @@ +#pragma once + +#include "../tinyxml2.h" + +#include +#include + +class ZRoom; + +enum class RoomCommand : uint8_t +{ + SetStartPositionList = 0x00, + SetActorList = 0x01, + SetCameraSomething = 0x02, + SetCollisionHeader = 0x03, + SetRoomList = 0x04, + SetWind = 0x05, + SetEntranceList = 0x06, + SetSpecialObjects = 0x07, + SetRoomBehavior = 0x08, + Unused09 = 0x09, + SetMesh = 0x0A, + SetObjectList = 0x0B, + SetLightList = 0x0C, + SetPathways = 0x0D, + SetTransitionActorList = 0x0E, + SetLightingSettings = 0x0F, + SetTimeSettings = 0x10, + SetSkyboxSettings = 0x11, + SetSkyboxModifier = 0x12, + SetExitList = 0x13, + EndMarker = 0x14, + SetSoundSettings = 0x15, + SetEchoSettings = 0x16, + SetCutscenes = 0x17, + SetAlternateHeaders = 0x18, + SetCameraSettings = 0x19, + + Error = 0xFF +}; + +class ZRoomCommand +{ +public: + RoomCommand cmdID; + int32_t cmdAddress; + int32_t cmdIndex; + int32_t cmdSet; + uint32_t commandSet; + + ZRoomCommand(ZRoom* nZRoom, std::vector rawData, int rawDataIndex); + + virtual std::string GenerateSourceCodePass1(std::string roomName, int baseAddress); + virtual std::string GenerateSourceCodePass2(std::string roomName, int baseAddress); + virtual std::string GenerateSourceCodePass3(std::string roomName); + virtual RoomCommand GetRoomCommand(); + virtual int32_t GetRawDataSize(); + virtual std::string GetCommandCName(); + virtual std::string GenerateExterns(); + virtual std::string Save(); + virtual std::string PreGenSourceFiles(); + +protected: + ZRoom* zRoom; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZRoot.h b/tools/ZAPD/ZAPD/ZRoot.h new file mode 100644 index 0000000000..6f70f09bee --- /dev/null +++ b/tools/ZAPD/ZAPD/ZRoot.h @@ -0,0 +1 @@ +#pragma once diff --git a/tools/ZAPD/ZAPD/ZSkeleton.cpp b/tools/ZAPD/ZAPD/ZSkeleton.cpp new file mode 100644 index 0000000000..7d41b51689 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZSkeleton.cpp @@ -0,0 +1,297 @@ +#include "ZSkeleton.h" +#include "BitConverter.h" +#include "StringHelper.h" +#include "HighLevel/HLModelIntermediette.h" +#include + +using namespace std; +using namespace tinyxml2; + +ZLimbStandard::ZLimbStandard() +{ + name = ""; + transX = 0; + transY = 0; + transZ = 0; + childIndex = 0; + siblingIndex = 0; + dListPtr = 0; + children = vector(); +} + +ZLimbStandard* ZLimbStandard::FromXML(XMLElement* reader, vector nRawData, int rawDataIndex, string nRelPath, ZFile* parent) +{ + ZLimbType limbType = ZLimbType::Standard; + string limbName = reader->Attribute("Name"); + int limbAddress = strtol(StringHelper::Split(reader->Attribute("Offset"), "0x")[1].c_str(), NULL, 16); + + if (string(reader->Attribute("Type")) == "LOD") + limbType = ZLimbType::LOD; + + ZLimbStandard* limb = ZLimbStandard::FromRawData(nRawData, rawDataIndex); + limb->ParseXML(reader); + limb->parent = parent; + limb->name = limbName; + limb->address = limbAddress; + + string entryType = limbType == ZLimbType::LOD ? "LodLimb" : "StandardLimb"; + + limb->parent->AddDeclaration(limb->address, DeclarationAlignment::None, 12, entryType, StringHelper::Sprintf("%s", limbName.c_str(), limb->address), ""); + + return limb; +} + +ZLimbStandard* ZLimbStandard::FromRawData(std::vector nRawData, int rawDataIndex) +{ + ZLimbStandard* limb = new ZLimbStandard(); + + limb->address = rawDataIndex; + + limb->transX = BitConverter::ToInt16BE(nRawData, rawDataIndex + 0); + limb->transY = BitConverter::ToInt16BE(nRawData, rawDataIndex + 2); + limb->transZ = BitConverter::ToInt16BE(nRawData, rawDataIndex + 4); + + limb->childIndex = nRawData[rawDataIndex + 6]; + limb->siblingIndex = nRawData[rawDataIndex + 7]; + + limb->dListPtr = BitConverter::ToInt32BE(nRawData, rawDataIndex + 8) & 0x00FFFFFF; + + return limb; +} + +string ZLimbStandard::GetSourceOutputCode(string prefix) +{ + string dListStr = dListPtr == 0 ? "NULL" : StringHelper::Sprintf("%s", parent->GetVarName(dListPtr).c_str()); + + string entryStr = StringHelper::Sprintf("{ %i, %i, %i }, %i, %i, %s", + transX, transY, transZ, childIndex, siblingIndex, dListStr.c_str()); + + Declaration* decl = parent->GetDeclaration(address); + decl->text = entryStr; + + return ""; +} + +int ZLimbStandard::GetRawDataSize() +{ + return 12; +} + +ZSkeleton::ZSkeleton() : ZResource() +{ + type = ZSkeletonType::Normal; + limbs = vector(); + rootLimb = nullptr; + dListCount = 0; +} + +void ZSkeleton::GenerateHLIntermediette(HLFileIntermediette& hlFile) +{ + HLModelIntermediette* mdl = (HLModelIntermediette*)&hlFile; + HLModelIntermediette::FromZSkeleton(mdl, this); + //mdl->blocks.push_back(new HLTerminator()); +} + +ZSkeleton* ZSkeleton::FromXML(XMLElement* reader, vector nRawData, int rawDataIndex, string nRelPath, ZFile* nParent) +{ + ZSkeleton* skeleton = new ZSkeleton(); + skeleton->name = reader->Attribute("Name"); + skeleton->parent = nParent; + ZLimbType limbType = ZLimbType::Standard; + ZSkeletonType skeletonType = ZSkeletonType::Normal; + int limbCount = 0; + + skeleton->rawData = nRawData; + skeleton->rawDataIndex = rawDataIndex; + + if (reader->Attribute("Type") != nullptr) + { + if (string(reader->Attribute("Type")) == "Flex") + skeletonType = ZSkeletonType::Flex; + else if (string(reader->Attribute("Type")) == "Skin") + skeletonType = ZSkeletonType::Skin; + else if (string(reader->Attribute("Type")) != "Normal") + { + // TODO: Print some error here... + } + } + + skeleton->type = skeletonType; + + if (reader->Attribute("LimbType") != nullptr) + { + //printf("C3\n"); + + if (string(reader->Attribute("LimbType")) == "LOD") + limbType = ZLimbType::LOD; + } + + limbCount = nRawData[rawDataIndex + 4]; + skeleton->dListCount = nRawData[rawDataIndex + 8]; + + ZLimbStandard* currentLimb = nullptr; + + uint32_t ptr = (uint32_t)BitConverter::ToInt32BE(nRawData, rawDataIndex) & 0x00FFFFFF; + + for (int i = 0; i < limbCount; i++) + { + uint32_t ptr2 = (uint32_t)BitConverter::ToInt32BE(nRawData, ptr) & 0x00FFFFFF; + + if (limbType == ZLimbType::Standard) + { + ZLimbStandard* limb = ZLimbStandard::FromRawData(nRawData, ptr2); + skeleton->limbs.push_back(limb); + } + else + { + ZLimbLOD* limb = ZLimbLOD::FromRawData(nRawData, ptr2); + skeleton->limbs.push_back(limb); + } + + ptr += 4; + } + + return skeleton; +} + +std::string ZSkeleton::GetSourceOutputCode(std::string prefix) +{ + if (parent != nullptr) + { + string defaultPrefix = name.c_str(); + defaultPrefix.replace(0, 1, "s"); // replace g prefix with s for local variables + + for (int i = 0; i < limbs.size(); i++) + { + ZLimbStandard* limb = limbs[i]; + + string defaultDLName = StringHelper::Sprintf("%sLimbDL_%06X", defaultPrefix.c_str(), limb->dListPtr); + string dListStr = limb->dListPtr == 0 ? "NULL" : StringHelper::Sprintf("%s", parent->GetDeclarationName(limb->dListPtr, defaultDLName).c_str()); + + if (limb->dListPtr != 0 && parent->GetDeclaration(limb->dListPtr) == nullptr) + { + ZDisplayList* dList = new ZDisplayList(rawData, limb->dListPtr, ZDisplayList::GetDListLength(rawData, limb->dListPtr)); + dList->parent = parent; + dList->SetName(StringHelper::Sprintf("%sLimbDL_%06X", defaultPrefix.c_str(), limb->dListPtr)); + dList->GetSourceOutputCode(defaultPrefix); + } + + string entryStr = ""; + string entryType = ""; + + if (typeid(*limb) == typeid(ZLimbLOD)) + { + ZLimbLOD* limbLOD = (ZLimbLOD*)limbs[i]; + string defaultFarDLName = StringHelper::Sprintf("%sFarLimbDlist0x%06X", defaultPrefix.c_str(), limbLOD->farDListPtr); + string dListStr2 = limbLOD->farDListPtr == 0 ? "NULL" : StringHelper::Sprintf("%s", parent->GetDeclarationName(limbLOD->farDListPtr, defaultFarDLName).c_str()); + + if (limbLOD->farDListPtr != 0 && parent->GetDeclaration(limbLOD->farDListPtr) == nullptr) + { + ZDisplayList* dList = new ZDisplayList(rawData, limbLOD->farDListPtr, ZDisplayList::GetDListLength(rawData, limbLOD->farDListPtr)); + dList->parent = parent; + dList->SetName(StringHelper::Sprintf("%s_farLimbDlist_%06X", defaultPrefix.c_str(), limbLOD->farDListPtr)); + dList->GetSourceOutputCode(defaultPrefix); + } + + entryType = "LodLimb"; + + entryStr = StringHelper::Sprintf("{ %i, %i, %i }, %i, %i, { %s, %s }", + limbLOD->transX, limbLOD->transY, limbLOD->transZ, limbLOD->childIndex, limbLOD->siblingIndex, dListStr.c_str(), dListStr2.c_str()); + } + else + { + entryType = "StandardLimb"; + + entryStr = StringHelper::Sprintf("{ %i, %i, %i }, %i, %i, %s", + limb->transX, limb->transY, limb->transZ, limb->childIndex, limb->siblingIndex, dListStr.c_str()); + } + + string limbName = StringHelper::Sprintf("%sLimb_%06X", defaultPrefix.c_str(), limb->address); + + if (parent->HasDeclaration(limb->address)) + limbName = parent->GetDeclarationName(limb->address); + + parent->AddDeclaration(limb->address, DeclarationAlignment::None, 12, entryType, limbName, entryStr); + } + + // Table + string tblStr = ""; + + for (int i = 0; i < limbs.size(); i++) + { + ZLimbStandard* limb = limbs[i]; + + //string decl = StringHelper::Sprintf(" &_%sLimb_%04X,\n", prefix.c_str(), limb->address); + string decl = ""; + + if (parent->HasDeclaration(limb->address)) + decl = StringHelper::Sprintf(" &%s,", parent->GetDeclarationName(limb->address).c_str()); + if (i != (limbs.size() - 1)) + decl += "\n"; + + tblStr += decl; + } + + uint32_t ptr = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex) & 0x00FFFFFF; + + if (!parent->HasDeclaration(ptr)) + { + parent->AddDeclarationArray(ptr, DeclarationAlignment::None, 4 * limbs.size(), + "static void*", StringHelper::Sprintf("%sLimbs", defaultPrefix.c_str()), limbs.size(), tblStr); + } + + if (type == ZSkeletonType::Normal) + { + string headerStr = StringHelper::Sprintf("%sLimbs, %i", defaultPrefix.c_str(), limbs.size()); + parent->AddDeclaration(rawDataIndex, DeclarationAlignment::Align16, 8, + "SkeletonHeader", StringHelper::Sprintf("%s", name.c_str()), headerStr); + } + else + { + string headerStr = StringHelper::Sprintf("%sLimbs, %i, %i", defaultPrefix.c_str(), limbs.size(), dListCount); + parent->AddDeclaration(rawDataIndex, DeclarationAlignment::Align16, 12, + "FlexSkeletonHeader", StringHelper::Sprintf("%s", name.c_str()), headerStr); + } + } + + return ""; +} + +void ZSkeleton::Save(string outFolder) +{ + +} + +ZLimbLOD::ZLimbLOD() : ZLimbStandard() +{ + farDListPtr = 0; +} + +ZLimbLOD* ZLimbLOD::FromRawData(vector nRawData, int rawDataIndex) +{ + ZLimbLOD* limb = new ZLimbLOD(); + + limb->address = rawDataIndex; + + limb->transX = BitConverter::ToInt16BE(nRawData, rawDataIndex + 0); + limb->transY = BitConverter::ToInt16BE(nRawData, rawDataIndex + 2); + limb->transZ = BitConverter::ToInt16BE(nRawData, rawDataIndex + 4); + + limb->childIndex = nRawData[rawDataIndex + 6]; + limb->siblingIndex = nRawData[rawDataIndex + 7]; + + limb->dListPtr = BitConverter::ToInt32BE(nRawData, rawDataIndex + 8) & 0x00FFFFFF; + limb->farDListPtr = BitConverter::ToInt32BE(nRawData, rawDataIndex + 12) & 0x00FFFFFF; + + return limb; +} + +string ZLimbLOD::GetSourceOutputCode(string prefix) +{ + return std::string(); +} + +int ZLimbLOD::GetRawDataSize() +{ + return 16; +} diff --git a/tools/ZAPD/ZAPD/ZSkeleton.h b/tools/ZAPD/ZAPD/ZSkeleton.h new file mode 100644 index 0000000000..61d69384af --- /dev/null +++ b/tools/ZAPD/ZAPD/ZSkeleton.h @@ -0,0 +1,64 @@ +#pragma once + +#include +#include +#include +#include "ZFile.h" + +enum class ZLimbType +{ + Standard, + LOD +}; + +struct ZLimbStandard : public ZResource +{ + uint32_t address; + std::string name; + + int16_t transX, transY, transZ; + uint8_t childIndex, siblingIndex; + uint32_t dListPtr; + + std::vector children; + + ZLimbStandard(); + static ZLimbStandard* FromXML(tinyxml2::XMLElement* reader, std::vector nRawData, int rawDataIndex, std::string nRelPath, ZFile* parent); + static ZLimbStandard* FromRawData(std::vector nRawData, int rawDataIndex); + std::string GetSourceOutputCode(std::string prefix); + virtual int GetRawDataSize(); +}; + +struct ZLimbLOD : ZLimbStandard +{ + uint32_t farDListPtr; + + ZLimbLOD(); + //static ZLimbLOD* FromXML(tinyxml2::XMLElement* reader, std::vector nRawData, int rawDataIndex, std::string nRelPath, ZFile* parent); + static ZLimbLOD* FromRawData(std::vector nRawData, int rawDataIndex); + std::string GetSourceOutputCode(std::string prefix); + virtual int GetRawDataSize(); +}; + +enum ZSkeletonType +{ + Normal, + Flex, + Skin +}; + +class ZSkeleton : public ZResource +{ +public: + ZSkeletonType type; + std::vector limbs; + ZLimbStandard* rootLimb; + uint8_t dListCount; // FLEX SKELETON ONLY + + ZSkeleton(); + virtual void GenerateHLIntermediette(HLFileIntermediette& hlFile); + static ZSkeleton* FromXML(tinyxml2::XMLElement* reader, std::vector nRawData, int rawDataIndex, std::string nRelPath, ZFile* nParent); + void Save(std::string outFolder); + + std::string GetSourceOutputCode(std::string prefix); +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZTexture.cpp b/tools/ZAPD/ZAPD/ZTexture.cpp new file mode 100644 index 0000000000..cf802a24cd --- /dev/null +++ b/tools/ZAPD/ZAPD/ZTexture.cpp @@ -0,0 +1,781 @@ +#define STB_IMAGE_IMPLEMENTATION +#define STB_IMAGE_WRITE_IMPLEMENTATION +#define TINYGLTF_IMPLEMENTATION + +#include "ZTexture.h" +#include "StringHelper.h" +#include "BitConverter.h" +#include "Path.h" +#include "File.h" + +#include "stb_image.h" +#include "stb_image_write.h" + +using namespace std; +using namespace tinyxml2; + +ZTexture::ZTexture() : ZResource() +{ + bmpRgb = nullptr; + bmpRgba = nullptr; + width = 0; + height = 0; + type = TextureType::Error; +} + +ZTexture::~ZTexture() +{ + if (bmpRgb != nullptr) + { + stbi_image_free(bmpRgb); + bmpRgb = nullptr; + } + + if (bmpRgba != nullptr) + { + stbi_image_free(bmpRgba); + bmpRgba = nullptr; + } + + width = 0; + height = 0; + type = TextureType::Error; +} + +// EXTRACT MODE +ZTexture* ZTexture::ExtractFromXML(XMLElement* reader, vector nRawData, int nRawDataIndex, string nRelPath) +{ + ZTexture* tex = new ZTexture(); + + tex->ParseXML(reader); + tex->rawDataIndex = nRawDataIndex; + tex->rawData = vector(nRawData.data() + tex->rawDataIndex, nRawData.data() + tex->rawDataIndex + tex->GetRawDataSize()); + + tex->relativePath = nRelPath; + + tex->FixRawData(); + tex->PrepareBitmap(); + + return tex; +} + +ZTexture* ZTexture::FromBinary(TextureType nType, std::vector nRawData, int nRawDataIndex, std::string nName, int nWidth, int nHeight) +{ + ZTexture* tex = new ZTexture(); + + tex->width = nWidth; + tex->height = nHeight; + tex->type = nType; + tex->name = nName; + tex->outName = nName; + tex->rawDataIndex = nRawDataIndex; + + int dataEnd = tex->rawDataIndex + tex->GetRawDataSize(); + tex->rawData = vector(nRawData.data() + tex->rawDataIndex, nRawData.data() + dataEnd); + + tex->FixRawData(); + tex->PrepareBitmap(); + + return tex; +} + +// BUILD MODE +ZTexture* ZTexture::BuildFromXML(XMLElement* reader, string inFolder, bool readFile) +{ + ZTexture* tex = new ZTexture(); + + tex->ParseXML(reader); + + if (readFile) + tex->PrepareRawData(inFolder); + + return tex; +} + +ZTexture* ZTexture::FromPNG(string pngFilePath, TextureType texType) +{ + int comp; + ZTexture* tex = new ZTexture(); + tex->type = texType; + tex->name = StringHelper::Split(Path::GetFileNameWithoutExtension(pngFilePath), ".")[0]; + + tex->bmpRgb = (uint8_t*)stbi_load((pngFilePath).c_str(), &tex->width, &tex->height, &comp, STBI_rgb); + stbi_image_free(tex->bmpRgb); + tex->bmpRgb = nullptr; + tex->rawData = vector(tex->GetRawDataSize()); + + switch (texType) + { + case TextureType::RGBA16bpp: tex->PrepareRawDataRGBA16(pngFilePath); break; + case TextureType::RGBA32bpp: tex->PrepareRawDataRGBA32(pngFilePath); break; + case TextureType::Grayscale4bpp: tex->PrepareRawDataGrayscale4(pngFilePath); break; + case TextureType::Grayscale8bpp: tex->PrepareRawDataGrayscale8(pngFilePath); break; + case TextureType::GrayscaleAlpha4bpp: tex->PrepareRawDataGrayscaleAlpha4(pngFilePath); break; + case TextureType::GrayscaleAlpha8bpp: tex->PrepareRawDataGrayscaleAlpha8(pngFilePath); break; + case TextureType::GrayscaleAlpha16bpp: tex->PrepareRawDataGrayscaleAlpha16(pngFilePath); break; + case TextureType::Palette4bpp: tex->PrepareRawDataPalette4(pngFilePath); break; + case TextureType::Palette8bpp: tex->PrepareRawDataPalette8(pngFilePath); break; + } + + tex->FixRawData(); + + return tex; +} + +ZTexture* ZTexture::FromHLTexture(HLTexture* hlTex) +{ + ZTexture* tex = new ZTexture(); + + tex->width = hlTex->width; + tex->height = hlTex->height; + tex->type = (TextureType)hlTex->type; + + return tex; +} + +void ZTexture::ParseXML(XMLElement* reader) +{ + ZResource::ParseXML(reader); + + if (reader->Attribute("Width") != nullptr) + width = atoi(reader->Attribute("Width")); + + if (reader->Attribute("Height") != nullptr) + height = atoi(reader->Attribute("Height")); + + string formatStr = reader->Attribute("Format"); + + type = GetTextureTypeFromString(formatStr); + + if (type == TextureType::Error) + throw "Format " + formatStr + " is not supported!"; +} + +void ZTexture::FixRawData() +{ + if (type == TextureType::RGBA32bpp) + { + for (int i = 0; i < rawData.size(); i += 4) + { + uint8_t tmp = rawData[i]; + rawData[i] = rawData[i + 2]; + rawData[i + 2] = tmp; + } + } + else if (type == TextureType::RGBA16bpp)// || type == TextureType::GrayscaleAlpha16bpp) + { + for (int i = 0; i < rawData.size(); i += 2) + { + uint8_t tmp = rawData[i]; + rawData[i] = rawData[i + 1]; + rawData[i + 1] = tmp; + } + } +} + +void ZTexture::PrepareBitmap() +{ + bmpRgb = new uint8_t[width * height * 3]; + bmpRgba = new uint8_t[width * height * 4]; + + switch (type) + { + case TextureType::RGBA16bpp: PrepareBitmapRGBA16(); break; + case TextureType::RGBA32bpp: PrepareBitmapRGBA32(); break; + case TextureType::Grayscale4bpp: PrepareBitmapGrayscale4(); break; + case TextureType::Grayscale8bpp: PrepareBitmapGrayscale8(); break; + case TextureType::GrayscaleAlpha4bpp: PrepareBitmapGrayscaleAlpha4(); break; + case TextureType::GrayscaleAlpha8bpp: PrepareBitmapGrayscaleAlpha8(); break; + case TextureType::GrayscaleAlpha16bpp: PrepareBitmapGrayscaleAlpha16(); break; + case TextureType::Palette4bpp: PrepareBitmapPalette4(); break; + case TextureType::Palette8bpp: PrepareBitmapPalette8(); break; + } +} + +void ZTexture::PrepareBitmapRGBA16() +{ + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + int pos = ((y * width) + x) * 2; + short data = (short)((rawData[pos + 1] << 8) + rawData[pos]); + uint8_t r = (uint8_t)((data & 0xF800) >> 11); + uint8_t g = (uint8_t)((data & 0x07C0) >> 6); + uint8_t b = (uint8_t)((data & 0x003E) >> 1); + uint8_t alpha = (uint8_t)(data & 0x01); + + bmpRgba[(((y * width) + x) * 4) + 0] = r * 8; + bmpRgba[(((y * width) + x) * 4) + 1] = g * 8; + bmpRgba[(((y * width) + x) * 4) + 2] = b * 8; + bmpRgba[(((y * width) + x) * 4) + 3] = alpha * 255; + } + } +} + +void ZTexture::PrepareBitmapRGBA32() +{ + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + int pos = ((y * width) + x) * 4; + + bmpRgba[(((y * width) + x) * 4) + 0] = rawData[pos + 2]; + bmpRgba[(((y * width) + x) * 4) + 1] = rawData[pos + 1]; + bmpRgba[(((y * width) + x) * 4) + 2] = rawData[pos + 0]; + bmpRgba[(((y * width) + x) * 4) + 3] = rawData[pos + 3]; + } + } +} + +void ZTexture::PrepareBitmapGrayscale4() +{ + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x += 2) + { + for (int i = 0; i < 2; i++) + { + int pos = ((y * width) + x) / 2; + uint8_t grayscale = 0; + + if (i == 0) + grayscale = (uint8_t)(rawData[pos] & 0xF0); + else + grayscale = (uint8_t)((rawData[pos] & 0x0F) << 4); + + bmpRgb[(((y * width) + x + i) * 3) + 0] = grayscale; + bmpRgb[(((y * width) + x + i) * 3) + 1] = grayscale; + bmpRgb[(((y * width) + x + i) * 3) + 2] = grayscale; + } + } + } +} + +void ZTexture::PrepareBitmapGrayscale8() +{ + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + int pos = ((y * width) + x) * 1; + + bmpRgb[(((y * width) + x) * 3) + 0] = rawData[pos]; + bmpRgb[(((y * width) + x) * 3) + 1] = rawData[pos]; + bmpRgb[(((y * width) + x) * 3) + 2] = rawData[pos]; + } + } +} + +void ZTexture::PrepareBitmapGrayscaleAlpha4() +{ + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x += 2) + { + for (int i = 0; i < 2; i++) + { + int pos = ((y * width) + x) / 2; + uint8_t data = 0; + + if (i == 0) + data = (uint8_t)((rawData[pos] & 0xF0) >> 4); + else + data = (uint8_t)(rawData[pos] & 0x0F); + + uint8_t grayscale = (uint8_t)(((data & 0x0E) >> 1) * 32); + uint8_t alpha = (uint8_t)((data & 0x01) * 255); + + bmpRgba[(((y * width) + x + i) * 4) + 0] = grayscale; + bmpRgba[(((y * width) + x + i) * 4) + 1] = grayscale; + bmpRgba[(((y * width) + x + i) * 4) + 2] = grayscale; + bmpRgba[(((y * width) + x + i) * 4) + 3] = alpha; + } + } + } +} + +void ZTexture::PrepareBitmapGrayscaleAlpha8() +{ + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + int pos = ((y * width) + x) * 1; + uint8_t grayscale = (uint8_t)(rawData[pos] & 0xF0); + uint8_t alpha = (uint8_t)((rawData[pos] & 0x0F) << 4); + + bmpRgba[(((y * width) + x) * 4) + 0] = grayscale; + bmpRgba[(((y * width) + x) * 4) + 1] = grayscale; + bmpRgba[(((y * width) + x) * 4) + 2] = grayscale; + bmpRgba[(((y * width) + x) * 4) + 3] = alpha; + } + } +} + +void ZTexture::PrepareBitmapGrayscaleAlpha16() +{ + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + int pos = ((y * width) + x) * 2; + uint8_t grayscale = rawData[pos + 0]; + uint8_t alpha = rawData[pos + 1]; + + bmpRgba[(((y * width) + x) * 4) + 0] = grayscale; + bmpRgba[(((y * width) + x) * 4) + 1] = grayscale; + bmpRgba[(((y * width) + x) * 4) + 2] = grayscale; + bmpRgba[(((y * width) + x) * 4) + 3] = alpha; + } + } +} + +void ZTexture::PrepareBitmapPalette4() +{ + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x += 2) + { + for (int i = 0; i < 2; i++) + { + int pos = ((y * width) + x) / 2; + uint8_t paletteIndex = 0; + + if (i == 0) + paletteIndex = (uint8_t)((rawData[pos] & 0xF0) >> 4); + else + paletteIndex = (uint8_t)((rawData[pos] & 0x0F)); + + bmpRgb[(((y * width) + x) * 3) + 0] = paletteIndex * 16; + bmpRgb[(((y * width) + x) * 3) + 1] = paletteIndex * 16; + bmpRgb[(((y * width) + x) * 3) + 2] = paletteIndex * 16; + } + } + } +} + +void ZTexture::PrepareBitmapPalette8() +{ + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + int pos = ((y * width) + x) * 1; + + bmpRgb[(((y * width) + x) * 3) + 0] = rawData[pos]; + bmpRgb[(((y * width) + x) * 3) + 1] = rawData[pos]; + bmpRgb[(((y * width) + x) * 3) + 2] = rawData[pos]; + } + } +} + +void ZTexture::PrepareRawData(string inFolder) +{ + rawData = vector(GetRawDataSize()); + + switch (type) + { + case TextureType::RGBA16bpp: PrepareRawDataRGBA16(inFolder + "/" + outName + ".rgba5a1.png"); break; + case TextureType::RGBA32bpp: PrepareRawDataRGBA32(inFolder + "/" + outName + ".rgba32.png"); break; + case TextureType::Grayscale4bpp: PrepareRawDataGrayscale4(inFolder + "/" + outName + ".i4.png"); break; + case TextureType::Grayscale8bpp: PrepareRawDataGrayscale8(inFolder + "/" + outName + ".i8.png"); break; + case TextureType::GrayscaleAlpha4bpp: PrepareRawDataGrayscaleAlpha4(inFolder + "/" + outName + ".ia4.png"); break; + case TextureType::GrayscaleAlpha8bpp: PrepareRawDataGrayscaleAlpha8(inFolder + "/" + outName + ".ia8.png"); break; + case TextureType::GrayscaleAlpha16bpp: PrepareRawDataGrayscaleAlpha16(inFolder + "/" + outName + ".ia16.png"); break; + case TextureType::Palette4bpp: PrepareRawDataPalette4(inFolder + "/" + outName + ".ci4.png"); break; + case TextureType::Palette8bpp: PrepareRawDataPalette8(inFolder + "/" + outName + ".ci8.png"); break; + default: + throw "Build Mode: Format is not supported!"; + } +} + +void ZTexture::PrepareRawDataRGBA16(string rgbaPath) +{ + int width; + int height; + int comp; + + bmpRgba = (uint8_t*)stbi_load(rgbaPath.c_str(), &width, &height, &comp, STBI_rgb_alpha); + + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + int pos = ((y * width) + x) * 2; + + uint8_t r = (uint8_t)(bmpRgba[(((y * width) + x) * 4) + 0] / 8); + uint8_t g = (uint8_t)(bmpRgba[(((y * width) + x) * 4) + 1] / 8); + uint8_t b = (uint8_t)(bmpRgba[(((y * width) + x) * 4) + 2] / 8); + + uint8_t alphaBit = (bmpRgba[(((y * width) + x) * 4) + 3] != 0); + + uint16_t data = (uint16_t)((r << 11) + (g << 6) + (b << 1) + alphaBit); + + rawData[pos + 0] = (uint8_t)((data & 0xFF00) >> 8); + rawData[pos + 1] = (uint8_t)((data & 0x00FF)); + } + } +} + +void ZTexture::PrepareRawDataRGBA32(string rgbaPath) +{ + int width; + int height; + int comp; + + bmpRgba = (uint8_t*)stbi_load(rgbaPath.c_str(), &width, &height, &comp, STBI_rgb_alpha); + + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + int pos = ((y * width) + x) * 4; + + rawData[pos + 0] = bmpRgba[(((y * width) + x) * 4) + 0]; + rawData[pos + 1] = bmpRgba[(((y * width) + x) * 4) + 1]; + rawData[pos + 2] = bmpRgba[(((y * width) + x) * 4) + 2]; + rawData[pos + 3] = bmpRgba[(((y * width) + x) * 4) + 3]; + } + } +} + +void ZTexture::PrepareRawDataGrayscale4(string grayPath) +{ + int width; + int height; + int comp; + + bmpRgb = (uint8_t*)stbi_load(grayPath.c_str(), &width, &height, &comp, STBI_rgb); + + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x += 2) + { + int pos = ((y * width) + x) / 2; + uint8_t r1 = (uint8_t)(bmpRgb[(((y * width) + x) * 3) + 0]); + uint8_t r2 = (uint8_t)(bmpRgb[(((y * width) + x + 1) * 3) + 0]); + + rawData[pos] = (uint8_t)(((r1 / 16) << 4) + (r2 / 16)); + } + } +} + +void ZTexture::PrepareRawDataGrayscale8(string grayPath) +{ + int width; + int height; + int comp; + + bmpRgb = (uint8_t*)stbi_load(grayPath.c_str(), &width, &height, &comp, STBI_rgb); + + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + int pos = ((y * width) + x); + rawData[pos] = bmpRgb[(((y * width) + x) * 3) + 0]; + } + } +} + +void ZTexture::PrepareRawDataGrayscaleAlpha4(string grayAlphaPath) +{ + int width; + int height; + int comp; + + bmpRgba = (uint8_t*)stbi_load(grayAlphaPath.c_str(), &width, &height, &comp, STBI_rgb_alpha); + + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x += 2) + { + int pos = ((y * width) + x) / 2; + uint8_t data = 0; + + for (int i = 0; i < 2; i++) + { + uint8_t cR = bmpRgba[(((y * width) + x + i) * 4) + 0]; + uint8_t alphaBit = (bmpRgba[(((y * width) + x + i) * 4) + 3] != 0); + + if (i == 0) + data += (uint8_t)((((cR / 32) << 1) + alphaBit) << 4); + else + data += (uint8_t)(((cR / 32) << 1) + alphaBit); + } + + rawData[pos] = data; + } + } +} + +void ZTexture::PrepareRawDataGrayscaleAlpha8(string grayAlphaPath) +{ + int width; + int height; + int comp; + + bmpRgba = (uint8_t*)stbi_load(grayAlphaPath.c_str(), &width, &height, &comp, STBI_rgb_alpha); + + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + int pos = ((y * width) + x) * 1; + + uint8_t r = (uint8_t)(bmpRgba[(((y * width) + x) * 4) + 0]); + uint8_t a = (uint8_t)(bmpRgba[(((y * width) + x) * 4) + 3]); + + rawData[pos] = (uint8_t)(((r / 16) << 4) + (a / 16)); + } + } +} + +void ZTexture::PrepareRawDataGrayscaleAlpha16(string grayAlphaPath) +{ + int width; + int height; + int comp; + + bmpRgba = (uint8_t*)stbi_load(grayAlphaPath.c_str(), &width, &height, &comp, STBI_rgb_alpha); + + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + int pos = ((y * width) + x) * 2; + + uint8_t cR = bmpRgba[(((y * width) + x) * 4) + 0]; + uint8_t aR = bmpRgba[(((y * width) + x) * 4) + 3]; + + rawData[pos + 0] = (uint8_t)(cR); + rawData[pos + 1] = (uint8_t)(aR); + } + } +} + +void ZTexture::PrepareRawDataPalette4(string palPath) +{ + int width; + int height; + int comp; + + bmpRgb = (uint8_t*)stbi_load(palPath.c_str(), &width, &height, &comp, STBI_rgb); + + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x += 2) + { + int pos = ((y * width) + x) / 2; + + uint8_t cR1 = bmpRgb[(((y * width) + x) * 3) + 0]; + uint8_t cR2 = bmpRgb[(((y * width) + x + 1) * 3) + 0]; + + rawData[pos] = (uint8_t)(((cR1 / 16) << 4) + (cR2 / 16)); + } + } +} + +void ZTexture::PrepareRawDataPalette8(string palPath) +{ + int width; + int height; + int comp; + + bmpRgb = (uint8_t*)stbi_load(palPath.c_str(), &width, &height, &comp, STBI_rgb); + + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + int pos = ((y * width) + x); + + uint8_t cR = bmpRgb[(((y * width) + x) * 3) + 0]; + rawData[pos] = cR; + } + } +} + +float ZTexture::GetPixelMultiplyer() +{ + switch (type) + { + case TextureType::Grayscale4bpp: case TextureType::GrayscaleAlpha4bpp: case TextureType::Palette4bpp: return 0.5f; + case TextureType::Grayscale8bpp: case TextureType::GrayscaleAlpha8bpp: case TextureType::Palette8bpp: return 1; + case TextureType::GrayscaleAlpha16bpp: case TextureType::RGBA16bpp: return 2; + case TextureType::RGBA32bpp: return 4; + } + + return -1; +} + +vector ZTexture::GetRawData() +{ + return rawData; +} + +int ZTexture::GetRawDataSize() +{ + return (int)(width * height * GetPixelMultiplyer()); +} + +std::string ZTexture::GetIMFmtFromType() +{ + switch (type) + { + case TextureType::RGBA32bpp: case TextureType::RGBA16bpp: return "G_IM_FMT_RGBA"; + case TextureType::Grayscale4bpp: case TextureType::Grayscale8bpp: return "G_IM_FMT_I"; + case TextureType::Palette4bpp: case TextureType::Palette8bpp: return "G_IM_FMT_CI"; + case TextureType::GrayscaleAlpha4bpp: case TextureType::GrayscaleAlpha8bpp: case TextureType::GrayscaleAlpha16bpp: return "G_IM_FMT_IA"; + } + + return "ERROR"; +} + +std::string ZTexture::GetIMSizFromType() +{ + switch (type) + { + case TextureType::Grayscale4bpp: case TextureType::Palette4bpp: case TextureType::GrayscaleAlpha4bpp: return "G_IM_SIZ_4b"; + case TextureType::Palette8bpp: case TextureType::Grayscale8bpp: return "G_IM_SIZ_8b"; + case TextureType::GrayscaleAlpha16bpp: case TextureType::RGBA16bpp: return "G_IM_SIZ_16b"; + case TextureType::RGBA32bpp: return "G_IM_SIZ_32b"; + } + + return "ERROR"; +} + +int ZTexture::GetWidth() +{ + return width; +} + +int ZTexture::GetHeight() +{ + return height; +} + +void ZTexture::Save(string outFolder) +{ + if (type == TextureType::RGBA32bpp) + stbi_write_png((outFolder + "/" + outName + ".rgba32.png").c_str(), width, height, 4, bmpRgba, width * 4); + else if (type == TextureType::RGBA16bpp) + stbi_write_png((outFolder + "/" + outName + ".rgb5a1.png").c_str(), width, height, 4, bmpRgba, width * 4); + else if (type == TextureType::Grayscale8bpp) + stbi_write_png((outFolder + "/" + outName + ".i8.png").c_str(), width, height, 3, bmpRgb, width * 3); + else if (type == TextureType::Grayscale4bpp) + stbi_write_png((outFolder + "/" + outName + ".i4.png").c_str(), width, height, 3, bmpRgb, width * 3); + else if (type == TextureType::GrayscaleAlpha16bpp) + stbi_write_png((outFolder + "/" + outName + ".ia16.png").c_str(), width, height, 4, bmpRgba, width * 4); + else if (type == TextureType::GrayscaleAlpha8bpp) + stbi_write_png((outFolder + "/" + outName + ".ia8.png").c_str(), width, height, 4, bmpRgba, width * 4); + else if (type == TextureType::GrayscaleAlpha4bpp) + stbi_write_png((outFolder + "/" + outName + ".ia4.png").c_str(), width, height, 4, bmpRgba, width * 4); + else if (type == TextureType::Palette4bpp) + stbi_write_png((outFolder + "/" + outName + ".ci4.png").c_str(), width, height, 3, bmpRgb, width * 3); + else if (type == TextureType::Palette8bpp) + stbi_write_png((outFolder + "/" + outName + ".ci8.png").c_str(), width, height, 3, bmpRgb, width * 3); + + //if (outName != name && outName != "") + //File::WriteAllText(outFolder + "/" + outName + ".cfg", name.c_str()); +} + +// HOTSPOT +string ZTexture::GetSourceOutputCode(std::string prefix) +{ + sourceOutput = ""; + + //sprintf(line, "%s:\n", name.c_str()); + //sourceOutput += line; + + // TODO: TEMP + relativePath = "build/assets/" + relativePath; + FixRawData(); + + //sourceOutput += StringHelper::Sprintf("u64 %s[] = \n{\n", name.c_str()); + + uint8_t* rawDataArr = rawData.data(); + + for (int i = 0; i < rawData.size(); i += 8) + { + if (i % 32 == 0) + sourceOutput += "\t"; + + sourceOutput += StringHelper::Sprintf("0x%016llX, ", BitConverter::ToInt64BE(rawDataArr, i)); + + if (i % 32 == 24) + sourceOutput += StringHelper::Sprintf(" // 0x%06X \n", rawDataIndex + ((i / 32) * 32)); + } + + //sourceOutput += "};\n"; + + return sourceOutput; +} + +bool ZTexture::IsExternalResource() +{ + return true; +} + +ZResourceType ZTexture::GetResourceType() +{ + return ZResourceType::Texture; +} + +void ZTexture::CalcHash() +{ + hash = 0; +} + +std::string ZTexture::GetExternalExtension() +{ + switch (type) + { + case TextureType::RGBA32bpp: return "rgba32"; + case TextureType::RGBA16bpp: return "rgb5a1"; + case TextureType::Grayscale4bpp: return "i4"; + case TextureType::Grayscale8bpp: return "i8"; + case TextureType::GrayscaleAlpha4bpp: return "ia4"; + case TextureType::GrayscaleAlpha8bpp: return "ia8"; + case TextureType::GrayscaleAlpha16bpp: return "ia16"; + case TextureType::Palette4bpp: return "ci4"; + case TextureType::Palette8bpp: return "ci8"; + } + + return ""; +} + + +string ZTexture::GetSourceOutputHeader(std::string prefix) +{ + //return StringHelper::Sprintf("extern u64 %s[];\n", name.c_str()); + return ""; +} + +TextureType ZTexture::GetTextureTypeFromString(string str) +{ + TextureType texType = TextureType::Error; + + if (str == "rgba32") + texType = TextureType::RGBA32bpp; + else if (str == "rgb5a1") + texType = TextureType::RGBA16bpp; + else if (str == "i4") + texType = TextureType::Grayscale4bpp; + else if (str == "i8") + texType = TextureType::Grayscale8bpp; + else if (str == "ia4") + texType = TextureType::GrayscaleAlpha4bpp; + else if (str == "ia8") + texType = TextureType::GrayscaleAlpha8bpp; + else if (str == "ia16") + texType = TextureType::GrayscaleAlpha16bpp; + else if (str == "ci4") + texType = TextureType::Palette4bpp; + else if (str == "ci8") + texType = TextureType::Palette8bpp; + + return texType; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZTexture.h b/tools/ZAPD/ZAPD/ZTexture.h new file mode 100644 index 0000000000..b16961d6e7 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZTexture.h @@ -0,0 +1,81 @@ +#pragma once + +#include "ZResource.h" +#include "HighLevel/HLTexture.h" +#include "tinyxml2.h" + +#include + +enum class TextureType +{ + RGBA32bpp, + RGBA16bpp, + Palette4bpp, + Palette8bpp, + Grayscale4bpp, + Grayscale8bpp, + GrayscaleAlpha4bpp, + GrayscaleAlpha8bpp, + GrayscaleAlpha16bpp, + Error +}; + +class ZTexture : public ZResource +{ +protected: + TextureType type; + int width, height; + + uint8_t* bmpRgb; + uint8_t* bmpRgba; + + virtual void ParseXML(tinyxml2::XMLElement* reader); + void FixRawData(); + void PrepareBitmap(); + void PrepareBitmapRGBA16(); + void PrepareBitmapRGBA32(); + void PrepareBitmapGrayscale8(); + void PrepareBitmapGrayscaleAlpha8(); + void PrepareBitmapGrayscale4(); + void PrepareBitmapGrayscaleAlpha4(); + void PrepareBitmapGrayscaleAlpha16(); + void PrepareBitmapPalette4(); + void PrepareBitmapPalette8(); + void PrepareRawData(std::string inFolder); + void PrepareRawDataRGBA16(std::string rgbaPath); + void PrepareRawDataRGBA32(std::string rgbaPath); + void PrepareRawDataGrayscale4(std::string grayPath); + void PrepareRawDataGrayscale8(std::string grayPath); + void PrepareRawDataGrayscaleAlpha4(std::string grayAlphaPath); + void PrepareRawDataGrayscaleAlpha8(std::string grayAlphaPath); + void PrepareRawDataGrayscaleAlpha16(std::string grayAlphaPath); + void PrepareRawDataPalette4(std::string palPath); + void PrepareRawDataPalette8(std::string palPath); + float GetPixelMultiplyer(); + bool IsExternalResource(); + ZResourceType GetResourceType(); + void CalcHash(); + +public: + ZTexture(); + ~ZTexture(); + + static ZTexture* BuildFromXML(tinyxml2::XMLElement* reader, std::string inFolder, bool readFile); + static ZTexture* ExtractFromXML(tinyxml2::XMLElement* reader, std::vector nRawData, int rawDataIndex, std::string nRelPath); + static ZTexture* FromBinary(TextureType nType, std::vector nRawData, int rawDataIndex, std::string nName, int nWidth, int nHeight); + static ZTexture* FromPNG(std::string pngFilePath, TextureType texType); + static ZTexture* FromHLTexture(HLTexture* hlTex); + static TextureType GetTextureTypeFromString(std::string str); + + std::string GetSourceOutputCode(std::string prefix); + std::string GetSourceOutputHeader(std::string prefix); + + std::vector GetRawData(); + int GetRawDataSize(); + std::string GetIMFmtFromType(); + std::string GetIMSizFromType(); + int GetWidth(); + int GetHeight(); + void Save(std::string outFolder); + std::string GetExternalExtension(); +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/assimp/.editorconfig b/tools/ZAPD/ZAPD/assimp/.editorconfig new file mode 100644 index 0000000000..9ea66423ad --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/.editorconfig @@ -0,0 +1,8 @@ +# See for details + +[*.{h,hpp,inl}] +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_size = 4 +indent_style = space diff --git a/tools/ZAPD/ZAPD/assimp/BaseImporter.h b/tools/ZAPD/ZAPD/assimp/BaseImporter.h new file mode 100644 index 0000000000..55f7fe3754 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/BaseImporter.h @@ -0,0 +1,418 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file Definition of the base class for all importer worker classes. */ +#ifndef INCLUDED_AI_BASEIMPORTER_H +#define INCLUDED_AI_BASEIMPORTER_H + +#include "Exceptional.h" + +#include +#include +#include +#include +#include +#include + +struct aiScene; +struct aiImporterDesc; + +namespace Assimp { + +class Importer; +class IOSystem; +class BaseProcess; +class SharedPostProcessInfo; +class IOStream; + +// utility to do char4 to uint32 in a portable manner +#define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \ + (string[1] << 16) + (string[2] << 8) + string[3])) + + +// --------------------------------------------------------------------------- +/** FOR IMPORTER PLUGINS ONLY: The BaseImporter defines a common interface + * for all importer worker classes. + * + * The interface defines two functions: CanRead() is used to check if the + * importer can handle the format of the given file. If an implementation of + * this function returns true, the importer then calls ReadFile() which + * imports the given file. ReadFile is not overridable, it just calls + * InternReadFile() and catches any ImportErrorException that might occur. + */ +class ASSIMP_API BaseImporter { + friend class Importer; + +private: + /* Pushes state into importer for the importer scale */ + virtual void UpdateImporterScale( Importer* pImp ); + +public: + + /** Constructor to be privately used by #Importer */ + BaseImporter() AI_NO_EXCEPT; + + /** Destructor, private as well */ + virtual ~BaseImporter(); + + // ------------------------------------------------------------------- + /** Returns whether the class can handle the format of the given file. + * + * The implementation should be as quick as possible. A check for + * the file extension is enough. If no suitable loader is found with + * this strategy, CanRead() is called again, the 'checkSig' parameter + * set to true this time. Now the implementation is expected to + * perform a full check of the file structure, possibly searching the + * first bytes of the file for magic identifiers or keywords. + * + * @param pFile Path and file name of the file to be examined. + * @param pIOHandler The IO handler to use for accessing any file. + * @param checkSig Set to true if this method is called a second time. + * This time, the implementation may take more time to examine the + * contents of the file to be loaded for magic bytes, keywords, etc + * to be able to load files with unknown/not existent file extensions. + * @return true if the class can read this file, false if not. + */ + virtual bool CanRead( + const std::string& pFile, + IOSystem* pIOHandler, + bool checkSig + ) const = 0; + + // ------------------------------------------------------------------- + /** Imports the given file and returns the imported data. + * If the import succeeds, ownership of the data is transferred to + * the caller. If the import fails, NULL is returned. The function + * takes care that any partially constructed data is destroyed + * beforehand. + * + * @param pImp #Importer object hosting this loader. + * @param pFile Path of the file to be imported. + * @param pIOHandler IO-Handler used to open this and possible other files. + * @return The imported data or NULL if failed. If it failed a + * human-readable error description can be retrieved by calling + * GetErrorText() + * + * @note This function is not intended to be overridden. Implement + * InternReadFile() to do the import. If an exception is thrown somewhere + * in InternReadFile(), this function will catch it and transform it into + * a suitable response to the caller. + */ + aiScene* ReadFile( + Importer* pImp, + const std::string& pFile, + IOSystem* pIOHandler + ); + + // ------------------------------------------------------------------- + /** Returns the error description of the last error that occurred. + * @return A description of the last error that occurred. An empty + * string if there was no error. + */ + const std::string& GetErrorText() const { + return m_ErrorText; + } + + // ------------------------------------------------------------------- + /** Called prior to ReadFile(). + * The function is a request to the importer to update its configuration + * basing on the Importer's configuration property list. + * @param pImp Importer instance + */ + virtual void SetupProperties( + const Importer* pImp + ); + + // ------------------------------------------------------------------- + /** Called by #Importer::GetImporterInfo to get a description of + * some loader features. Importers must provide this information. */ + virtual const aiImporterDesc* GetInfo() const = 0; + + /** + * Will be called only by scale process when scaling is requested. + */ + virtual void SetFileScale(double scale) + { + fileScale = scale; + } + + virtual double GetFileScale() const + { + return fileScale; + } + + enum ImporterUnits { + M, + MM, + CM, + INCHES, + FEET + }; + + /** + * Assimp Importer + * unit conversions available + * if you need another measurment unit add it below. + * it's currently defined in assimp that we prefer meters. + * */ + std::map importerUnits = { + {ImporterUnits::M, 1}, + {ImporterUnits::CM, 0.01}, + {ImporterUnits::MM, 0.001}, + {ImporterUnits::INCHES, 0.0254}, + {ImporterUnits::FEET, 0.3048} + }; + + virtual void SetApplicationUnits( const ImporterUnits& unit ) + { + importerScale = importerUnits[unit]; + applicationUnits = unit; + } + + virtual const ImporterUnits& GetApplicationUnits() + { + return applicationUnits; + } + + // ------------------------------------------------------------------- + /** Called by #Importer::GetExtensionList for each loaded importer. + * Take the extension list contained in the structure returned by + * #GetInfo and insert all file extensions into the given set. + * @param extension set to collect file extensions in*/ + void GetExtensionList(std::set& extensions); + +protected: + ImporterUnits applicationUnits = ImporterUnits::M; + double importerScale = 1.0; + double fileScale = 1.0; + + + + // ------------------------------------------------------------------- + /** Imports the given file into the given scene structure. The + * function is expected to throw an ImportErrorException if there is + * an error. If it terminates normally, the data in aiScene is + * expected to be correct. Override this function to implement the + * actual importing. + *
+ * The output scene must meet the following requirements:
+ *
    + *
  • At least a root node must be there, even if its only purpose + * is to reference one mesh.
  • + *
  • aiMesh::mPrimitiveTypes may be 0. The types of primitives + * in the mesh are determined automatically in this case.
  • + *
  • the vertex data is stored in a pseudo-indexed "verbose" format. + * In fact this means that every vertex that is referenced by + * a face is unique. Or the other way round: a vertex index may + * not occur twice in a single aiMesh.
  • + *
  • aiAnimation::mDuration may be -1. Assimp determines the length + * of the animation automatically in this case as the length of + * the longest animation channel.
  • + *
  • aiMesh::mBitangents may be NULL if tangents and normals are + * given. In this case bitangents are computed as the cross product + * between normal and tangent.
  • + *
  • There needn't be a material. If none is there a default material + * is generated. However, it is recommended practice for loaders + * to generate a default material for yourself that matches the + * default material setting for the file format better than Assimp's + * generic default material. Note that default materials *should* + * be named AI_DEFAULT_MATERIAL_NAME if they're just color-shaded + * or AI_DEFAULT_TEXTURED_MATERIAL_NAME if they define a (dummy) + * texture.
  • + *
+ * If the AI_SCENE_FLAGS_INCOMPLETE-Flag is not set:
    + *
  • at least one mesh must be there
  • + *
  • there may be no meshes with 0 vertices or faces
  • + *
+ * This won't be checked (except by the validation step): Assimp will + * crash if one of the conditions is not met! + * + * @param pFile Path of the file to be imported. + * @param pScene The scene object to hold the imported data. + * NULL is not a valid parameter. + * @param pIOHandler The IO handler to use for any file access. + * NULL is not a valid parameter. */ + virtual void InternReadFile( + const std::string& pFile, + aiScene* pScene, + IOSystem* pIOHandler + ) = 0; + +public: // static utilities + + // ------------------------------------------------------------------- + /** A utility for CanRead(). + * + * The function searches the header of a file for a specific token + * and returns true if this token is found. This works for text + * files only. There is a rudimentary handling of UNICODE files. + * The comparison is case independent. + * + * @param pIOSystem IO System to work with + * @param file File name of the file + * @param tokens List of tokens to search for + * @param numTokens Size of the token array + * @param searchBytes Number of bytes to be searched for the tokens. + */ + static bool SearchFileHeaderForToken( + IOSystem* pIOSystem, + const std::string& file, + const char** tokens, + unsigned int numTokens, + unsigned int searchBytes = 200, + bool tokensSol = false, + bool noAlphaBeforeTokens = false); + + // ------------------------------------------------------------------- + /** @brief Check whether a file has a specific file extension + * @param pFile Input file + * @param ext0 Extension to check for. Lowercase characters only, no dot! + * @param ext1 Optional second extension + * @param ext2 Optional third extension + * @note Case-insensitive + */ + static bool SimpleExtensionCheck ( + const std::string& pFile, + const char* ext0, + const char* ext1 = NULL, + const char* ext2 = NULL); + + // ------------------------------------------------------------------- + /** @brief Extract file extension from a string + * @param pFile Input file + * @return Extension without trailing dot, all lowercase + */ + static std::string GetExtension ( + const std::string& pFile); + + // ------------------------------------------------------------------- + /** @brief Check whether a file starts with one or more magic tokens + * @param pFile Input file + * @param pIOHandler IO system to be used + * @param magic n magic tokens + * @params num Size of magic + * @param offset Offset from file start where tokens are located + * @param Size of one token, in bytes. Maximally 16 bytes. + * @return true if one of the given tokens was found + * + * @note For convenience, the check is also performed for the + * byte-swapped variant of all tokens (big endian). Only for + * tokens of size 2,4. + */ + static bool CheckMagicToken( + IOSystem* pIOHandler, + const std::string& pFile, + const void* magic, + unsigned int num, + unsigned int offset = 0, + unsigned int size = 4); + + // ------------------------------------------------------------------- + /** An utility for all text file loaders. It converts a file to our + * UTF8 character set. Errors are reported, but ignored. + * + * @param data File buffer to be converted to UTF8 data. The buffer + * is resized as appropriate. */ + static void ConvertToUTF8( + std::vector& data); + + // ------------------------------------------------------------------- + /** An utility for all text file loaders. It converts a file from our + * UTF8 character set back to ISO-8859-1. Errors are reported, but ignored. + * + * @param data File buffer to be converted from UTF8 to ISO-8859-1. The buffer + * is resized as appropriate. */ + static void ConvertUTF8toISO8859_1( + std::string& data); + + // ------------------------------------------------------------------- + /// @brief Enum to define, if empty files are ok or not. + enum TextFileMode { + ALLOW_EMPTY, + FORBID_EMPTY + }; + + // ------------------------------------------------------------------- + /** Utility for text file loaders which copies the contents of the + * file into a memory buffer and converts it to our UTF8 + * representation. + * @param stream Stream to read from. + * @param data Output buffer to be resized and filled with the + * converted text file data. The buffer is terminated with + * a binary 0. + * @param mode Whether it is OK to load empty text files. */ + static void TextFileToBuffer( + IOStream* stream, + std::vector& data, + TextFileMode mode = FORBID_EMPTY); + + // ------------------------------------------------------------------- + /** Utility function to move a std::vector into a aiScene array + * @param vec The vector to be moved + * @param out The output pointer to the allocated array. + * @param numOut The output count of elements copied. */ + template + AI_FORCE_INLINE + static void CopyVector( + std::vector& vec, + T*& out, + unsigned int& outLength) + { + outLength = unsigned(vec.size()); + if (outLength) { + out = new T[outLength]; + std::swap_ranges(vec.begin(), vec.end(), out); + } + } + +protected: + /// Error description in case there was one. + std::string m_ErrorText; + /// Currently set progress handler. + ProgressHandler* m_progress; +}; + + + +} // end of namespace Assimp + +#endif // AI_BASEIMPORTER_H_INC diff --git a/tools/ZAPD/ZAPD/assimp/Bitmap.h b/tools/ZAPD/ZAPD/assimp/Bitmap.h new file mode 100644 index 0000000000..e6b5fb1327 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/Bitmap.h @@ -0,0 +1,125 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file Bitmap.h + * @brief Defines bitmap format helper for textures + * + * Used for file formats which embed their textures into the model file. + */ + +#ifndef AI_BITMAP_H_INC +#define AI_BITMAP_H_INC + +#include "defs.h" +#include +#include + +struct aiTexture; + +namespace Assimp { + +class IOStream; + +class ASSIMP_API Bitmap { +protected: + + struct Header { + uint16_t type; + uint32_t size; + uint16_t reserved1; + uint16_t reserved2; + uint32_t offset; + + // We define the struct size because sizeof(Header) might return a wrong result because of structure padding. + // Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field). + static const std::size_t header_size = + sizeof(uint16_t) + // type + sizeof(uint32_t) + // size + sizeof(uint16_t) + // reserved1 + sizeof(uint16_t) + // reserved2 + sizeof(uint32_t); // offset + }; + + struct DIB { + uint32_t size; + int32_t width; + int32_t height; + uint16_t planes; + uint16_t bits_per_pixel; + uint32_t compression; + uint32_t image_size; + int32_t x_resolution; + int32_t y_resolution; + uint32_t nb_colors; + uint32_t nb_important_colors; + + // We define the struct size because sizeof(DIB) might return a wrong result because of structure padding. + // Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field). + static const std::size_t dib_size = + sizeof(uint32_t) + // size + sizeof(int32_t) + // width + sizeof(int32_t) + // height + sizeof(uint16_t) + // planes + sizeof(uint16_t) + // bits_per_pixel + sizeof(uint32_t) + // compression + sizeof(uint32_t) + // image_size + sizeof(int32_t) + // x_resolution + sizeof(int32_t) + // y_resolution + sizeof(uint32_t) + // nb_colors + sizeof(uint32_t); // nb_important_colors + }; + + static const std::size_t mBytesPerPixel = 4; + +public: + static void Save(aiTexture* texture, IOStream* file); + +protected: + static void WriteHeader(Header& header, IOStream* file); + static void WriteDIB(DIB& dib, IOStream* file); + static void WriteData(aiTexture* texture, IOStream* file); +}; + +} + +#endif // AI_BITMAP_H_INC diff --git a/tools/ZAPD/ZAPD/assimp/BlobIOSystem.h b/tools/ZAPD/ZAPD/assimp/BlobIOSystem.h new file mode 100644 index 0000000000..d005e5c119 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/BlobIOSystem.h @@ -0,0 +1,338 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file Provides cheat implementations for IOSystem and IOStream to + * redirect exporter output to a blob chain.*/ + +#ifndef AI_BLOBIOSYSTEM_H_INCLUDED +#define AI_BLOBIOSYSTEM_H_INCLUDED + +#include +#include +#include +#include +#include +#include +#include + +namespace Assimp { + class BlobIOSystem; + +// -------------------------------------------------------------------------------------------- +/** Redirect IOStream to a blob */ +// -------------------------------------------------------------------------------------------- +class BlobIOStream : public IOStream +{ +public: + + BlobIOStream(BlobIOSystem* creator, const std::string& file, size_t initial = 4096) + : buffer() + , cur_size() + , file_size() + , cursor() + , initial(initial) + , file(file) + , creator(creator) + { + } + + + virtual ~BlobIOStream(); + +public: + + // ------------------------------------------------------------------- + aiExportDataBlob* GetBlob() + { + aiExportDataBlob* blob = new aiExportDataBlob(); + blob->size = file_size; + blob->data = buffer; + + buffer = NULL; + + return blob; + } + + +public: + + + // ------------------------------------------------------------------- + virtual size_t Read( void *, + size_t, + size_t ) + { + return 0; + } + + // ------------------------------------------------------------------- + virtual size_t Write(const void* pvBuffer, + size_t pSize, + size_t pCount) + { + pSize *= pCount; + if (cursor + pSize > cur_size) { + Grow(cursor + pSize); + } + + memcpy(buffer+cursor, pvBuffer, pSize); + cursor += pSize; + + file_size = std::max(file_size,cursor); + return pCount; + } + + // ------------------------------------------------------------------- + virtual aiReturn Seek(size_t pOffset, + aiOrigin pOrigin) + { + switch(pOrigin) + { + case aiOrigin_CUR: + cursor += pOffset; + break; + + case aiOrigin_END: + cursor = file_size - pOffset; + break; + + case aiOrigin_SET: + cursor = pOffset; + break; + + default: + return AI_FAILURE; + } + + if (cursor > file_size) { + Grow(cursor); + } + + file_size = std::max(cursor,file_size); + return AI_SUCCESS; + } + + // ------------------------------------------------------------------- + virtual size_t Tell() const + { + return cursor; + } + + // ------------------------------------------------------------------- + virtual size_t FileSize() const + { + return file_size; + } + + // ------------------------------------------------------------------- + virtual void Flush() + { + // ignore + } + + + +private: + + // ------------------------------------------------------------------- + void Grow(size_t need = 0) + { + // 1.5 and phi are very heap-friendly growth factors (the first + // allows for frequent re-use of heap blocks, the second + // forms a fibonacci sequence with similar characteristics - + // since this heavily depends on the heap implementation + // and other factors as well, i'll just go with 1.5 since + // it is quicker to compute). + size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) )); + + const uint8_t* const old = buffer; + buffer = new uint8_t[new_size]; + + if (old) { + memcpy(buffer,old,cur_size); + delete[] old; + } + + cur_size = new_size; + } + +private: + + uint8_t* buffer; + size_t cur_size,file_size, cursor, initial; + + const std::string file; + BlobIOSystem* const creator; +}; + + +#define AI_BLOBIO_MAGIC "$blobfile" + +// -------------------------------------------------------------------------------------------- +/** Redirect IOSystem to a blob */ +// -------------------------------------------------------------------------------------------- +class BlobIOSystem : public IOSystem +{ + + friend class BlobIOStream; + typedef std::pair BlobEntry; + +public: + + BlobIOSystem() + { + } + + virtual ~BlobIOSystem() + { + for(BlobEntry& blobby : blobs) { + delete blobby.second; + } + } + +public: + + // ------------------------------------------------------------------- + const char* GetMagicFileName() const + { + return AI_BLOBIO_MAGIC; + } + + + // ------------------------------------------------------------------- + aiExportDataBlob* GetBlobChain() + { + // one must be the master + aiExportDataBlob* master = NULL, *cur; + for(const BlobEntry& blobby : blobs) { + if (blobby.first == AI_BLOBIO_MAGIC) { + master = blobby.second; + break; + } + } + if (!master) { + ASSIMP_LOG_ERROR("BlobIOSystem: no data written or master file was not closed properly."); + return NULL; + } + + master->name.Set(""); + + cur = master; + for(const BlobEntry& blobby : blobs) { + if (blobby.second == master) { + continue; + } + + cur->next = blobby.second; + cur = cur->next; + + // extract the file extension from the file written + const std::string::size_type s = blobby.first.find_first_of('.'); + cur->name.Set(s == std::string::npos ? blobby.first : blobby.first.substr(s+1)); + } + + // give up blob ownership + blobs.clear(); + return master; + } + +public: + + // ------------------------------------------------------------------- + virtual bool Exists( const char* pFile) const { + return created.find(std::string(pFile)) != created.end(); + } + + + // ------------------------------------------------------------------- + virtual char getOsSeparator() const { + return '/'; + } + + + // ------------------------------------------------------------------- + virtual IOStream* Open(const char* pFile, + const char* pMode) + { + if (pMode[0] != 'w') { + return NULL; + } + + created.insert(std::string(pFile)); + return new BlobIOStream(this,std::string(pFile)); + } + + // ------------------------------------------------------------------- + virtual void Close( IOStream* pFile) + { + delete pFile; + } + +private: + + // ------------------------------------------------------------------- + void OnDestruct(const std::string& filename, BlobIOStream* child) + { + // we don't know in which the files are closed, so we + // can't reliably say that the first must be the master + // file ... + blobs.push_back( BlobEntry(filename,child->GetBlob()) ); + } + +private: + std::set created; + std::vector< BlobEntry > blobs; +}; + + +// -------------------------------------------------------------------------------------------- +BlobIOStream :: ~BlobIOStream() +{ + creator->OnDestruct(file,this); + delete[] buffer; +} + + +} // end Assimp + +#endif diff --git a/tools/ZAPD/ZAPD/assimp/ByteSwapper.h b/tools/ZAPD/ZAPD/assimp/ByteSwapper.h new file mode 100644 index 0000000000..20a2463fb8 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/ByteSwapper.h @@ -0,0 +1,287 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file Helper class tp perform various byte oder swappings + (e.g. little to big endian) */ +#ifndef AI_BYTESWAPPER_H_INC +#define AI_BYTESWAPPER_H_INC + +#include +#include +#include + +#if _MSC_VER >= 1400 +#include +#endif + +namespace Assimp { +// -------------------------------------------------------------------------------------- +/** Defines some useful byte order swap routines. + * + * This is required to read big-endian model formats on little-endian machines, + * and vice versa. Direct use of this class is DEPRECATED. Use #StreamReader instead. */ +// -------------------------------------------------------------------------------------- +class ByteSwap { + ByteSwap() AI_NO_EXCEPT {} + +public: + + // ---------------------------------------------------------------------- + /** Swap two bytes of data + * @param[inout] _szOut A void* to save the reintcasts for the caller. */ + static inline void Swap2(void* _szOut) + { + ai_assert(_szOut); + +#if _MSC_VER >= 1400 + uint16_t* const szOut = reinterpret_cast(_szOut); + *szOut = _byteswap_ushort(*szOut); +#else + uint8_t* const szOut = reinterpret_cast(_szOut); + std::swap(szOut[0],szOut[1]); +#endif + } + + // ---------------------------------------------------------------------- + /** Swap four bytes of data + * @param[inout] _szOut A void* to save the reintcasts for the caller. */ + static inline void Swap4(void* _szOut) + { + ai_assert(_szOut); + +#if _MSC_VER >= 1400 + uint32_t* const szOut = reinterpret_cast(_szOut); + *szOut = _byteswap_ulong(*szOut); +#else + uint8_t* const szOut = reinterpret_cast(_szOut); + std::swap(szOut[0],szOut[3]); + std::swap(szOut[1],szOut[2]); +#endif + } + + // ---------------------------------------------------------------------- + /** Swap eight bytes of data + * @param[inout] _szOut A void* to save the reintcasts for the caller. */ + static inline void Swap8(void* _szOut) + { + ai_assert(_szOut); + +#if _MSC_VER >= 1400 + uint64_t* const szOut = reinterpret_cast(_szOut); + *szOut = _byteswap_uint64(*szOut); +#else + uint8_t* const szOut = reinterpret_cast(_szOut); + std::swap(szOut[0],szOut[7]); + std::swap(szOut[1],szOut[6]); + std::swap(szOut[2],szOut[5]); + std::swap(szOut[3],szOut[4]); +#endif + } + + // ---------------------------------------------------------------------- + /** ByteSwap a float. Not a joke. + * @param[inout] fOut ehm. .. */ + static inline void Swap(float* fOut) { + Swap4(fOut); + } + + // ---------------------------------------------------------------------- + /** ByteSwap a double. Not a joke. + * @param[inout] fOut ehm. .. */ + static inline void Swap(double* fOut) { + Swap8(fOut); + } + + + // ---------------------------------------------------------------------- + /** ByteSwap an int16t. Not a joke. + * @param[inout] fOut ehm. .. */ + static inline void Swap(int16_t* fOut) { + Swap2(fOut); + } + + static inline void Swap(uint16_t* fOut) { + Swap2(fOut); + } + + // ---------------------------------------------------------------------- + /** ByteSwap an int32t. Not a joke. + * @param[inout] fOut ehm. .. */ + static inline void Swap(int32_t* fOut){ + Swap4(fOut); + } + + static inline void Swap(uint32_t* fOut){ + Swap4(fOut); + } + + // ---------------------------------------------------------------------- + /** ByteSwap an int64t. Not a joke. + * @param[inout] fOut ehm. .. */ + static inline void Swap(int64_t* fOut) { + Swap8(fOut); + } + + static inline void Swap(uint64_t* fOut) { + Swap8(fOut); + } + + // ---------------------------------------------------------------------- + //! Templatized ByteSwap + //! \returns param tOut as swapped + template + static inline Type Swapped(Type tOut) + { + return _swapper()(tOut); + } + +private: + + template struct _swapper; +}; + +template struct ByteSwap::_swapper { + T operator() (T tOut) { + Swap2(&tOut); + return tOut; + } +}; + +template struct ByteSwap::_swapper { + T operator() (T tOut) { + Swap4(&tOut); + return tOut; + } +}; + +template struct ByteSwap::_swapper { + T operator() (T tOut) { + Swap8(&tOut); + return tOut; + } +}; + + +// -------------------------------------------------------------------------------------- +// ByteSwap macros for BigEndian/LittleEndian support +// -------------------------------------------------------------------------------------- +#if (defined AI_BUILD_BIG_ENDIAN) +# define AI_LE(t) (t) +# define AI_BE(t) ByteSwap::Swapped(t) +# define AI_LSWAP2(p) +# define AI_LSWAP4(p) +# define AI_LSWAP8(p) +# define AI_LSWAP2P(p) +# define AI_LSWAP4P(p) +# define AI_LSWAP8P(p) +# define LE_NCONST const +# define AI_SWAP2(p) ByteSwap::Swap2(&(p)) +# define AI_SWAP4(p) ByteSwap::Swap4(&(p)) +# define AI_SWAP8(p) ByteSwap::Swap8(&(p)) +# define AI_SWAP2P(p) ByteSwap::Swap2((p)) +# define AI_SWAP4P(p) ByteSwap::Swap4((p)) +# define AI_SWAP8P(p) ByteSwap::Swap8((p)) +# define BE_NCONST +#else +# define AI_BE(t) (t) +# define AI_LE(t) ByteSwap::Swapped(t) +# define AI_SWAP2(p) +# define AI_SWAP4(p) +# define AI_SWAP8(p) +# define AI_SWAP2P(p) +# define AI_SWAP4P(p) +# define AI_SWAP8P(p) +# define BE_NCONST const +# define AI_LSWAP2(p) ByteSwap::Swap2(&(p)) +# define AI_LSWAP4(p) ByteSwap::Swap4(&(p)) +# define AI_LSWAP8(p) ByteSwap::Swap8(&(p)) +# define AI_LSWAP2P(p) ByteSwap::Swap2((p)) +# define AI_LSWAP4P(p) ByteSwap::Swap4((p)) +# define AI_LSWAP8P(p) ByteSwap::Swap8((p)) +# define LE_NCONST +#endif + + +namespace Intern { + +// -------------------------------------------------------------------------------------------- +template +struct ByteSwapper { + void operator() (T* inout) { + ByteSwap::Swap(inout); + } +}; + +template +struct ByteSwapper { + void operator() (T*) { + } +}; + +// -------------------------------------------------------------------------------------------- +template +struct Getter { + void operator() (T* inout, bool le) { +#ifdef AI_BUILD_BIG_ENDIAN + le = le; +#else + le = !le; +#endif + if (le) { + ByteSwapper1?true:false)> () (inout); + } + else ByteSwapper () (inout); + } +}; + +template +struct Getter { + + void operator() (T* inout, bool /*le*/) { + // static branch + ByteSwapper1)> () (inout); + } +}; +} // end Intern +} // end Assimp + +#endif //!! AI_BYTESWAPPER_H_INC diff --git a/tools/ZAPD/ZAPD/assimp/Compiler/poppack1.h b/tools/ZAPD/ZAPD/assimp/Compiler/poppack1.h new file mode 100644 index 0000000000..e033bc1472 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/Compiler/poppack1.h @@ -0,0 +1,22 @@ + +// =============================================================================== +// May be included multiple times - resets structure packing to the defaults +// for all supported compilers. Reverts the changes made by #include +// +// Currently this works on the following compilers: +// MSVC 7,8,9 +// GCC +// BORLAND (complains about 'pack state changed but not reverted', but works) +// =============================================================================== + +#ifndef AI_PUSHPACK_IS_DEFINED +# error pushpack1.h must be included after poppack1.h +#endif + +// reset packing to the original value +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( pop ) +#endif +#undef PACK_STRUCT + +#undef AI_PUSHPACK_IS_DEFINED diff --git a/tools/ZAPD/ZAPD/assimp/Compiler/pstdint.h b/tools/ZAPD/ZAPD/assimp/Compiler/pstdint.h new file mode 100644 index 0000000000..4de4ce2a90 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/Compiler/pstdint.h @@ -0,0 +1,912 @@ +/* A portable stdint.h + **************************************************************************** + * BSD License: + **************************************************************************** + * + * Copyright (c) 2005-2016 Paul Hsieh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************** + * + * Version 0.1.15.4 + * + * The ANSI C standard committee, for the C99 standard, specified the + * inclusion of a new standard include file called stdint.h. This is + * a very useful and long desired include file which contains several + * very precise definitions for integer scalar types that is + * critically important for making portable several classes of + * applications including cryptography, hashing, variable length + * integer libraries and so on. But for most developers its likely + * useful just for programming sanity. + * + * The problem is that some compiler vendors chose to ignore the C99 + * standard and some older compilers have no opportunity to be updated. + * Because of this situation, simply including stdint.h in your code + * makes it unportable. + * + * So that's what this file is all about. Its an attempt to build a + * single universal include file that works on as many platforms as + * possible to deliver what stdint.h is supposed to. Even compilers + * that already come with stdint.h can use this file instead without + * any loss of functionality. A few things that should be noted about + * this file: + * + * 1) It is not guaranteed to be portable and/or present an identical + * interface on all platforms. The extreme variability of the + * ANSI C standard makes this an impossibility right from the + * very get go. Its really only meant to be useful for the vast + * majority of platforms that possess the capability of + * implementing usefully and precisely defined, standard sized + * integer scalars. Systems which are not intrinsically 2s + * complement may produce invalid constants. + * + * 2) There is an unavoidable use of non-reserved symbols. + * + * 3) Other standard include files are invoked. + * + * 4) This file may come in conflict with future platforms that do + * include stdint.h. The hope is that one or the other can be + * used with no real difference. + * + * 5) In the current version, if your platform can't represent + * int32_t, int16_t and int8_t, it just dumps out with a compiler + * error. + * + * 6) 64 bit integers may or may not be defined. Test for their + * presence with the test: #ifdef INT64_MAX or #ifdef UINT64_MAX. + * Note that this is different from the C99 specification which + * requires the existence of 64 bit support in the compiler. If + * this is not defined for your platform, yet it is capable of + * dealing with 64 bits then it is because this file has not yet + * been extended to cover all of your system's capabilities. + * + * 7) (u)intptr_t may or may not be defined. Test for its presence + * with the test: #ifdef PTRDIFF_MAX. If this is not defined + * for your platform, then it is because this file has not yet + * been extended to cover all of your system's capabilities, not + * because its optional. + * + * 8) The following might not been defined even if your platform is + * capable of defining it: + * + * WCHAR_MIN + * WCHAR_MAX + * (u)int64_t + * PTRDIFF_MIN + * PTRDIFF_MAX + * (u)intptr_t + * + * 9) The following have not been defined: + * + * WINT_MIN + * WINT_MAX + * + * 10) The criteria for defining (u)int_least(*)_t isn't clear, + * except for systems which don't have a type that precisely + * defined 8, 16, or 32 bit types (which this include file does + * not support anyways). Default definitions have been given. + * + * 11) The criteria for defining (u)int_fast(*)_t isn't something I + * would trust to any particular compiler vendor or the ANSI C + * committee. It is well known that "compatible systems" are + * commonly created that have very different performance + * characteristics from the systems they are compatible with, + * especially those whose vendors make both the compiler and the + * system. Default definitions have been given, but its strongly + * recommended that users never use these definitions for any + * reason (they do *NOT* deliver any serious guarantee of + * improved performance -- not in this file, nor any vendor's + * stdint.h). + * + * 12) The following macros: + * + * PRINTF_INTMAX_MODIFIER + * PRINTF_INT64_MODIFIER + * PRINTF_INT32_MODIFIER + * PRINTF_INT16_MODIFIER + * PRINTF_LEAST64_MODIFIER + * PRINTF_LEAST32_MODIFIER + * PRINTF_LEAST16_MODIFIER + * PRINTF_INTPTR_MODIFIER + * + * are strings which have been defined as the modifiers required + * for the "d", "u" and "x" printf formats to correctly output + * (u)intmax_t, (u)int64_t, (u)int32_t, (u)int16_t, (u)least64_t, + * (u)least32_t, (u)least16_t and (u)intptr_t types respectively. + * PRINTF_INTPTR_MODIFIER is not defined for some systems which + * provide their own stdint.h. PRINTF_INT64_MODIFIER is not + * defined if INT64_MAX is not defined. These are an extension + * beyond what C99 specifies must be in stdint.h. + * + * In addition, the following macros are defined: + * + * PRINTF_INTMAX_HEX_WIDTH + * PRINTF_INT64_HEX_WIDTH + * PRINTF_INT32_HEX_WIDTH + * PRINTF_INT16_HEX_WIDTH + * PRINTF_INT8_HEX_WIDTH + * PRINTF_INTMAX_DEC_WIDTH + * PRINTF_INT64_DEC_WIDTH + * PRINTF_INT32_DEC_WIDTH + * PRINTF_INT16_DEC_WIDTH + * PRINTF_UINT8_DEC_WIDTH + * PRINTF_UINTMAX_DEC_WIDTH + * PRINTF_UINT64_DEC_WIDTH + * PRINTF_UINT32_DEC_WIDTH + * PRINTF_UINT16_DEC_WIDTH + * PRINTF_UINT8_DEC_WIDTH + * + * Which specifies the maximum number of characters required to + * print the number of that type in either hexadecimal or decimal. + * These are an extension beyond what C99 specifies must be in + * stdint.h. + * + * Compilers tested (all with 0 warnings at their highest respective + * settings): Borland Turbo C 2.0, WATCOM C/C++ 11.0 (16 bits and 32 + * bits), Microsoft Visual C++ 6.0 (32 bit), Microsoft Visual Studio + * .net (VC7), Intel C++ 4.0, GNU gcc v3.3.3 + * + * This file should be considered a work in progress. Suggestions for + * improvements, especially those which increase coverage are strongly + * encouraged. + * + * Acknowledgements + * + * The following people have made significant contributions to the + * development and testing of this file: + * + * Chris Howie + * John Steele Scott + * Dave Thorup + * John Dill + * Florian Wobbe + * Christopher Sean Morrison + * Mikkel Fahnoe Jorgensen + * + */ + +#include +#include +#include + +/* + * For gcc with _STDINT_H, fill in the PRINTF_INT*_MODIFIER macros, and + * do nothing else. On the Mac OS X version of gcc this is _STDINT_H_. + */ + +#if ((defined(__SUNPRO_C) && __SUNPRO_C >= 0x570) || (defined(_MSC_VER) && _MSC_VER >= 1600) || (defined(__STDC__) && __STDC__ && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (__GNUC__ > 3 || defined(_STDINT_H) || defined(_STDINT_H_) || defined (__UINT_FAST64_TYPE__)) )) && !defined (_PSTDINT_H_INCLUDED) +#include +#define _PSTDINT_H_INCLUDED +# if defined(__GNUC__) && (defined(__x86_64__) || defined(__ppc64__)) && !(defined(__APPLE__) && defined(__MACH__)) +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "l" +# endif +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "" +# endif +# else +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "ll" +# endif +# ifndef PRINTF_INT32_MODIFIER +# if (UINT_MAX == UINT32_MAX) +# define PRINTF_INT32_MODIFIER "" +# else +# define PRINTF_INT32_MODIFIER "l" +# endif +# endif +# endif +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "h" +# endif +# ifndef PRINTF_INTMAX_MODIFIER +# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER +# endif +# ifndef PRINTF_INT64_HEX_WIDTH +# define PRINTF_INT64_HEX_WIDTH "16" +# endif +# ifndef PRINTF_UINT64_HEX_WIDTH +# define PRINTF_UINT64_HEX_WIDTH "16" +# endif +# ifndef PRINTF_INT32_HEX_WIDTH +# define PRINTF_INT32_HEX_WIDTH "8" +# endif +# ifndef PRINTF_UINT32_HEX_WIDTH +# define PRINTF_UINT32_HEX_WIDTH "8" +# endif +# ifndef PRINTF_INT16_HEX_WIDTH +# define PRINTF_INT16_HEX_WIDTH "4" +# endif +# ifndef PRINTF_UINT16_HEX_WIDTH +# define PRINTF_UINT16_HEX_WIDTH "4" +# endif +# ifndef PRINTF_INT8_HEX_WIDTH +# define PRINTF_INT8_HEX_WIDTH "2" +# endif +# ifndef PRINTF_UINT8_HEX_WIDTH +# define PRINTF_UINT8_HEX_WIDTH "2" +# endif +# ifndef PRINTF_INT64_DEC_WIDTH +# define PRINTF_INT64_DEC_WIDTH "19" +# endif +# ifndef PRINTF_UINT64_DEC_WIDTH +# define PRINTF_UINT64_DEC_WIDTH "20" +# endif +# ifndef PRINTF_INT32_DEC_WIDTH +# define PRINTF_INT32_DEC_WIDTH "10" +# endif +# ifndef PRINTF_UINT32_DEC_WIDTH +# define PRINTF_UINT32_DEC_WIDTH "10" +# endif +# ifndef PRINTF_INT16_DEC_WIDTH +# define PRINTF_INT16_DEC_WIDTH "5" +# endif +# ifndef PRINTF_UINT16_DEC_WIDTH +# define PRINTF_UINT16_DEC_WIDTH "5" +# endif +# ifndef PRINTF_INT8_DEC_WIDTH +# define PRINTF_INT8_DEC_WIDTH "3" +# endif +# ifndef PRINTF_UINT8_DEC_WIDTH +# define PRINTF_UINT8_DEC_WIDTH "3" +# endif +# ifndef PRINTF_INTMAX_HEX_WIDTH +# define PRINTF_INTMAX_HEX_WIDTH PRINTF_UINT64_HEX_WIDTH +# endif +# ifndef PRINTF_UINTMAX_HEX_WIDTH +# define PRINTF_UINTMAX_HEX_WIDTH PRINTF_UINT64_HEX_WIDTH +# endif +# ifndef PRINTF_INTMAX_DEC_WIDTH +# define PRINTF_INTMAX_DEC_WIDTH PRINTF_UINT64_DEC_WIDTH +# endif +# ifndef PRINTF_UINTMAX_DEC_WIDTH +# define PRINTF_UINTMAX_DEC_WIDTH PRINTF_UINT64_DEC_WIDTH +# endif + +/* + * Something really weird is going on with Open Watcom. Just pull some of + * these duplicated definitions from Open Watcom's stdint.h file for now. + */ + +# if defined (__WATCOMC__) && __WATCOMC__ >= 1250 +# if !defined (INT64_C) +# define INT64_C(x) (x + (INT64_MAX - INT64_MAX)) +# endif +# if !defined (UINT64_C) +# define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX)) +# endif +# if !defined (INT32_C) +# define INT32_C(x) (x + (INT32_MAX - INT32_MAX)) +# endif +# if !defined (UINT32_C) +# define UINT32_C(x) (x + (UINT32_MAX - UINT32_MAX)) +# endif +# if !defined (INT16_C) +# define INT16_C(x) (x) +# endif +# if !defined (UINT16_C) +# define UINT16_C(x) (x) +# endif +# if !defined (INT8_C) +# define INT8_C(x) (x) +# endif +# if !defined (UINT8_C) +# define UINT8_C(x) (x) +# endif +# if !defined (UINT64_MAX) +# define UINT64_MAX 18446744073709551615ULL +# endif +# if !defined (INT64_MAX) +# define INT64_MAX 9223372036854775807LL +# endif +# if !defined (UINT32_MAX) +# define UINT32_MAX 4294967295UL +# endif +# if !defined (INT32_MAX) +# define INT32_MAX 2147483647L +# endif +# if !defined (INTMAX_MAX) +# define INTMAX_MAX INT64_MAX +# endif +# if !defined (INTMAX_MIN) +# define INTMAX_MIN INT64_MIN +# endif +# endif +#endif + +/* + * I have no idea what is the truly correct thing to do on older Solaris. + * From some online discussions, this seems to be what is being + * recommended. For people who actually are developing on older Solaris, + * what I would like to know is, does this define all of the relevant + * macros of a complete stdint.h? Remember, in pstdint.h 64 bit is + * considered optional. + */ + +#if (defined(__SUNPRO_C) && __SUNPRO_C >= 0x420) && !defined(_PSTDINT_H_INCLUDED) +#include +#define _PSTDINT_H_INCLUDED +#endif + +#ifndef _PSTDINT_H_INCLUDED +#define _PSTDINT_H_INCLUDED + +#ifndef SIZE_MAX +# define SIZE_MAX (~(size_t)0) +#endif + +/* + * Deduce the type assignments from limits.h under the assumption that + * integer sizes in bits are powers of 2, and follow the ANSI + * definitions. + */ + +#ifndef UINT8_MAX +# define UINT8_MAX 0xff +#endif +#if !defined(uint8_t) && !defined(_UINT8_T) && !defined(vxWorks) +# if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S) + typedef unsigned char uint8_t; +# define UINT8_C(v) ((uint8_t) v) +# else +# error "Platform not supported" +# endif +#endif + +#ifndef INT8_MAX +# define INT8_MAX 0x7f +#endif +#ifndef INT8_MIN +# define INT8_MIN INT8_C(0x80) +#endif +#if !defined(int8_t) && !defined(_INT8_T) && !defined(vxWorks) +# if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S) + typedef signed char int8_t; +# define INT8_C(v) ((int8_t) v) +# else +# error "Platform not supported" +# endif +#endif + +#ifndef UINT16_MAX +# define UINT16_MAX 0xffff +#endif +#if !defined(uint16_t) && !defined(_UINT16_T) && !defined(vxWorks) +#if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S) + typedef unsigned int uint16_t; +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "" +# endif +# define UINT16_C(v) ((uint16_t) (v)) +#elif (USHRT_MAX == UINT16_MAX) + typedef unsigned short uint16_t; +# define UINT16_C(v) ((uint16_t) (v)) +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "h" +# endif +#else +#error "Platform not supported" +#endif +#endif + +#ifndef INT16_MAX +# define INT16_MAX 0x7fff +#endif +#ifndef INT16_MIN +# define INT16_MIN INT16_C(0x8000) +#endif +#if !defined(int16_t) && !defined(_INT16_T) && !defined(vxWorks) +#if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S) + typedef signed int int16_t; +# define INT16_C(v) ((int16_t) (v)) +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "" +# endif +#elif (SHRT_MAX == INT16_MAX) + typedef signed short int16_t; +# define INT16_C(v) ((int16_t) (v)) +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "h" +# endif +#else +#error "Platform not supported" +#endif +#endif + +#ifndef UINT32_MAX +# define UINT32_MAX (0xffffffffUL) +#endif +#if !defined(uint32_t) && !defined(_UINT32_T) && !defined(vxWorks) +#if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S) + typedef unsigned long uint32_t; +# define UINT32_C(v) v ## UL +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "l" +# endif +#elif (UINT_MAX == UINT32_MAX) + typedef unsigned int uint32_t; +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "" +# endif +# define UINT32_C(v) v ## U +#elif (USHRT_MAX == UINT32_MAX) + typedef unsigned short uint32_t; +# define UINT32_C(v) ((unsigned short) (v)) +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "" +# endif +#else +#error "Platform not supported" +#endif +#endif + +#ifndef INT32_MAX +# define INT32_MAX (0x7fffffffL) +#endif +#ifndef INT32_MIN +# define INT32_MIN INT32_C(0x80000000) +#endif +#if !defined(int32_t) && !defined(_INT32_T) && !defined(vxWorks) +#if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S) + typedef signed long int32_t; +# define INT32_C(v) v ## L +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "l" +# endif +#elif (INT_MAX == INT32_MAX) + typedef signed int int32_t; +# define INT32_C(v) v +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "" +# endif +#elif (SHRT_MAX == INT32_MAX) + typedef signed short int32_t; +# define INT32_C(v) ((short) (v)) +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "" +# endif +#else +#error "Platform not supported" +#endif +#endif + +/* + * The macro stdint_int64_defined is temporarily used to record + * whether or not 64 integer support is available. It must be + * defined for any 64 integer extensions for new platforms that are + * added. + */ + +#undef stdint_int64_defined +#if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S) +# if (__STDC__ && __STDC_VERSION__ >= 199901L) || defined (S_SPLINT_S) +# define stdint_int64_defined + typedef long long int64_t; + typedef unsigned long long uint64_t; +# define UINT64_C(v) v ## ULL +# define INT64_C(v) v ## LL +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "ll" +# endif +# endif +#endif + +#if !defined (stdint_int64_defined) +# if defined(__GNUC__) && !defined(vxWorks) +# define stdint_int64_defined + __extension__ typedef long long int64_t; + __extension__ typedef unsigned long long uint64_t; +# define UINT64_C(v) v ## ULL +# define INT64_C(v) v ## LL +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "ll" +# endif +# elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S) +# define stdint_int64_defined + typedef long long int64_t; + typedef unsigned long long uint64_t; +# define UINT64_C(v) v ## ULL +# define INT64_C(v) v ## LL +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "ll" +# endif +# elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC) +# define stdint_int64_defined + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; +# define UINT64_C(v) v ## UI64 +# define INT64_C(v) v ## I64 +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "I64" +# endif +# endif +#endif + +#if !defined (LONG_LONG_MAX) && defined (INT64_C) +# define LONG_LONG_MAX INT64_C (9223372036854775807) +#endif +#ifndef ULONG_LONG_MAX +# define ULONG_LONG_MAX UINT64_C (18446744073709551615) +#endif + +#if !defined (INT64_MAX) && defined (INT64_C) +# define INT64_MAX INT64_C (9223372036854775807) +#endif +#if !defined (INT64_MIN) && defined (INT64_C) +# define INT64_MIN INT64_C (-9223372036854775808) +#endif +#if !defined (UINT64_MAX) && defined (INT64_C) +# define UINT64_MAX UINT64_C (18446744073709551615) +#endif + +/* + * Width of hexadecimal for number field. + */ + +#ifndef PRINTF_INT64_HEX_WIDTH +# define PRINTF_INT64_HEX_WIDTH "16" +#endif +#ifndef PRINTF_INT32_HEX_WIDTH +# define PRINTF_INT32_HEX_WIDTH "8" +#endif +#ifndef PRINTF_INT16_HEX_WIDTH +# define PRINTF_INT16_HEX_WIDTH "4" +#endif +#ifndef PRINTF_INT8_HEX_WIDTH +# define PRINTF_INT8_HEX_WIDTH "2" +#endif +#ifndef PRINTF_INT64_DEC_WIDTH +# define PRINTF_INT64_DEC_WIDTH "19" +#endif +#ifndef PRINTF_INT32_DEC_WIDTH +# define PRINTF_INT32_DEC_WIDTH "10" +#endif +#ifndef PRINTF_INT16_DEC_WIDTH +# define PRINTF_INT16_DEC_WIDTH "5" +#endif +#ifndef PRINTF_INT8_DEC_WIDTH +# define PRINTF_INT8_DEC_WIDTH "3" +#endif +#ifndef PRINTF_UINT64_DEC_WIDTH +# define PRINTF_UINT64_DEC_WIDTH "20" +#endif +#ifndef PRINTF_UINT32_DEC_WIDTH +# define PRINTF_UINT32_DEC_WIDTH "10" +#endif +#ifndef PRINTF_UINT16_DEC_WIDTH +# define PRINTF_UINT16_DEC_WIDTH "5" +#endif +#ifndef PRINTF_UINT8_DEC_WIDTH +# define PRINTF_UINT8_DEC_WIDTH "3" +#endif + +/* + * Ok, lets not worry about 128 bit integers for now. Moore's law says + * we don't need to worry about that until about 2040 at which point + * we'll have bigger things to worry about. + */ + +#ifdef stdint_int64_defined + typedef int64_t intmax_t; + typedef uint64_t uintmax_t; +# define INTMAX_MAX INT64_MAX +# define INTMAX_MIN INT64_MIN +# define UINTMAX_MAX UINT64_MAX +# define UINTMAX_C(v) UINT64_C(v) +# define INTMAX_C(v) INT64_C(v) +# ifndef PRINTF_INTMAX_MODIFIER +# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER +# endif +# ifndef PRINTF_INTMAX_HEX_WIDTH +# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH +# endif +# ifndef PRINTF_INTMAX_DEC_WIDTH +# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH +# endif +#else + typedef int32_t intmax_t; + typedef uint32_t uintmax_t; +# define INTMAX_MAX INT32_MAX +# define UINTMAX_MAX UINT32_MAX +# define UINTMAX_C(v) UINT32_C(v) +# define INTMAX_C(v) INT32_C(v) +# ifndef PRINTF_INTMAX_MODIFIER +# define PRINTF_INTMAX_MODIFIER PRINTF_INT32_MODIFIER +# endif +# ifndef PRINTF_INTMAX_HEX_WIDTH +# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT32_HEX_WIDTH +# endif +# ifndef PRINTF_INTMAX_DEC_WIDTH +# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT32_DEC_WIDTH +# endif +#endif + +/* + * Because this file currently only supports platforms which have + * precise powers of 2 as bit sizes for the default integers, the + * least definitions are all trivial. Its possible that a future + * version of this file could have different definitions. + */ + +#ifndef stdint_least_defined + typedef int8_t int_least8_t; + typedef uint8_t uint_least8_t; + typedef int16_t int_least16_t; + typedef uint16_t uint_least16_t; + typedef int32_t int_least32_t; + typedef uint32_t uint_least32_t; +# define PRINTF_LEAST32_MODIFIER PRINTF_INT32_MODIFIER +# define PRINTF_LEAST16_MODIFIER PRINTF_INT16_MODIFIER +# define UINT_LEAST8_MAX UINT8_MAX +# define INT_LEAST8_MAX INT8_MAX +# define UINT_LEAST16_MAX UINT16_MAX +# define INT_LEAST16_MAX INT16_MAX +# define UINT_LEAST32_MAX UINT32_MAX +# define INT_LEAST32_MAX INT32_MAX +# define INT_LEAST8_MIN INT8_MIN +# define INT_LEAST16_MIN INT16_MIN +# define INT_LEAST32_MIN INT32_MIN +# ifdef stdint_int64_defined + typedef int64_t int_least64_t; + typedef uint64_t uint_least64_t; +# define PRINTF_LEAST64_MODIFIER PRINTF_INT64_MODIFIER +# define UINT_LEAST64_MAX UINT64_MAX +# define INT_LEAST64_MAX INT64_MAX +# define INT_LEAST64_MIN INT64_MIN +# endif +#endif +#undef stdint_least_defined + +/* + * The ANSI C committee pretending to know or specify anything about + * performance is the epitome of misguided arrogance. The mandate of + * this file is to *ONLY* ever support that absolute minimum + * definition of the fast integer types, for compatibility purposes. + * No extensions, and no attempt to suggest what may or may not be a + * faster integer type will ever be made in this file. Developers are + * warned to stay away from these types when using this or any other + * stdint.h. + */ + +typedef int_least8_t int_fast8_t; +typedef uint_least8_t uint_fast8_t; +typedef int_least16_t int_fast16_t; +typedef uint_least16_t uint_fast16_t; +typedef int_least32_t int_fast32_t; +typedef uint_least32_t uint_fast32_t; +#define UINT_FAST8_MAX UINT_LEAST8_MAX +#define INT_FAST8_MAX INT_LEAST8_MAX +#define UINT_FAST16_MAX UINT_LEAST16_MAX +#define INT_FAST16_MAX INT_LEAST16_MAX +#define UINT_FAST32_MAX UINT_LEAST32_MAX +#define INT_FAST32_MAX INT_LEAST32_MAX +#define INT_FAST8_MIN INT_LEAST8_MIN +#define INT_FAST16_MIN INT_LEAST16_MIN +#define INT_FAST32_MIN INT_LEAST32_MIN +#ifdef stdint_int64_defined + typedef int_least64_t int_fast64_t; + typedef uint_least64_t uint_fast64_t; +# define UINT_FAST64_MAX UINT_LEAST64_MAX +# define INT_FAST64_MAX INT_LEAST64_MAX +# define INT_FAST64_MIN INT_LEAST64_MIN +#endif + +#undef stdint_int64_defined + +/* + * Whatever piecemeal, per compiler thing we can do about the wchar_t + * type limits. + */ + +#if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__) && !defined(vxWorks) +# include +# ifndef WCHAR_MIN +# define WCHAR_MIN 0 +# endif +# ifndef WCHAR_MAX +# define WCHAR_MAX ((wchar_t)-1) +# endif +#endif + +/* + * Whatever piecemeal, per compiler/platform thing we can do about the + * (u)intptr_t types and limits. + */ + +#if (defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED)) || defined (_UINTPTR_T) +# define STDINT_H_UINTPTR_T_DEFINED +#endif + +#ifndef STDINT_H_UINTPTR_T_DEFINED +# if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64) || defined (__ppc64__) +# define stdint_intptr_bits 64 +# elif defined (__WATCOMC__) || defined (__TURBOC__) +# if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__) +# define stdint_intptr_bits 16 +# else +# define stdint_intptr_bits 32 +# endif +# elif defined (__i386__) || defined (_WIN32) || defined (WIN32) || defined (__ppc64__) +# define stdint_intptr_bits 32 +# elif defined (__INTEL_COMPILER) +/* TODO -- what did Intel do about x86-64? */ +# else +/* #error "This platform might not be supported yet" */ +# endif + +# ifdef stdint_intptr_bits +# define stdint_intptr_glue3_i(a,b,c) a##b##c +# define stdint_intptr_glue3(a,b,c) stdint_intptr_glue3_i(a,b,c) +# ifndef PRINTF_INTPTR_MODIFIER +# define PRINTF_INTPTR_MODIFIER stdint_intptr_glue3(PRINTF_INT,stdint_intptr_bits,_MODIFIER) +# endif +# ifndef PTRDIFF_MAX +# define PTRDIFF_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX) +# endif +# ifndef PTRDIFF_MIN +# define PTRDIFF_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN) +# endif +# ifndef UINTPTR_MAX +# define UINTPTR_MAX stdint_intptr_glue3(UINT,stdint_intptr_bits,_MAX) +# endif +# ifndef INTPTR_MAX +# define INTPTR_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX) +# endif +# ifndef INTPTR_MIN +# define INTPTR_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN) +# endif +# ifndef INTPTR_C +# define INTPTR_C(x) stdint_intptr_glue3(INT,stdint_intptr_bits,_C)(x) +# endif +# ifndef UINTPTR_C +# define UINTPTR_C(x) stdint_intptr_glue3(UINT,stdint_intptr_bits,_C)(x) +# endif + typedef stdint_intptr_glue3(uint,stdint_intptr_bits,_t) uintptr_t; + typedef stdint_intptr_glue3( int,stdint_intptr_bits,_t) intptr_t; +# else +/* TODO -- This following is likely wrong for some platforms, and does + nothing for the definition of uintptr_t. */ + typedef ptrdiff_t intptr_t; +# endif +# define STDINT_H_UINTPTR_T_DEFINED +#endif + +/* + * Assumes sig_atomic_t is signed and we have a 2s complement machine. + */ + +#ifndef SIG_ATOMIC_MAX +# define SIG_ATOMIC_MAX ((((sig_atomic_t) 1) << (sizeof (sig_atomic_t)*CHAR_BIT-1)) - 1) +#endif + +#endif + +#if defined (__TEST_PSTDINT_FOR_CORRECTNESS) + +/* + * Please compile with the maximum warning settings to make sure macros are + * not defined more than once. + */ + +#include +#include +#include + +#define glue3_aux(x,y,z) x ## y ## z +#define glue3(x,y,z) glue3_aux(x,y,z) + +#define DECLU(bits) glue3(uint,bits,_t) glue3(u,bits,) = glue3(UINT,bits,_C) (0); +#define DECLI(bits) glue3(int,bits,_t) glue3(i,bits,) = glue3(INT,bits,_C) (0); + +#define DECL(us,bits) glue3(DECL,us,) (bits) + +#define TESTUMAX(bits) glue3(u,bits,) = ~glue3(u,bits,); if (glue3(UINT,bits,_MAX) != glue3(u,bits,)) printf ("Something wrong with UINT%d_MAX\n", bits) + +#define REPORTERROR(msg) { err_n++; if (err_first <= 0) err_first = __LINE__; printf msg; } + +int main () { + int err_n = 0; + int err_first = 0; + DECL(I,8) + DECL(U,8) + DECL(I,16) + DECL(U,16) + DECL(I,32) + DECL(U,32) +#ifdef INT64_MAX + DECL(I,64) + DECL(U,64) +#endif + intmax_t imax = INTMAX_C(0); + uintmax_t umax = UINTMAX_C(0); + char str0[256], str1[256]; + + sprintf (str0, "%" PRINTF_INT32_MODIFIER "d", INT32_C(2147483647)); + if (0 != strcmp (str0, "2147483647")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str0)); + if (atoi(PRINTF_INT32_DEC_WIDTH) != (int) strlen(str0)) REPORTERROR (("Something wrong with PRINTF_INT32_DEC_WIDTH : %s\n", PRINTF_INT32_DEC_WIDTH)); + sprintf (str0, "%" PRINTF_INT32_MODIFIER "u", UINT32_C(4294967295)); + if (0 != strcmp (str0, "4294967295")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str0)); + if (atoi(PRINTF_UINT32_DEC_WIDTH) != (int) strlen(str0)) REPORTERROR (("Something wrong with PRINTF_UINT32_DEC_WIDTH : %s\n", PRINTF_UINT32_DEC_WIDTH)); +#ifdef INT64_MAX + sprintf (str1, "%" PRINTF_INT64_MODIFIER "d", INT64_C(9223372036854775807)); + if (0 != strcmp (str1, "9223372036854775807")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str1)); + if (atoi(PRINTF_INT64_DEC_WIDTH) != (int) strlen(str1)) REPORTERROR (("Something wrong with PRINTF_INT64_DEC_WIDTH : %s, %d\n", PRINTF_INT64_DEC_WIDTH, (int) strlen(str1))); + sprintf (str1, "%" PRINTF_INT64_MODIFIER "u", UINT64_C(18446744073709550591)); + if (0 != strcmp (str1, "18446744073709550591")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str1)); + if (atoi(PRINTF_UINT64_DEC_WIDTH) != (int) strlen(str1)) REPORTERROR (("Something wrong with PRINTF_UINT64_DEC_WIDTH : %s, %d\n", PRINTF_UINT64_DEC_WIDTH, (int) strlen(str1))); +#endif + + sprintf (str0, "%d %x\n", 0, ~0); + + sprintf (str1, "%d %x\n", i8, ~0); + if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i8 : %s\n", str1)); + sprintf (str1, "%u %x\n", u8, ~0); + if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u8 : %s\n", str1)); + sprintf (str1, "%d %x\n", i16, ~0); + if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i16 : %s\n", str1)); + sprintf (str1, "%u %x\n", u16, ~0); + if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u16 : %s\n", str1)); + sprintf (str1, "%" PRINTF_INT32_MODIFIER "d %x\n", i32, ~0); + if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i32 : %s\n", str1)); + sprintf (str1, "%" PRINTF_INT32_MODIFIER "u %x\n", u32, ~0); + if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u32 : %s\n", str1)); +#ifdef INT64_MAX + sprintf (str1, "%" PRINTF_INT64_MODIFIER "d %x\n", i64, ~0); + if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i64 : %s\n", str1)); +#endif + sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "d %x\n", imax, ~0); + if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with imax : %s\n", str1)); + sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "u %x\n", umax, ~0); + if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with umax : %s\n", str1)); + + TESTUMAX(8); + TESTUMAX(16); + TESTUMAX(32); +#ifdef INT64_MAX + TESTUMAX(64); +#endif + +#define STR(v) #v +#define Q(v) printf ("sizeof " STR(v) " = %u\n", (unsigned) sizeof (v)); + if (err_n) { + printf ("pstdint.h is not correct. Please use sizes below to correct it:\n"); + } + + Q(int) + Q(unsigned) + Q(long int) + Q(short int) + Q(int8_t) + Q(int16_t) + Q(int32_t) +#ifdef INT64_MAX + Q(int64_t) +#endif + + return EXIT_SUCCESS; +} + +#endif diff --git a/tools/ZAPD/ZAPD/assimp/Compiler/pushpack1.h b/tools/ZAPD/ZAPD/assimp/Compiler/pushpack1.h new file mode 100644 index 0000000000..4c9fbb857f --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/Compiler/pushpack1.h @@ -0,0 +1,43 @@ + + +// =============================================================================== +// May be included multiple times - sets structure packing to 1 +// for all supported compilers. #include reverts the changes. +// +// Currently this works on the following compilers: +// MSVC 7,8,9 +// GCC +// BORLAND (complains about 'pack state changed but not reverted', but works) +// Clang +// +// +// USAGE: +// +// struct StructToBePacked { +// } PACK_STRUCT; +// +// =============================================================================== + +#ifdef AI_PUSHPACK_IS_DEFINED +# error poppack1.h must be included after pushpack1.h +#endif + +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack(push,1) +# define PACK_STRUCT +#elif defined( __GNUC__ ) || defined(__clang__) +# if !defined(HOST_MINGW) +# define PACK_STRUCT __attribute__((__packed__)) +# else +# define PACK_STRUCT __attribute__((gcc_struct, __packed__)) +# endif +#else +# error Compiler not supported +#endif + +#if defined(_MSC_VER) +// C4103: Packing was changed after the inclusion of the header, probably missing #pragma pop +# pragma warning (disable : 4103) +#endif + +#define AI_PUSHPACK_IS_DEFINED diff --git a/tools/ZAPD/ZAPD/assimp/CreateAnimMesh.h b/tools/ZAPD/ZAPD/assimp/CreateAnimMesh.h new file mode 100644 index 0000000000..a60173588f --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/CreateAnimMesh.h @@ -0,0 +1,58 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file CreateAnimMesh.h + * Create AnimMesh from Mesh + */ +#ifndef INCLUDED_AI_CREATE_ANIM_MESH_H +#define INCLUDED_AI_CREATE_ANIM_MESH_H + +#include + +namespace Assimp { + +/** Create aiAnimMesh from aiMesh. */ +ASSIMP_API aiAnimMesh *aiCreateAnimMesh(const aiMesh *mesh); + +} // end of namespace Assimp +#endif // INCLUDED_AI_CREATE_ANIM_MESH_H + diff --git a/tools/ZAPD/ZAPD/assimp/DefaultIOStream.h b/tools/ZAPD/ZAPD/assimp/DefaultIOStream.h new file mode 100644 index 0000000000..994d728ff5 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/DefaultIOStream.h @@ -0,0 +1,140 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file Default file I/O using fXXX()-family of functions */ +#ifndef AI_DEFAULTIOSTREAM_H_INC +#define AI_DEFAULTIOSTREAM_H_INC + +#include +#include +#include +#include + +namespace Assimp { + +// ---------------------------------------------------------------------------------- +//! @class DefaultIOStream +//! @brief Default IO implementation, use standard IO operations +//! @note An instance of this class can exist without a valid file handle +//! attached to it. All calls fail, but the instance can nevertheless be +//! used with no restrictions. +class ASSIMP_API DefaultIOStream : public IOStream +{ + friend class DefaultIOSystem; +#if __ANDROID__ +# if __ANDROID_API__ > 9 +# if defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT) + friend class AndroidJNIIOSystem; +# endif // defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT) +# endif // __ANDROID_API__ > 9 +#endif // __ANDROID__ + +protected: + DefaultIOStream() AI_NO_EXCEPT; + DefaultIOStream(FILE* pFile, const std::string &strFilename); + +public: + /** Destructor public to allow simple deletion to close the file. */ + ~DefaultIOStream (); + + // ------------------------------------------------------------------- + /// Read from stream + size_t Read(void* pvBuffer, + size_t pSize, + size_t pCount); + + + // ------------------------------------------------------------------- + /// Write to stream + size_t Write(const void* pvBuffer, + size_t pSize, + size_t pCount); + + // ------------------------------------------------------------------- + /// Seek specific position + aiReturn Seek(size_t pOffset, + aiOrigin pOrigin); + + // ------------------------------------------------------------------- + /// Get current seek position + size_t Tell() const; + + // ------------------------------------------------------------------- + /// Get size of file + size_t FileSize() const; + + // ------------------------------------------------------------------- + /// Flush file contents + void Flush(); + +private: + // File data-structure, using clib + FILE* mFile; + // Filename + std::string mFilename; + // Cached file size + mutable size_t mCachedSize; +}; + +// ---------------------------------------------------------------------------------- +inline +DefaultIOStream::DefaultIOStream() AI_NO_EXCEPT +: mFile(nullptr) +, mFilename("") +, mCachedSize(SIZE_MAX) { + // empty +} + +// ---------------------------------------------------------------------------------- +inline +DefaultIOStream::DefaultIOStream (FILE* pFile, const std::string &strFilename) +: mFile(pFile) +, mFilename(strFilename) +, mCachedSize(SIZE_MAX) { + // empty +} +// ---------------------------------------------------------------------------------- + +} // ns assimp + +#endif //!!AI_DEFAULTIOSTREAM_H_INC + diff --git a/tools/ZAPD/ZAPD/assimp/DefaultIOSystem.h b/tools/ZAPD/ZAPD/assimp/DefaultIOSystem.h new file mode 100644 index 0000000000..2dd5c801b5 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/DefaultIOSystem.h @@ -0,0 +1,93 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file Default implementation of IOSystem using the standard C file functions */ +#ifndef AI_DEFAULTIOSYSTEM_H_INC +#define AI_DEFAULTIOSYSTEM_H_INC + +#include + +namespace Assimp { + +// --------------------------------------------------------------------------- +/** Default implementation of IOSystem using the standard C file functions */ +class ASSIMP_API DefaultIOSystem : public IOSystem { +public: + // ------------------------------------------------------------------- + /** Tests for the existence of a file at the given path. */ + bool Exists( const char* pFile) const; + + // ------------------------------------------------------------------- + /** Returns the directory separator. */ + char getOsSeparator() const; + + // ------------------------------------------------------------------- + /** Open a new file with a given path. */ + IOStream* Open( const char* pFile, const char* pMode = "rb"); + + // ------------------------------------------------------------------- + /** Closes the given file and releases all resources associated with it. */ + void Close( IOStream* pFile); + + // ------------------------------------------------------------------- + /** Compare two paths */ + bool ComparePaths (const char* one, const char* second) const; + + /** @brief get the file name of a full filepath + * example: /tmp/archive.tar.gz -> archive.tar.gz + */ + static std::string fileName( const std::string &path ); + + /** @brief get the complete base name of a full filepath + * example: /tmp/archive.tar.gz -> archive.tar + */ + static std::string completeBaseName( const std::string &path); + + /** @brief get the path of a full filepath + * example: /tmp/archive.tar.gz -> /tmp/ + */ + static std::string absolutePath( const std::string &path); +}; + +} //!ns Assimp + +#endif //AI_DEFAULTIOSYSTEM_H_INC diff --git a/tools/ZAPD/ZAPD/assimp/DefaultLogger.hpp b/tools/ZAPD/ZAPD/assimp/DefaultLogger.hpp new file mode 100644 index 0000000000..1946e250a6 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/DefaultLogger.hpp @@ -0,0 +1,188 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ +/** @file DefaultLogger.hpp +*/ + +#ifndef INCLUDED_AI_DEFAULTLOGGER +#define INCLUDED_AI_DEFAULTLOGGER + +#include "Logger.hpp" +#include "LogStream.hpp" +#include "NullLogger.hpp" +#include + +namespace Assimp { +// ------------------------------------------------------------------------------------ +class IOStream; +struct LogStreamInfo; + +/** default name of logfile */ +#define ASSIMP_DEFAULT_LOG_NAME "AssimpLog.txt" + +// ------------------------------------------------------------------------------------ +/** @brief CPP-API: Primary logging facility of Assimp. + * + * The library stores its primary #Logger as a static member of this class. + * #get() returns this primary logger. By default the underlying implementation is + * just a #NullLogger which rejects all log messages. By calling #create(), logging + * is turned on. To capture the log output multiple log streams (#LogStream) can be + * attach to the logger. Some default streams for common streaming locations (such as + * a file, std::cout, OutputDebugString()) are also provided. + * + * If you wish to customize the logging at an even deeper level supply your own + * implementation of #Logger to #set(). + * @note The whole logging stuff causes a small extra overhead for all imports. */ +class ASSIMP_API DefaultLogger : + public Logger { + +public: + + // ---------------------------------------------------------------------- + /** @brief Creates a logging instance. + * @param name Name for log file. Only valid in combination + * with the aiDefaultLogStream_FILE flag. + * @param severity Log severity, VERBOSE turns on debug messages + * @param defStreams Default log streams to be attached. Any bitwise + * combination of the aiDefaultLogStream enumerated values. + * If #aiDefaultLogStream_FILE is specified but an empty string is + * passed for 'name', no log file is created at all. + * @param io IOSystem to be used to open external files (such as the + * log file). Pass NULL to rely on the default implementation. + * This replaces the default #NullLogger with a #DefaultLogger instance. */ + static Logger *create(const char* name = ASSIMP_DEFAULT_LOG_NAME, + LogSeverity severity = NORMAL, + unsigned int defStreams = aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE, + IOSystem* io = NULL); + + // ---------------------------------------------------------------------- + /** @brief Setup a custom #Logger implementation. + * + * Use this if the provided #DefaultLogger class doesn't fit into + * your needs. If the provided message formatting is OK for you, + * it's much easier to use #create() and to attach your own custom + * output streams to it. + * @param logger Pass NULL to setup a default NullLogger*/ + static void set (Logger *logger); + + // ---------------------------------------------------------------------- + /** @brief Getter for singleton instance + * @return Only instance. This is never null, but it could be a + * NullLogger. Use isNullLogger to check this.*/ + static Logger *get(); + + // ---------------------------------------------------------------------- + /** @brief Return whether a #NullLogger is currently active + * @return true if the current logger is a #NullLogger. + * Use create() or set() to setup a logger that does actually do + * something else than just rejecting all log messages. */ + static bool isNullLogger(); + + // ---------------------------------------------------------------------- + /** @brief Kills the current singleton logger and replaces it with a + * #NullLogger instance. */ + static void kill(); + + // ---------------------------------------------------------------------- + /** @copydoc Logger::attachStream */ + bool attachStream(LogStream *pStream, + unsigned int severity); + + // ---------------------------------------------------------------------- + /** @copydoc Logger::detatchStream */ + bool detatchStream(LogStream *pStream, + unsigned int severity); + +private: + // ---------------------------------------------------------------------- + /** @briefPrivate construction for internal use by create(). + * @param severity Logging granularity */ + explicit DefaultLogger(LogSeverity severity); + + // ---------------------------------------------------------------------- + /** @briefDestructor */ + ~DefaultLogger(); + + /** @brief Logs debug infos, only been written when severity level VERBOSE is set */ + void OnDebug(const char* message); + + /** @brief Logs an info message */ + void OnInfo(const char* message); + + /** @brief Logs a warning message */ + void OnWarn(const char* message); + + /** @brief Logs an error message */ + void OnError(const char* message); + + // ---------------------------------------------------------------------- + /** @brief Writes a message to all streams */ + void WriteToStreams(const char* message, ErrorSeverity ErrorSev ); + + // ---------------------------------------------------------------------- + /** @brief Returns the thread id. + * @note This is an OS specific feature, if not supported, a + * zero will be returned. + */ + unsigned int GetThreadID(); + +private: + // Aliases for stream container + typedef std::vector StreamArray; + typedef std::vector::iterator StreamIt; + typedef std::vector::const_iterator ConstStreamIt; + + //! only logging instance + static Logger *m_pLogger; + static NullLogger s_pNullLogger; + + //! Attached streams + StreamArray m_StreamArray; + + bool noRepeatMsg; + char lastMsg[MAX_LOG_MESSAGE_LENGTH*2]; + size_t lastLen; +}; +// ------------------------------------------------------------------------------------ + +} // Namespace Assimp + +#endif // !! INCLUDED_AI_DEFAULTLOGGER diff --git a/tools/ZAPD/ZAPD/assimp/Defines.h b/tools/ZAPD/ZAPD/assimp/Defines.h new file mode 100644 index 0000000000..15e1d83c26 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/Defines.h @@ -0,0 +1,49 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +// We need those constants, workaround for any platforms where nobody defined them yet +#if (!defined SIZE_MAX) +# define SIZE_MAX (~((size_t)0)) +#endif + +#if (!defined UINT_MAX) +# define UINT_MAX (~((unsigned int)0)) +#endif + diff --git a/tools/ZAPD/ZAPD/assimp/Exceptional.h b/tools/ZAPD/ZAPD/assimp/Exceptional.h new file mode 100644 index 0000000000..5109b8f077 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/Exceptional.h @@ -0,0 +1,125 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2008, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +#ifndef INCLUDED_EXCEPTIONAL_H +#define INCLUDED_EXCEPTIONAL_H + +#include +#include +using std::runtime_error; + +#ifdef _MSC_VER +# pragma warning(disable : 4275) +#endif + +// --------------------------------------------------------------------------- +/** FOR IMPORTER PLUGINS ONLY: Simple exception class to be thrown if an + * unrecoverable error occurs while importing. Loading APIs return + * NULL instead of a valid aiScene then. */ +class DeadlyImportError + : public runtime_error +{ +public: + /** Constructor with arguments */ + explicit DeadlyImportError( const std::string& errorText) + : runtime_error(errorText) + { + } + +private: +}; + +typedef DeadlyImportError DeadlyExportError; + +#ifdef _MSC_VER +# pragma warning(default : 4275) +#endif + +// --------------------------------------------------------------------------- +template +struct ExceptionSwallower { + T operator ()() const { + return T(); + } +}; + +// --------------------------------------------------------------------------- +template +struct ExceptionSwallower { + T* operator ()() const { + return NULL; + } +}; + +// --------------------------------------------------------------------------- +template <> +struct ExceptionSwallower { + aiReturn operator ()() const { + try { + throw; + } + catch (std::bad_alloc&) { + return aiReturn_OUTOFMEMORY; + } + catch (...) { + return aiReturn_FAILURE; + } + } +}; + +// --------------------------------------------------------------------------- +template <> +struct ExceptionSwallower { + void operator ()() const { + return; + } +}; + +#define ASSIMP_BEGIN_EXCEPTION_REGION()\ +{\ + try { + +#define ASSIMP_END_EXCEPTION_REGION(type)\ + } catch(...) {\ + return ExceptionSwallower()();\ + }\ +} + +#endif // INCLUDED_EXCEPTIONAL_H diff --git a/tools/ZAPD/ZAPD/assimp/Exporter.hpp b/tools/ZAPD/ZAPD/assimp/Exporter.hpp new file mode 100644 index 0000000000..ea0303e804 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/Exporter.hpp @@ -0,0 +1,505 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above +copyright notice, this list of conditions and the +following disclaimer. + +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other +materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its +contributors may be used to endorse or promote products +derived from this software without specific prior +written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file Exporter.hpp +* @brief Defines the CPP-API for the Assimp export interface +*/ +#pragma once +#ifndef AI_EXPORT_HPP_INC +#define AI_EXPORT_HPP_INC + +#ifndef ASSIMP_BUILD_NO_EXPORT + +#include "cexport.h" +#include + +namespace Assimp { + +class ExporterPimpl; +class IOSystem; +class ProgressHandler; + +// ---------------------------------------------------------------------------------- +/** CPP-API: The Exporter class forms an C++ interface to the export functionality + * of the Open Asset Import Library. Note that the export interface is available + * only if Assimp has been built with ASSIMP_BUILD_NO_EXPORT not defined. + * + * The interface is modeled after the importer interface and mostly + * symmetric. The same rules for threading etc. apply. + * + * In a nutshell, there are two export interfaces: #Export, which writes the + * output file(s) either to the regular file system or to a user-supplied + * #IOSystem, and #ExportToBlob which returns a linked list of memory + * buffers (blob), each referring to one output file (in most cases + * there will be only one output file of course, but this extra complexity is + * needed since Assimp aims at supporting a wide range of file formats). + * + * #ExportToBlob is especially useful if you intend to work + * with the data in-memory. +*/ +class ASSIMP_API ExportProperties; + +class ASSIMP_API Exporter { +public: + /** Function pointer type of a Export worker function */ + typedef void (*fpExportFunc)(const char*, IOSystem*, const aiScene*, const ExportProperties*); + + /** Internal description of an Assimp export format option */ + struct ExportFormatEntry { + /// Public description structure to be returned by aiGetExportFormatDescription() + aiExportFormatDesc mDescription; + + // Worker function to do the actual exporting + fpExportFunc mExportFunction; + + // Post-processing steps to be executed PRIOR to invoking mExportFunction + unsigned int mEnforcePP; + + // Constructor to fill all entries + ExportFormatEntry( const char* pId, const char* pDesc, const char* pExtension, fpExportFunc pFunction, unsigned int pEnforcePP = 0u) + { + mDescription.id = pId; + mDescription.description = pDesc; + mDescription.fileExtension = pExtension; + mExportFunction = pFunction; + mEnforcePP = pEnforcePP; + } + + ExportFormatEntry() : + mExportFunction() + , mEnforcePP() + { + mDescription.id = NULL; + mDescription.description = NULL; + mDescription.fileExtension = NULL; + } + }; + + /** + * @brief The class constructor. + */ + Exporter(); + + /** + * @brief The class destructor. + */ + ~Exporter(); + + // ------------------------------------------------------------------- + /** Supplies a custom IO handler to the exporter to use to open and + * access files. + * + * If you need #Export to use custom IO logic to access the files, + * you need to supply a custom implementation of IOSystem and + * IOFile to the exporter. + * + * #Exporter takes ownership of the object and will destroy it + * afterwards. The previously assigned handler will be deleted. + * Pass NULL to take again ownership of your IOSystem and reset Assimp + * to use its default implementation, which uses plain file IO. + * + * @param pIOHandler The IO handler to be used in all file accesses + * of the Importer. */ + void SetIOHandler( IOSystem* pIOHandler); + + // ------------------------------------------------------------------- + /** Retrieves the IO handler that is currently set. + * You can use #IsDefaultIOHandler() to check whether the returned + * interface is the default IO handler provided by ASSIMP. The default + * handler is active as long the application doesn't supply its own + * custom IO handler via #SetIOHandler(). + * @return A valid IOSystem interface, never NULL. */ + IOSystem* GetIOHandler() const; + + // ------------------------------------------------------------------- + /** Checks whether a default IO handler is active + * A default handler is active as long the application doesn't + * supply its own custom IO handler via #SetIOHandler(). + * @return true by default */ + bool IsDefaultIOHandler() const; + + // ------------------------------------------------------------------- + /** Supplies a custom progress handler to the exporter. This + * interface exposes an #Update() callback, which is called + * more or less periodically (please don't sue us if it + * isn't as periodically as you'd like it to have ...). + * This can be used to implement progress bars and loading + * timeouts. + * @param pHandler Progress callback interface. Pass nullptr to + * disable progress reporting. + * @note Progress handlers can be used to abort the loading + * at almost any time.*/ + void SetProgressHandler(ProgressHandler* pHandler); + + // ------------------------------------------------------------------- + /** Exports the given scene to a chosen file format. Returns the exported + * data as a binary blob which you can write into a file or something. + * When you're done with the data, simply let the #Exporter instance go + * out of scope to have it released automatically. + * @param pScene The scene to export. Stays in possession of the caller, + * is not changed by the function. + * @param pFormatId ID string to specify to which format you want to + * export to. Use + * #GetExportFormatCount / #GetExportFormatDescription to learn which + * export formats are available. + * @param pPreprocessing See the documentation for #Export + * @return the exported data or NULL in case of error. + * @note If the Exporter instance did already hold a blob from + * a previous call to #ExportToBlob, it will be disposed. + * Any IO handlers set via #SetIOHandler are ignored here. + * @note Use aiCopyScene() to get a modifiable copy of a previously + * imported scene. */ + const aiExportDataBlob* ExportToBlob(const aiScene* pScene, const char* pFormatId, + unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = nullptr); + const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const std::string& pFormatId, + unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = nullptr); + + // ------------------------------------------------------------------- + /** Convenience function to export directly to a file. Use + * #SetIOSystem to supply a custom IOSystem to gain fine-grained control + * about the output data flow of the export process. + * @param pBlob A data blob obtained from a previous call to #aiExportScene. Must not be NULL. + * @param pPath Full target file name. Target must be accessible. + * @param pPreprocessing Accepts any choice of the #aiPostProcessSteps enumerated + * flags, but in reality only a subset of them makes sense here. Specifying + * 'preprocessing' flags is useful if the input scene does not conform to + * Assimp's default conventions as specified in the @link data Data Structures Page @endlink. + * In short, this means the geometry data should use a right-handed coordinate systems, face + * winding should be counter-clockwise and the UV coordinate origin is assumed to be in + * the upper left. The #aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and + * #aiProcess_FlipWindingOrder flags are used in the import side to allow users + * to have those defaults automatically adapted to their conventions. Specifying those flags + * for exporting has the opposite effect, respectively. Some other of the + * #aiPostProcessSteps enumerated values may be useful as well, but you'll need + * to try out what their effect on the exported file is. Many formats impose + * their own restrictions on the structure of the geometry stored therein, + * so some preprocessing may have little or no effect at all, or may be + * redundant as exporters would apply them anyhow. A good example + * is triangulation - whilst you can enforce it by specifying + * the #aiProcess_Triangulate flag, most export formats support only + * triangulate data so they would run the step even if it wasn't requested. + * + * If assimp detects that the input scene was directly taken from the importer side of + * the library (i.e. not copied using aiCopyScene and potentially modified afterwards), + * any post-processing steps already applied to the scene will not be applied again, unless + * they show non-idempotent behavior (#aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and + * #aiProcess_FlipWindingOrder). + * @return AI_SUCCESS if everything was fine. + * @note Use aiCopyScene() to get a modifiable copy of a previously + * imported scene.*/ + aiReturn Export( const aiScene* pScene, const char* pFormatId, const char* pPath, + unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = nullptr); + aiReturn Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath, + unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = nullptr); + + // ------------------------------------------------------------------- + /** Returns an error description of an error that occurred in #Export + * or #ExportToBlob + * + * Returns an empty string if no error occurred. + * @return A description of the last error, an empty string if no + * error occurred. The string is never NULL. + * + * @note The returned function remains valid until one of the + * following methods is called: #Export, #ExportToBlob, #FreeBlob */ + const char* GetErrorString() const; + + // ------------------------------------------------------------------- + /** Return the blob obtained from the last call to #ExportToBlob */ + const aiExportDataBlob* GetBlob() const; + + // ------------------------------------------------------------------- + /** Orphan the blob from the last call to #ExportToBlob. This means + * the caller takes ownership and is thus responsible for calling + * the C API function #aiReleaseExportBlob to release it. */ + const aiExportDataBlob* GetOrphanedBlob() const; + + // ------------------------------------------------------------------- + /** Frees the current blob. + * + * The function does nothing if no blob has previously been + * previously produced via #ExportToBlob. #FreeBlob is called + * automatically by the destructor. The only reason to call + * it manually would be to reclaim as much storage as possible + * without giving up the #Exporter instance yet. */ + void FreeBlob( ); + + // ------------------------------------------------------------------- + /** Returns the number of export file formats available in the current + * Assimp build. Use #Exporter::GetExportFormatDescription to + * retrieve infos of a specific export format. + * + * This includes built-in exporters as well as exporters registered + * using #RegisterExporter. + **/ + size_t GetExportFormatCount() const; + + // ------------------------------------------------------------------- + /** Returns a description of the nth export file format. Use # + * #Exporter::GetExportFormatCount to learn how many export + * formats are supported. + * + * The returned pointer is of static storage duration if the + * pIndex pertains to a built-in exporter (i.e. one not registered + * via #RegistrerExporter). It is restricted to the life-time of the + * #Exporter instance otherwise. + * + * @param pIndex Index of the export format to retrieve information + * for. Valid range is 0 to #Exporter::GetExportFormatCount + * @return A description of that specific export format. + * NULL if pIndex is out of range. */ + const aiExportFormatDesc* GetExportFormatDescription( size_t pIndex ) const; + + // ------------------------------------------------------------------- + /** Register a custom exporter. Custom export formats are limited to + * to the current #Exporter instance and do not affect the + * library globally. The indexes under which the format's + * export format description can be queried are assigned + * monotonously. + * @param desc Exporter description. + * @return aiReturn_SUCCESS if the export format was successfully + * registered. A common cause that would prevent an exporter + * from being registered is that its format id is already + * occupied by another format. */ + aiReturn RegisterExporter(const ExportFormatEntry& desc); + + // ------------------------------------------------------------------- + /** Remove an export format previously registered with #RegisterExporter + * from the #Exporter instance (this can also be used to drop + * built-in exporters because those are implicitly registered + * using #RegisterExporter). + * @param id Format id to be unregistered, this refers to the + * 'id' field of #aiExportFormatDesc. + * @note Calling this method on a format description not yet registered + * has no effect.*/ + void UnregisterExporter(const char* id); + +protected: + // Just because we don't want you to know how we're hacking around. + ExporterPimpl* pimpl; +}; + +class ASSIMP_API ExportProperties { +public: + // Data type to store the key hash + typedef unsigned int KeyType; + + // typedefs for our four configuration maps. + // We don't need more, so there is no need for a generic solution + typedef std::map IntPropertyMap; + typedef std::map FloatPropertyMap; + typedef std::map StringPropertyMap; + typedef std::map MatrixPropertyMap; + +public: + /** Standard constructor + * @see ExportProperties() + */ + ExportProperties(); + + // ------------------------------------------------------------------- + /** Copy constructor. + * + * This copies the configuration properties of another ExportProperties. + * @see ExportProperties(const ExportProperties& other) + */ + ExportProperties(const ExportProperties& other); + + // ------------------------------------------------------------------- + /** Set an integer configuration property. + * @param szName Name of the property. All supported properties + * are defined in the aiConfig.g header (all constants share the + * prefix AI_CONFIG_XXX and are simple strings). + * @param iValue New value of the property + * @return true if the property was set before. The new value replaces + * the previous value in this case. + * @note Property of different types (float, int, string ..) are kept + * on different stacks, so calling SetPropertyInteger() for a + * floating-point property has no effect - the loader will call + * GetPropertyFloat() to read the property, but it won't be there. + */ + bool SetPropertyInteger(const char* szName, int iValue); + + // ------------------------------------------------------------------- + /** Set a boolean configuration property. Boolean properties + * are stored on the integer stack internally so it's possible + * to set them via #SetPropertyBool and query them with + * #GetPropertyBool and vice versa. + * @see SetPropertyInteger() + */ + bool SetPropertyBool(const char* szName, bool value) { + return SetPropertyInteger(szName,value); + } + + // ------------------------------------------------------------------- + /** Set a floating-point configuration property. + * @see SetPropertyInteger() + */ + bool SetPropertyFloat(const char* szName, ai_real fValue); + + // ------------------------------------------------------------------- + /** Set a string configuration property. + * @see SetPropertyInteger() + */ + bool SetPropertyString(const char* szName, const std::string& sValue); + + // ------------------------------------------------------------------- + /** Set a matrix configuration property. + * @see SetPropertyInteger() + */ + bool SetPropertyMatrix(const char* szName, const aiMatrix4x4& sValue); + + // ------------------------------------------------------------------- + /** Get a configuration property. + * @param szName Name of the property. All supported properties + * are defined in the aiConfig.g header (all constants share the + * prefix AI_CONFIG_XXX). + * @param iErrorReturn Value that is returned if the property + * is not found. + * @return Current value of the property + * @note Property of different types (float, int, string ..) are kept + * on different lists, so calling SetPropertyInteger() for a + * floating-point property has no effect - the loader will call + * GetPropertyFloat() to read the property, but it won't be there. + */ + int GetPropertyInteger(const char* szName, + int iErrorReturn = 0xffffffff) const; + + // ------------------------------------------------------------------- + /** Get a boolean configuration property. Boolean properties + * are stored on the integer stack internally so it's possible + * to set them via #SetPropertyBool and query them with + * #GetPropertyBool and vice versa. + * @see GetPropertyInteger() + */ + bool GetPropertyBool(const char* szName, bool bErrorReturn = false) const { + return GetPropertyInteger(szName,bErrorReturn)!=0; + } + + // ------------------------------------------------------------------- + /** Get a floating-point configuration property + * @see GetPropertyInteger() + */ + ai_real GetPropertyFloat(const char* szName, + ai_real fErrorReturn = 10e10f) const; + + // ------------------------------------------------------------------- + /** Get a string configuration property + * + * The return value remains valid until the property is modified. + * @see GetPropertyInteger() + */ + const std::string GetPropertyString(const char* szName, + const std::string& sErrorReturn = "") const; + + // ------------------------------------------------------------------- + /** Get a matrix configuration property + * + * The return value remains valid until the property is modified. + * @see GetPropertyInteger() + */ + const aiMatrix4x4 GetPropertyMatrix(const char* szName, + const aiMatrix4x4& sErrorReturn = aiMatrix4x4()) const; + + // ------------------------------------------------------------------- + /** Determine a integer configuration property has been set. + * @see HasPropertyInteger() + */ + bool HasPropertyInteger(const char* szName) const; + + /** Determine a boolean configuration property has been set. + * @see HasPropertyBool() + */ + bool HasPropertyBool(const char* szName) const; + + /** Determine a boolean configuration property has been set. + * @see HasPropertyFloat() + */ + bool HasPropertyFloat(const char* szName) const; + + /** Determine a String configuration property has been set. + * @see HasPropertyString() + */ + bool HasPropertyString(const char* szName) const; + + /** Determine a Matrix configuration property has been set. + * @see HasPropertyMatrix() + */ + bool HasPropertyMatrix(const char* szName) const; + +protected: + + /** List of integer properties */ + IntPropertyMap mIntProperties; + + /** List of floating-point properties */ + FloatPropertyMap mFloatProperties; + + /** List of string properties */ + StringPropertyMap mStringProperties; + + /** List of Matrix properties */ + MatrixPropertyMap mMatrixProperties; +}; + +// ---------------------------------------------------------------------------------- +inline +const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const std::string& pFormatId, + unsigned int pPreprocessing, const ExportProperties* pProperties) +{ + return ExportToBlob(pScene,pFormatId.c_str(),pPreprocessing, pProperties); +} + +// ---------------------------------------------------------------------------------- +inline +aiReturn Exporter :: Export( const aiScene* pScene, const std::string& pFormatId, + const std::string& pPath, unsigned int pPreprocessing, + const ExportProperties* pProperties) +{ + return Export(pScene,pFormatId.c_str(),pPath.c_str(),pPreprocessing, pProperties); +} + +} // namespace Assimp + +#endif // ASSIMP_BUILD_NO_EXPORT +#endif // AI_EXPORT_HPP_INC diff --git a/tools/ZAPD/ZAPD/assimp/GenericProperty.h b/tools/ZAPD/ZAPD/assimp/GenericProperty.h new file mode 100644 index 0000000000..183ecd5197 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/GenericProperty.h @@ -0,0 +1,133 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +#ifndef AI_GENERIC_PROPERTY_H_INCLUDED +#define AI_GENERIC_PROPERTY_H_INCLUDED + +#include +#include +#include "Hash.h" + +#include + +// ------------------------------------------------------------------------------------------------ +template +inline +bool SetGenericProperty(std::map< unsigned int, T >& list, + const char* szName, const T& value) { + ai_assert(nullptr != szName); + const uint32_t hash = SuperFastHash(szName); + + typename std::map::iterator it = list.find(hash); + if (it == list.end()) { + list.insert(std::pair( hash, value )); + return false; + } + (*it).second = value; + + return true; +} + +// ------------------------------------------------------------------------------------------------ +template +inline +const T& GetGenericProperty(const std::map< unsigned int, T >& list, + const char* szName, const T& errorReturn) { + ai_assert(nullptr != szName); + const uint32_t hash = SuperFastHash(szName); + + typename std::map::const_iterator it = list.find(hash); + if (it == list.end()) { + return errorReturn; + } + + return (*it).second; +} + +// ------------------------------------------------------------------------------------------------ +// Special version for pointer types - they will be deleted when replaced with another value +// passing NULL removes the whole property +template +inline +void SetGenericPropertyPtr(std::map< unsigned int, T* >& list, + const char* szName, T* value, bool* bWasExisting = nullptr ) { + ai_assert(nullptr != szName); + const uint32_t hash = SuperFastHash(szName); + + typename std::map::iterator it = list.find(hash); + if (it == list.end()) { + if (bWasExisting) { + *bWasExisting = false; + } + + list.insert(std::pair( hash, value )); + return; + } + if ((*it).second != value) { + delete (*it).second; + (*it).second = value; + } + if (!value) { + list.erase(it); + } + if (bWasExisting) { + *bWasExisting = true; + } +} + +// ------------------------------------------------------------------------------------------------ +template +inline +bool HasGenericProperty(const std::map< unsigned int, T >& list, + const char* szName) { + ai_assert(nullptr != szName); + const uint32_t hash = SuperFastHash(szName); + + typename std::map::const_iterator it = list.find(hash); + if (it == list.end()) { + return false; + } + + return true; +} + +#endif // !! AI_GENERIC_PROPERTY_H_INCLUDED diff --git a/tools/ZAPD/ZAPD/assimp/Hash.h b/tools/ZAPD/ZAPD/assimp/Hash.h new file mode 100644 index 0000000000..30657be198 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/Hash.h @@ -0,0 +1,118 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +#ifndef AI_HASH_H_INCLUDED +#define AI_HASH_H_INCLUDED + +#include +#include + +// ------------------------------------------------------------------------------------------------ +// Hashing function taken from +// http://www.azillionmonkeys.com/qed/hash.html +// (incremental version) +// +// This code is Copyright 2004-2008 by Paul Hsieh. It is used here in the belief that +// Assimp's license is considered compatible with Pauls's derivative license as specified +// on his web page. +// +// (stdint.h should have been been included here) +// ------------------------------------------------------------------------------------------------ +#undef get16bits +#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ + || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) +#define get16bits(d) (*((const uint16_t *) (d))) +#endif + +#if !defined (get16bits) +#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\ + +(uint32_t)(((const uint8_t *)(d))[0]) ) +#endif + +// ------------------------------------------------------------------------------------------------ +inline uint32_t SuperFastHash (const char * data, uint32_t len = 0, uint32_t hash = 0) { +uint32_t tmp; +int rem; + + if (!data) return 0; + if (!len)len = (uint32_t)::strlen(data); + + rem = len & 3; + len >>= 2; + + /* Main loop */ + for (;len > 0; len--) { + hash += get16bits (data); + tmp = (get16bits (data+2) << 11) ^ hash; + hash = (hash << 16) ^ tmp; + data += 2*sizeof (uint16_t); + hash += hash >> 11; + } + + /* Handle end cases */ + switch (rem) { + case 3: hash += get16bits (data); + hash ^= hash << 16; + hash ^= data[sizeof (uint16_t)] << 18; + hash += hash >> 11; + break; + case 2: hash += get16bits (data); + hash ^= hash << 11; + hash += hash >> 17; + break; + case 1: hash += *data; + hash ^= hash << 10; + hash += hash >> 1; + } + + /* Force "avalanching" of final 127 bits */ + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 4; + hash += hash >> 17; + hash ^= hash << 25; + hash += hash >> 6; + + return hash; +} + +#endif // !! AI_HASH_H_INCLUDED diff --git a/tools/ZAPD/ZAPD/assimp/IOStream.hpp b/tools/ZAPD/ZAPD/assimp/IOStream.hpp new file mode 100644 index 0000000000..0623d0f70b --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/IOStream.hpp @@ -0,0 +1,142 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ +/** @file IOStream.hpp + * @brief File I/O wrappers for C++. + */ + +#pragma once +#ifndef AI_IOSTREAM_H_INC +#define AI_IOSTREAM_H_INC + +#include "types.h" + +#ifndef __cplusplus +# error This header requires C++ to be used. aiFileIO.h is the \ + corresponding C interface. +#endif + +namespace Assimp { + +// ---------------------------------------------------------------------------------- +/** @brief CPP-API: Class to handle file I/O for C++ + * + * Derive an own implementation from this interface to provide custom IO handling + * to the Importer. If you implement this interface, be sure to also provide an + * implementation for IOSystem that creates instances of your custom IO class. +*/ +class ASSIMP_API IOStream +#ifndef SWIG + : public Intern::AllocateFromAssimpHeap +#endif +{ +protected: + /** Constructor protected, use IOSystem::Open() to create an instance. */ + IOStream() AI_NO_EXCEPT; + +public: + // ------------------------------------------------------------------- + /** @brief Destructor. Deleting the object closes the underlying file, + * alternatively you may use IOSystem::Close() to release the file. + */ + virtual ~IOStream(); + + // ------------------------------------------------------------------- + /** @brief Read from the file + * + * See fread() for more details + * This fails for write-only files */ + virtual size_t Read(void* pvBuffer, + size_t pSize, + size_t pCount) = 0; + + // ------------------------------------------------------------------- + /** @brief Write to the file + * + * See fwrite() for more details + * This fails for read-only files */ + virtual size_t Write(const void* pvBuffer, + size_t pSize, + size_t pCount) = 0; + + // ------------------------------------------------------------------- + /** @brief Set the read/write cursor of the file + * + * Note that the offset is _negative_ for aiOrigin_END. + * See fseek() for more details */ + virtual aiReturn Seek(size_t pOffset, + aiOrigin pOrigin) = 0; + + // ------------------------------------------------------------------- + /** @brief Get the current position of the read/write cursor + * + * See ftell() for more details */ + virtual size_t Tell() const = 0; + + // ------------------------------------------------------------------- + /** @brief Returns filesize + * Returns the filesize. */ + virtual size_t FileSize() const = 0; + + // ------------------------------------------------------------------- + /** @brief Flush the contents of the file buffer (for writers) + * See fflush() for more details. + */ + virtual void Flush() = 0; +}; //! class IOStream + +// ---------------------------------------------------------------------------------- +inline +IOStream::IOStream() AI_NO_EXCEPT { + // empty +} + +// ---------------------------------------------------------------------------------- +inline +IOStream::~IOStream() { + // empty +} +// ---------------------------------------------------------------------------------- + +} //!namespace Assimp + +#endif //!!AI_IOSTREAM_H_INC diff --git a/tools/ZAPD/ZAPD/assimp/IOStreamBuffer.h b/tools/ZAPD/ZAPD/assimp/IOStreamBuffer.h new file mode 100644 index 0000000000..58abd97a02 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/IOStreamBuffer.h @@ -0,0 +1,355 @@ +#pragma once + +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above +copyright notice, this list of conditions and the +following disclaimer. + +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other +materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its +contributors may be used to endorse or promote products +derived from this software without specific prior +written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +#include +#include + +#include "ParsingUtils.h" + +#include + +namespace Assimp { + +// --------------------------------------------------------------------------- +/** + * Implementation of a cached stream buffer. + */ +template +class IOStreamBuffer { +public: + /// @brief The class constructor. + IOStreamBuffer( size_t cache = 4096 * 4096 ); + + /// @brief The class destructor. + ~IOStreamBuffer(); + + /// @brief Will open the cached access for a given stream. + /// @param stream The stream to cache. + /// @return true if successful. + bool open( IOStream *stream ); + + /// @brief Will close the cached access. + /// @return true if successful. + bool close(); + + /// @brief Returns the file-size. + /// @return The file-size. + size_t size() const; + + /// @brief Returns the cache size. + /// @return The cache size. + size_t cacheSize() const; + + /// @brief Will read the next block. + /// @return true if successful. + bool readNextBlock(); + + /// @brief Returns the number of blocks to read. + /// @return The number of blocks. + size_t getNumBlocks() const; + + /// @brief Returns the current block index. + /// @return The current block index. + size_t getCurrentBlockIndex() const; + + /// @brief Returns the current file pos. + /// @return The current file pos. + size_t getFilePos() const; + + /// @brief Will read the next line. + /// @param buffer The buffer for the next line. + /// @return true if successful. + bool getNextDataLine( std::vector &buffer, T continuationToken ); + + /// @brief Will read the next line ascii or binary end line char. + /// @param buffer The buffer for the next line. + /// @return true if successful. + bool getNextLine(std::vector &buffer); + + /// @brief Will read the next block. + /// @param buffer The buffer for the next block. + /// @return true if successful. + bool getNextBlock( std::vector &buffer ); + +private: + IOStream *m_stream; + size_t m_filesize; + size_t m_cacheSize; + size_t m_numBlocks; + size_t m_blockIdx; + std::vector m_cache; + size_t m_cachePos; + size_t m_filePos; +}; + +template +inline +IOStreamBuffer::IOStreamBuffer( size_t cache ) +: m_stream( nullptr ) +, m_filesize( 0 ) +, m_cacheSize( cache ) +, m_numBlocks( 0 ) +, m_blockIdx( 0 ) +, m_cachePos( 0 ) +, m_filePos( 0 ) { + m_cache.resize( cache ); + std::fill( m_cache.begin(), m_cache.end(), '\n' ); +} + +template +inline +IOStreamBuffer::~IOStreamBuffer() { + // empty +} + +template +inline +bool IOStreamBuffer::open( IOStream *stream ) { + // file still opened! + if ( nullptr != m_stream ) { + return false; + } + + // Invalid stream pointer + if ( nullptr == stream ) { + return false; + } + + m_stream = stream; + m_filesize = m_stream->FileSize(); + if ( m_filesize == 0 ) { + return false; + } + if ( m_filesize < m_cacheSize ) { + m_cacheSize = m_filesize; + } + + m_numBlocks = m_filesize / m_cacheSize; + if ( ( m_filesize % m_cacheSize ) > 0 ) { + m_numBlocks++; + } + + return true; +} + +template +inline +bool IOStreamBuffer::close() { + if ( nullptr == m_stream ) { + return false; + } + + // init counters and state vars + m_stream = nullptr; + m_filesize = 0; + m_numBlocks = 0; + m_blockIdx = 0; + m_cachePos = 0; + m_filePos = 0; + + return true; +} + +template +inline +size_t IOStreamBuffer::size() const { + return m_filesize; +} + +template +inline +size_t IOStreamBuffer::cacheSize() const { + return m_cacheSize; +} + +template +inline +bool IOStreamBuffer::readNextBlock() { + m_stream->Seek( m_filePos, aiOrigin_SET ); + size_t readLen = m_stream->Read( &m_cache[ 0 ], sizeof( T ), m_cacheSize ); + if ( readLen == 0 ) { + return false; + } + if ( readLen < m_cacheSize ) { + m_cacheSize = readLen; + } + m_filePos += m_cacheSize; + m_cachePos = 0; + m_blockIdx++; + + return true; +} + +template +inline +size_t IOStreamBuffer::getNumBlocks() const { + return m_numBlocks; +} + +template +inline +size_t IOStreamBuffer::getCurrentBlockIndex() const { + return m_blockIdx; +} + +template +inline +size_t IOStreamBuffer::getFilePos() const { + return m_filePos; +} + +template +inline +bool IOStreamBuffer::getNextDataLine( std::vector &buffer, T continuationToken ) { + buffer.resize( m_cacheSize ); + if ( m_cachePos >= m_cacheSize || 0 == m_filePos ) { + if ( !readNextBlock() ) { + return false; + } + } + + bool continuationFound( false ); + size_t i = 0; + for( ;; ) { + if ( continuationToken == m_cache[ m_cachePos ] ) { + continuationFound = true; + ++m_cachePos; + } + if ( IsLineEnd( m_cache[ m_cachePos ] ) ) { + if ( !continuationFound ) { + // the end of the data line + break; + } else { + // skip line end + while ( m_cache[m_cachePos] != '\n') { + ++m_cachePos; + } + ++m_cachePos; + continuationFound = false; + } + } + + buffer[ i ] = m_cache[ m_cachePos ]; + ++m_cachePos; + ++i; + if (m_cachePos >= size()) { + break; + } + if ( m_cachePos >= m_cacheSize ) { + if ( !readNextBlock() ) { + return false; + } + } + } + + buffer[ i ] = '\n'; + ++m_cachePos; + + return true; +} + +static inline +bool isEndOfCache( size_t pos, size_t cacheSize ) { + return ( pos == cacheSize ); +} + +template +inline +bool IOStreamBuffer::getNextLine(std::vector &buffer) { + buffer.resize(m_cacheSize); + if ( isEndOfCache( m_cachePos, m_cacheSize ) || 0 == m_filePos) { + if (!readNextBlock()) { + return false; + } + } + + if (IsLineEnd(m_cache[m_cachePos])) { + // skip line end + while (m_cache[m_cachePos] != '\n') { + ++m_cachePos; + } + ++m_cachePos; + if ( isEndOfCache( m_cachePos, m_cacheSize ) ) { + if ( !readNextBlock() ) { + return false; + } + } + } + + size_t i( 0 ); + while (!IsLineEnd(m_cache[ m_cachePos ])) { + buffer[i] = m_cache[ m_cachePos ]; + ++m_cachePos; + ++i; + if (m_cachePos >= m_cacheSize) { + if (!readNextBlock()) { + return false; + } + } + } + buffer[i] = '\n'; + ++m_cachePos; + + return true; +} + +template +inline +bool IOStreamBuffer::getNextBlock( std::vector &buffer) { + // Return the last block-value if getNextLine was used before + if ( 0 != m_cachePos ) { + buffer = std::vector( m_cache.begin() + m_cachePos, m_cache.end() ); + m_cachePos = 0; + } else { + if ( !readNextBlock() ) { + return false; + } + + buffer = std::vector(m_cache.begin(), m_cache.end()); + } + + return true; +} + +} // !ns Assimp diff --git a/tools/ZAPD/ZAPD/assimp/IOSystem.hpp b/tools/ZAPD/ZAPD/assimp/IOSystem.hpp new file mode 100644 index 0000000000..78139c2839 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/IOSystem.hpp @@ -0,0 +1,357 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file IOSystem.hpp + * @brief File system wrapper for C++. Inherit this class to supply + * custom file handling logic to the Import library. +*/ + +#pragma once +#ifndef AI_IOSYSTEM_H_INC +#define AI_IOSYSTEM_H_INC + +#ifndef __cplusplus +# error This header requires C++ to be used. aiFileIO.h is the \ + corresponding C interface. +#endif + +#include "types.h" + +#ifdef _WIN32 +# include +# include +# include +#else +# include +# include +# include +#endif // _WIN32 + +#include + +namespace Assimp { + + class IOStream; + +// --------------------------------------------------------------------------- +/** @brief CPP-API: Interface to the file system. + * + * Derive an own implementation from this interface to supply custom file handling + * to the importer library. If you implement this interface, you also want to + * supply a custom implementation for IOStream. + * + * @see Importer::SetIOHandler() + */ +class ASSIMP_API IOSystem +#ifndef SWIG + : public Intern::AllocateFromAssimpHeap +#endif +{ +public: + + // ------------------------------------------------------------------- + /** @brief Default constructor. + * + * Create an instance of your derived class and assign it to an + * #Assimp::Importer instance by calling Importer::SetIOHandler(). + */ + IOSystem() AI_NO_EXCEPT; + + // ------------------------------------------------------------------- + /** @brief Virtual destructor. + * + * It is safe to be called from within DLL Assimp, we're constructed + * on Assimp's heap. + */ + virtual ~IOSystem(); + + // ------------------------------------------------------------------- + /** @brief For backward compatibility + * @see Exists(const char*) + */ + AI_FORCE_INLINE bool Exists( const std::string& pFile) const; + + // ------------------------------------------------------------------- + /** @brief Tests for the existence of a file at the given path. + * + * @param pFile Path to the file + * @return true if there is a file with this path, else false. + */ + virtual bool Exists( const char* pFile) const = 0; + + // ------------------------------------------------------------------- + /** @brief Returns the system specific directory separator + * @return System specific directory separator + */ + virtual char getOsSeparator() const = 0; + + // ------------------------------------------------------------------- + /** @brief Open a new file with a given path. + * + * When the access to the file is finished, call Close() to release + * all associated resources (or the virtual dtor of the IOStream). + * + * @param pFile Path to the file + * @param pMode Desired file I/O mode. Required are: "wb", "w", "wt", + * "rb", "r", "rt". + * + * @return New IOStream interface allowing the lib to access + * the underlying file. + * @note When implementing this class to provide custom IO handling, + * you probably have to supply an own implementation of IOStream as well. + */ + virtual IOStream* Open(const char* pFile, + const char* pMode = "rb") = 0; + + // ------------------------------------------------------------------- + /** @brief For backward compatibility + * @see Open(const char*, const char*) + */ + inline IOStream* Open(const std::string& pFile, + const std::string& pMode = std::string("rb")); + + // ------------------------------------------------------------------- + /** @brief Closes the given file and releases all resources + * associated with it. + * @param pFile The file instance previously created by Open(). + */ + virtual void Close( IOStream* pFile) = 0; + + // ------------------------------------------------------------------- + /** @brief Compares two paths and check whether the point to + * identical files. + * + * The dummy implementation of this virtual member performs a + * case-insensitive comparison of the given strings. The default IO + * system implementation uses OS mechanisms to convert relative into + * absolute paths, so the result can be trusted. + * @param one First file + * @param second Second file + * @return true if the paths point to the same file. The file needn't + * be existing, however. + */ + virtual bool ComparePaths (const char* one, + const char* second) const; + + // ------------------------------------------------------------------- + /** @brief For backward compatibility + * @see ComparePaths(const char*, const char*) + */ + inline bool ComparePaths (const std::string& one, + const std::string& second) const; + + // ------------------------------------------------------------------- + /** @brief Pushes a new directory onto the directory stack. + * @param path Path to push onto the stack. + * @return True, when push was successful, false if path is empty. + */ + virtual bool PushDirectory( const std::string &path ); + + // ------------------------------------------------------------------- + /** @brief Returns the top directory from the stack. + * @return The directory on the top of the stack. + * Returns empty when no directory was pushed to the stack. + */ + virtual const std::string &CurrentDirectory() const; + + // ------------------------------------------------------------------- + /** @brief Returns the number of directories stored on the stack. + * @return The number of directories of the stack. + */ + virtual size_t StackSize() const; + + // ------------------------------------------------------------------- + /** @brief Pops the top directory from the stack. + * @return True, when a directory was on the stack. False if no + * directory was on the stack. + */ + virtual bool PopDirectory(); + + // ------------------------------------------------------------------- + /** @brief CReates an new directory at the given path. + * @param path [in] The path to create. + * @return True, when a directory was created. False if the directory + * cannot be created. + */ + virtual bool CreateDirectory( const std::string &path ); + + // ------------------------------------------------------------------- + /** @brief Will change the current directory to the given path. + * @param path [in] The path to change to. + * @return True, when the directory has changed successfully. + */ + virtual bool ChangeDirectory( const std::string &path ); + + virtual bool DeleteFile( const std::string &file ); + +private: + std::vector m_pathStack; +}; + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE +IOSystem::IOSystem() AI_NO_EXCEPT +: m_pathStack() { + // empty +} + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE +IOSystem::~IOSystem() { + // empty +} + +// ---------------------------------------------------------------------------- +// For compatibility, the interface of some functions taking a std::string was +// changed to const char* to avoid crashes between binary incompatible STL +// versions. This code her is inlined, so it shouldn't cause any problems. +// ---------------------------------------------------------------------------- + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE +IOStream* IOSystem::Open(const std::string& pFile, const std::string& pMode) { + // NOTE: + // For compatibility, interface was changed to const char* to + // avoid crashes between binary incompatible STL versions + return Open(pFile.c_str(),pMode.c_str()); +} + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE +bool IOSystem::Exists( const std::string& pFile) const { + // NOTE: + // For compatibility, interface was changed to const char* to + // avoid crashes between binary incompatible STL versions + return Exists(pFile.c_str()); +} + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE +bool IOSystem::ComparePaths (const std::string& one, const std::string& second) const { + // NOTE: + // For compatibility, interface was changed to const char* to + // avoid crashes between binary incompatible STL versions + return ComparePaths(one.c_str(),second.c_str()); +} + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE +bool IOSystem::PushDirectory( const std::string &path ) { + if ( path.empty() ) { + return false; + } + + m_pathStack.push_back( path ); + + return true; +} + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE +const std::string &IOSystem::CurrentDirectory() const { + if ( m_pathStack.empty() ) { + static const std::string Dummy(""); + return Dummy; + } + return m_pathStack[ m_pathStack.size()-1 ]; +} + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE +size_t IOSystem::StackSize() const { + return m_pathStack.size(); +} + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE +bool IOSystem::PopDirectory() { + if ( m_pathStack.empty() ) { + return false; + } + + m_pathStack.pop_back(); + + return true; +} + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE +bool IOSystem::CreateDirectory( const std::string &path ) { + if ( path.empty() ) { + return false; + } + +#ifdef _WIN32 + return 0 != ::_mkdir( path.c_str() ); +#else + return 0 != ::mkdir( path.c_str(), 0777 ); +#endif // _WIN32 +} + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE +bool IOSystem::ChangeDirectory( const std::string &path ) { + if ( path.empty() ) { + return false; + } + +#ifdef _WIN32 + return 0 != ::_chdir( path.c_str() ); +#else + return 0 != ::chdir( path.c_str() ); +#endif // _WIN32 +} + + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE +bool IOSystem::DeleteFile( const std::string &file ) { + if ( file.empty() ) { + return false; + } + const int retCode( ::remove( file.c_str() ) ); + return ( 0 == retCode ); +} +} //!ns Assimp + +#endif //AI_IOSYSTEM_H_INC diff --git a/tools/ZAPD/ZAPD/assimp/Importer.hpp b/tools/ZAPD/ZAPD/assimp/Importer.hpp new file mode 100644 index 0000000000..4941df4122 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/Importer.hpp @@ -0,0 +1,659 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file Importer.hpp + * @brief Defines the C++-API to the Open Asset Import Library. + */ +#pragma once +#ifndef AI_ASSIMP_HPP_INC +#define AI_ASSIMP_HPP_INC + +#ifndef __cplusplus +# error This header requires C++ to be used. Use assimp.h for plain C. +#endif // __cplusplus + +// Public ASSIMP data structures +#include + +namespace Assimp { + // ======================================================================= + // Public interface to Assimp + class Importer; + class IOStream; + class IOSystem; + class ProgressHandler; + + // ======================================================================= + // Plugin development + // + // Include the following headers for the declarations: + // BaseImporter.h + // BaseProcess.h + class BaseImporter; + class BaseProcess; + class SharedPostProcessInfo; + class BatchLoader; + + // ======================================================================= + // Holy stuff, only for members of the high council of the Jedi. + class ImporterPimpl; +} //! namespace Assimp + +#define AI_PROPERTY_WAS_NOT_EXISTING 0xffffffff + +struct aiScene; + +// importerdesc.h +struct aiImporterDesc; + +/** @namespace Assimp Assimp's CPP-API and all internal APIs */ +namespace Assimp { + +// ---------------------------------------------------------------------------------- +/** CPP-API: The Importer class forms an C++ interface to the functionality of the +* Open Asset Import Library. +* +* Create an object of this class and call ReadFile() to import a file. +* If the import succeeds, the function returns a pointer to the imported data. +* The data remains property of the object, it is intended to be accessed +* read-only. The imported data will be destroyed along with the Importer +* object. If the import fails, ReadFile() returns a NULL pointer. In this +* case you can retrieve a human-readable error description be calling +* GetErrorString(). You can call ReadFile() multiple times with a single Importer +* instance. Actually, constructing Importer objects involves quite many +* allocations and may take some time, so it's better to reuse them as often as +* possible. +* +* If you need the Importer to do custom file handling to access the files, +* implement IOSystem and IOStream and supply an instance of your custom +* IOSystem implementation by calling SetIOHandler() before calling ReadFile(). +* If you do not assign a custion IO handler, a default handler using the +* standard C++ IO logic will be used. +* +* @note One Importer instance is not thread-safe. If you use multiple +* threads for loading, each thread should maintain its own Importer instance. +*/ +class ASSIMP_API Importer { +public: + /** + * @brief The upper limit for hints. + */ + static const unsigned int MaxLenHint = 200; + +public: + + // ------------------------------------------------------------------- + /** Constructor. Creates an empty importer object. + * + * Call ReadFile() to start the import process. The configuration + * property table is initially empty. + */ + Importer(); + + // ------------------------------------------------------------------- + /** Copy constructor. + * + * This copies the configuration properties of another Importer. + * If this Importer owns a scene it won't be copied. + * Call ReadFile() to start the import process. + */ + Importer(const Importer& other)=delete; + + // ------------------------------------------------------------------- + /** Assignment operator has been deleted + */ + Importer &operator=(const Importer &) = delete; + + // ------------------------------------------------------------------- + /** Destructor. The object kept ownership of the imported data, + * which now will be destroyed along with the object. + */ + ~Importer(); + + + // ------------------------------------------------------------------- + /** Registers a new loader. + * + * @param pImp Importer to be added. The Importer instance takes + * ownership of the pointer, so it will be automatically deleted + * with the Importer instance. + * @return AI_SUCCESS if the loader has been added. The registration + * fails if there is already a loader for a specific file extension. + */ + aiReturn RegisterLoader(BaseImporter* pImp); + + // ------------------------------------------------------------------- + /** Unregisters a loader. + * + * @param pImp Importer to be unregistered. + * @return AI_SUCCESS if the loader has been removed. The function + * fails if the loader is currently in use (this could happen + * if the #Importer instance is used by more than one thread) or + * if it has not yet been registered. + */ + aiReturn UnregisterLoader(BaseImporter* pImp); + + // ------------------------------------------------------------------- + /** Registers a new post-process step. + * + * At the moment, there's a small limitation: new post processing + * steps are added to end of the list, or in other words, executed + * last, after all built-in steps. + * @param pImp Post-process step to be added. The Importer instance + * takes ownership of the pointer, so it will be automatically + * deleted with the Importer instance. + * @return AI_SUCCESS if the step has been added correctly. + */ + aiReturn RegisterPPStep(BaseProcess* pImp); + + // ------------------------------------------------------------------- + /** Unregisters a post-process step. + * + * @param pImp Step to be unregistered. + * @return AI_SUCCESS if the step has been removed. The function + * fails if the step is currently in use (this could happen + * if the #Importer instance is used by more than one thread) or + * if it has not yet been registered. + */ + aiReturn UnregisterPPStep(BaseProcess* pImp); + + // ------------------------------------------------------------------- + /** Set an integer configuration property. + * @param szName Name of the property. All supported properties + * are defined in the aiConfig.g header (all constants share the + * prefix AI_CONFIG_XXX and are simple strings). + * @param iValue New value of the property + * @return true if the property was set before. The new value replaces + * the previous value in this case. + * @note Property of different types (float, int, string ..) are kept + * on different stacks, so calling SetPropertyInteger() for a + * floating-point property has no effect - the loader will call + * GetPropertyFloat() to read the property, but it won't be there. + */ + bool SetPropertyInteger(const char* szName, int iValue); + + // ------------------------------------------------------------------- + /** Set a boolean configuration property. Boolean properties + * are stored on the integer stack internally so it's possible + * to set them via #SetPropertyBool and query them with + * #GetPropertyBool and vice versa. + * @see SetPropertyInteger() + */ + bool SetPropertyBool(const char* szName, bool value) { + return SetPropertyInteger(szName,value); + } + + // ------------------------------------------------------------------- + /** Set a floating-point configuration property. + * @see SetPropertyInteger() + */ + bool SetPropertyFloat(const char* szName, ai_real fValue); + + // ------------------------------------------------------------------- + /** Set a string configuration property. + * @see SetPropertyInteger() + */ + bool SetPropertyString(const char* szName, const std::string& sValue); + + // ------------------------------------------------------------------- + /** Set a matrix configuration property. + * @see SetPropertyInteger() + */ + bool SetPropertyMatrix(const char* szName, const aiMatrix4x4& sValue); + + // ------------------------------------------------------------------- + /** Get a configuration property. + * @param szName Name of the property. All supported properties + * are defined in the aiConfig.g header (all constants share the + * prefix AI_CONFIG_XXX). + * @param iErrorReturn Value that is returned if the property + * is not found. + * @return Current value of the property + * @note Property of different types (float, int, string ..) are kept + * on different lists, so calling SetPropertyInteger() for a + * floating-point property has no effect - the loader will call + * GetPropertyFloat() to read the property, but it won't be there. + */ + int GetPropertyInteger(const char* szName, + int iErrorReturn = 0xffffffff) const; + + // ------------------------------------------------------------------- + /** Get a boolean configuration property. Boolean properties + * are stored on the integer stack internally so it's possible + * to set them via #SetPropertyBool and query them with + * #GetPropertyBool and vice versa. + * @see GetPropertyInteger() + */ + bool GetPropertyBool(const char* szName, bool bErrorReturn = false) const { + return GetPropertyInteger(szName,bErrorReturn)!=0; + } + + // ------------------------------------------------------------------- + /** Get a floating-point configuration property + * @see GetPropertyInteger() + */ + ai_real GetPropertyFloat(const char* szName, + ai_real fErrorReturn = 10e10) const; + + // ------------------------------------------------------------------- + /** Get a string configuration property + * + * The return value remains valid until the property is modified. + * @see GetPropertyInteger() + */ + const std::string GetPropertyString(const char* szName, + const std::string& sErrorReturn = "") const; + + // ------------------------------------------------------------------- + /** Get a matrix configuration property + * + * The return value remains valid until the property is modified. + * @see GetPropertyInteger() + */ + const aiMatrix4x4 GetPropertyMatrix(const char* szName, + const aiMatrix4x4& sErrorReturn = aiMatrix4x4()) const; + + // ------------------------------------------------------------------- + /** Supplies a custom IO handler to the importer to use to open and + * access files. If you need the importer to use custom IO logic to + * access the files, you need to provide a custom implementation of + * IOSystem and IOFile to the importer. Then create an instance of + * your custom IOSystem implementation and supply it by this function. + * + * The Importer takes ownership of the object and will destroy it + * afterwards. The previously assigned handler will be deleted. + * Pass NULL to take again ownership of your IOSystem and reset Assimp + * to use its default implementation. + * + * @param pIOHandler The IO handler to be used in all file accesses + * of the Importer. + */ + void SetIOHandler( IOSystem* pIOHandler); + + // ------------------------------------------------------------------- + /** Retrieves the IO handler that is currently set. + * You can use #IsDefaultIOHandler() to check whether the returned + * interface is the default IO handler provided by ASSIMP. The default + * handler is active as long the application doesn't supply its own + * custom IO handler via #SetIOHandler(). + * @return A valid IOSystem interface, never NULL. + */ + IOSystem* GetIOHandler() const; + + // ------------------------------------------------------------------- + /** Checks whether a default IO handler is active + * A default handler is active as long the application doesn't + * supply its own custom IO handler via #SetIOHandler(). + * @return true by default + */ + bool IsDefaultIOHandler() const; + + // ------------------------------------------------------------------- + /** Supplies a custom progress handler to the importer. This + * interface exposes an #Update() callback, which is called + * more or less periodically (please don't sue us if it + * isn't as periodically as you'd like it to have ...). + * This can be used to implement progress bars and loading + * timeouts. + * @param pHandler Progress callback interface. Pass NULL to + * disable progress reporting. + * @note Progress handlers can be used to abort the loading + * at almost any time.*/ + void SetProgressHandler ( ProgressHandler* pHandler ); + + // ------------------------------------------------------------------- + /** Retrieves the progress handler that is currently set. + * You can use #IsDefaultProgressHandler() to check whether the returned + * interface is the default handler provided by ASSIMP. The default + * handler is active as long the application doesn't supply its own + * custom handler via #SetProgressHandler(). + * @return A valid ProgressHandler interface, never NULL. + */ + ProgressHandler* GetProgressHandler() const; + + // ------------------------------------------------------------------- + /** Checks whether a default progress handler is active + * A default handler is active as long the application doesn't + * supply its own custom progress handler via #SetProgressHandler(). + * @return true by default + */ + bool IsDefaultProgressHandler() const; + + // ------------------------------------------------------------------- + /** @brief Check whether a given set of post-processing flags + * is supported. + * + * Some flags are mutually exclusive, others are probably + * not available because your excluded them from your + * Assimp builds. Calling this function is recommended if + * you're unsure. + * + * @param pFlags Bitwise combination of the aiPostProcess flags. + * @return true if this flag combination is fine. + */ + bool ValidateFlags(unsigned int pFlags) const; + + // ------------------------------------------------------------------- + /** Reads the given file and returns its contents if successful. + * + * If the call succeeds, the contents of the file are returned as a + * pointer to an aiScene object. The returned data is intended to be + * read-only, the importer object keeps ownership of the data and will + * destroy it upon destruction. If the import fails, NULL is returned. + * A human-readable error description can be retrieved by calling + * GetErrorString(). The previous scene will be deleted during this call. + * @param pFile Path and filename to the file to be imported. + * @param pFlags Optional post processing steps to be executed after + * a successful import. Provide a bitwise combination of the + * #aiPostProcessSteps flags. If you wish to inspect the imported + * scene first in order to fine-tune your post-processing setup, + * consider to use #ApplyPostProcessing(). + * @return A pointer to the imported data, NULL if the import failed. + * The pointer to the scene remains in possession of the Importer + * instance. Use GetOrphanedScene() to take ownership of it. + * + * @note Assimp is able to determine the file format of a file + * automatically. + */ + const aiScene* ReadFile( + const char* pFile, + unsigned int pFlags); + + // ------------------------------------------------------------------- + /** Reads the given file from a memory buffer and returns its + * contents if successful. + * + * If the call succeeds, the contents of the file are returned as a + * pointer to an aiScene object. The returned data is intended to be + * read-only, the importer object keeps ownership of the data and will + * destroy it upon destruction. If the import fails, NULL is returned. + * A human-readable error description can be retrieved by calling + * GetErrorString(). The previous scene will be deleted during this call. + * Calling this method doesn't affect the active IOSystem. + * @param pBuffer Pointer to the file data + * @param pLength Length of pBuffer, in bytes + * @param pFlags Optional post processing steps to be executed after + * a successful import. Provide a bitwise combination of the + * #aiPostProcessSteps flags. If you wish to inspect the imported + * scene first in order to fine-tune your post-processing setup, + * consider to use #ApplyPostProcessing(). + * @param pHint An additional hint to the library. If this is a non + * empty string, the library looks for a loader to support + * the file extension specified by pHint and passes the file to + * the first matching loader. If this loader is unable to completely + * the request, the library continues and tries to determine the + * file format on its own, a task that may or may not be successful. + * Check the return value, and you'll know ... + * @return A pointer to the imported data, NULL if the import failed. + * The pointer to the scene remains in possession of the Importer + * instance. Use GetOrphanedScene() to take ownership of it. + * + * @note This is a straightforward way to decode models from memory + * buffers, but it doesn't handle model formats that spread their + * data across multiple files or even directories. Examples include + * OBJ or MD3, which outsource parts of their material info into + * external scripts. If you need full functionality, provide + * a custom IOSystem to make Assimp find these files and use + * the regular ReadFile() API. + */ + const aiScene* ReadFileFromMemory( + const void* pBuffer, + size_t pLength, + unsigned int pFlags, + const char* pHint = ""); + + // ------------------------------------------------------------------- + /** Apply post-processing to an already-imported scene. + * + * This is strictly equivalent to calling #ReadFile() with the same + * flags. However, you can use this separate function to inspect + * the imported scene first to fine-tune your post-processing setup. + * @param pFlags Provide a bitwise combination of the + * #aiPostProcessSteps flags. + * @return A pointer to the post-processed data. This is still the + * same as the pointer returned by #ReadFile(). However, if + * post-processing fails, the scene could now be NULL. + * That's quite a rare case, post processing steps are not really + * designed to 'fail'. To be exact, the #aiProcess_ValidateDS + * flag is currently the only post processing step which can actually + * cause the scene to be reset to NULL. + * + * @note The method does nothing if no scene is currently bound + * to the #Importer instance. */ + const aiScene* ApplyPostProcessing(unsigned int pFlags); + + const aiScene* ApplyCustomizedPostProcessing( BaseProcess *rootProcess, bool requestValidation ); + + // ------------------------------------------------------------------- + /** @brief Reads the given file and returns its contents if successful. + * + * This function is provided for backward compatibility. + * See the const char* version for detailed docs. + * @see ReadFile(const char*, pFlags) */ + const aiScene* ReadFile( + const std::string& pFile, + unsigned int pFlags); + + // ------------------------------------------------------------------- + /** Frees the current scene. + * + * The function does nothing if no scene has previously been + * read via ReadFile(). FreeScene() is called automatically by the + * destructor and ReadFile() itself. */ + void FreeScene( ); + + // ------------------------------------------------------------------- + /** Returns an error description of an error that occurred in ReadFile(). + * + * Returns an empty string if no error occurred. + * @return A description of the last error, an empty string if no + * error occurred. The string is never NULL. + * + * @note The returned function remains valid until one of the + * following methods is called: #ReadFile(), #FreeScene(). */ + const char* GetErrorString() const; + + // ------------------------------------------------------------------- + /** Returns the scene loaded by the last successful call to ReadFile() + * + * @return Current scene or NULL if there is currently no scene loaded */ + const aiScene* GetScene() const; + + // ------------------------------------------------------------------- + /** Returns the scene loaded by the last successful call to ReadFile() + * and releases the scene from the ownership of the Importer + * instance. The application is now responsible for deleting the + * scene. Any further calls to GetScene() or GetOrphanedScene() + * will return NULL - until a new scene has been loaded via ReadFile(). + * + * @return Current scene or NULL if there is currently no scene loaded + * @note Use this method with maximal caution, and only if you have to. + * By design, aiScene's are exclusively maintained, allocated and + * deallocated by Assimp and no one else. The reasoning behind this + * is the golden rule that deallocations should always be done + * by the module that did the original allocation because heaps + * are not necessarily shared. GetOrphanedScene() enforces you + * to delete the returned scene by yourself, but this will only + * be fine if and only if you're using the same heap as assimp. + * On Windows, it's typically fine provided everything is linked + * against the multithreaded-dll version of the runtime library. + * It will work as well for static linkage with Assimp.*/ + aiScene* GetOrphanedScene(); + + // ------------------------------------------------------------------- + /** Returns whether a given file extension is supported by ASSIMP. + * + * @param szExtension Extension to be checked. + * Must include a trailing dot '.'. Example: ".3ds", ".md3". + * Cases-insensitive. + * @return true if the extension is supported, false otherwise */ + bool IsExtensionSupported(const char* szExtension) const; + + // ------------------------------------------------------------------- + /** @brief Returns whether a given file extension is supported by ASSIMP. + * + * This function is provided for backward compatibility. + * See the const char* version for detailed and up-to-date docs. + * @see IsExtensionSupported(const char*) */ + inline bool IsExtensionSupported(const std::string& szExtension) const; + + // ------------------------------------------------------------------- + /** Get a full list of all file extensions supported by ASSIMP. + * + * If a file extension is contained in the list this does of course not + * mean that ASSIMP is able to load all files with this extension --- + * it simply means there is an importer loaded which claims to handle + * files with this file extension. + * @param szOut String to receive the extension list. + * Format of the list: "*.3ds;*.obj;*.dae". This is useful for + * use with the WinAPI call GetOpenFileName(Ex). */ + void GetExtensionList(aiString& szOut) const; + + // ------------------------------------------------------------------- + /** @brief Get a full list of all file extensions supported by ASSIMP. + * + * This function is provided for backward compatibility. + * See the aiString version for detailed and up-to-date docs. + * @see GetExtensionList(aiString&)*/ + inline void GetExtensionList(std::string& szOut) const; + + // ------------------------------------------------------------------- + /** Get the number of importers currently registered with Assimp. */ + size_t GetImporterCount() const; + + // ------------------------------------------------------------------- + /** Get meta data for the importer corresponding to a specific index.. + * + * For the declaration of #aiImporterDesc, include . + * @param index Index to query, must be within [0,GetImporterCount()) + * @return Importer meta data structure, NULL if the index does not + * exist or if the importer doesn't offer meta information ( + * importers may do this at the cost of being hated by their peers).*/ + const aiImporterDesc* GetImporterInfo(size_t index) const; + + // ------------------------------------------------------------------- + /** Find the importer corresponding to a specific index. + * + * @param index Index to query, must be within [0,GetImporterCount()) + * @return Importer instance. NULL if the index does not + * exist. */ + BaseImporter* GetImporter(size_t index) const; + + // ------------------------------------------------------------------- + /** Find the importer corresponding to a specific file extension. + * + * This is quite similar to #IsExtensionSupported except a + * BaseImporter instance is returned. + * @param szExtension Extension to check for. The following formats + * are recognized (BAH being the file extension): "BAH" (comparison + * is case-insensitive), ".bah", "*.bah" (wild card and dot + * characters at the beginning of the extension are skipped). + * @return NULL if no importer is found*/ + BaseImporter* GetImporter (const char* szExtension) const; + + // ------------------------------------------------------------------- + /** Find the importer index corresponding to a specific file extension. + * + * @param szExtension Extension to check for. The following formats + * are recognized (BAH being the file extension): "BAH" (comparison + * is case-insensitive), ".bah", "*.bah" (wild card and dot + * characters at the beginning of the extension are skipped). + * @return (size_t)-1 if no importer is found */ + size_t GetImporterIndex (const char* szExtension) const; + + // ------------------------------------------------------------------- + /** Returns the storage allocated by ASSIMP to hold the scene data + * in memory. + * + * This refers to the currently loaded file, see #ReadFile(). + * @param in Data structure to be filled. + * @note The returned memory statistics refer to the actual + * size of the use data of the aiScene. Heap-related overhead + * is (naturally) not included.*/ + void GetMemoryRequirements(aiMemoryInfo& in) const; + + // ------------------------------------------------------------------- + /** Enables "extra verbose" mode. + * + * 'Extra verbose' means the data structure is validated after *every* + * single post processing step to make sure everyone modifies the data + * structure in a well-defined manner. This is a debug feature and not + * intended for use in production environments. */ + void SetExtraVerbose(bool bDo); + + // ------------------------------------------------------------------- + /** Private, do not use. */ + ImporterPimpl* Pimpl() { return pimpl; } + const ImporterPimpl* Pimpl() const { return pimpl; } + +protected: + + // Just because we don't want you to know how we're hacking around. + ImporterPimpl* pimpl; +}; //! class Importer + + +// ---------------------------------------------------------------------------- +// For compatibility, the interface of some functions taking a std::string was +// changed to const char* to avoid crashes between binary incompatible STL +// versions. This code her is inlined, so it shouldn't cause any problems. +// ---------------------------------------------------------------------------- + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE const aiScene* Importer::ReadFile( const std::string& pFile,unsigned int pFlags){ + return ReadFile(pFile.c_str(),pFlags); +} +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE void Importer::GetExtensionList(std::string& szOut) const { + aiString s; + GetExtensionList(s); + szOut = s.data; +} +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE bool Importer::IsExtensionSupported(const std::string& szExtension) const { + return IsExtensionSupported(szExtension.c_str()); +} + +} // !namespace Assimp + +#endif // AI_ASSIMP_HPP_INC diff --git a/tools/ZAPD/ZAPD/assimp/LineSplitter.h b/tools/ZAPD/ZAPD/assimp/LineSplitter.h new file mode 100644 index 0000000000..4afe45b92a --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/LineSplitter.h @@ -0,0 +1,285 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file LineSplitter.h + * @brief LineSplitter, a helper class to iterate through all lines + * of a file easily. Works with StreamReader. + */ +#pragma once +#ifndef INCLUDED_LINE_SPLITTER_H +#define INCLUDED_LINE_SPLITTER_H + +#include +#include "StreamReader.h" +#include "ParsingUtils.h" + +namespace Assimp { + +// ------------------------------------------------------------------------------------------------ +/** Usage: +@code +for(LineSplitter splitter(stream);splitter;++splitter) { + + if (*splitter == "hi!") { + ... + } + else if (splitter->substr(0,5) == "hello") { + ... + // access the third token in the line (tokens are space-separated) + if (strtol(splitter[2]) > 5) { .. } + } + + std::cout << "Current line is: " << splitter.get_index() << std::endl; +} +@endcode +*/ +// ------------------------------------------------------------------------------------------------ +class LineSplitter { +public: + typedef size_t line_idx; + + // ----------------------------------------- + /** construct from existing stream reader + note: trim is *always* assumed true if skyp_empty_lines==true + */ + LineSplitter(StreamReaderLE& stream, bool skip_empty_lines = true, bool trim = true); + + ~LineSplitter(); + + // ----------------------------------------- + /** pseudo-iterator increment */ + LineSplitter& operator++(); + + // ----------------------------------------- + LineSplitter& operator++(int); + + // ----------------------------------------- + /** get a pointer to the beginning of a particular token */ + const char* operator[] (size_t idx) const; + + // ----------------------------------------- + /** extract the start positions of N tokens from the current line*/ + template + void get_tokens(const char* (&tokens)[N]) const; + + // ----------------------------------------- + /** member access */ + const std::string* operator -> () const; + + std::string operator* () const; + + // ----------------------------------------- + /** boolean context */ + operator bool() const; + + // ----------------------------------------- + /** line indices are zero-based, empty lines are included */ + operator line_idx() const; + + line_idx get_index() const; + + // ----------------------------------------- + /** access the underlying stream object */ + StreamReaderLE& get_stream(); + + // ----------------------------------------- + /** !strcmp((*this)->substr(0,strlen(check)),check) */ + bool match_start(const char* check); + + // ----------------------------------------- + /** swallow the next call to ++, return the previous value. */ + void swallow_next_increment(); + + LineSplitter( const LineSplitter & ) = delete; + LineSplitter(LineSplitter &&) = delete; + LineSplitter &operator = ( const LineSplitter & ) = delete; + +private: + line_idx mIdx; + std::string mCur; + StreamReaderLE& mStream; + bool mSwallow, mSkip_empty_lines, mTrim; +}; + +inline +LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool trim ) +: mIdx(0) +, mCur() +, mStream(stream) +, mSwallow() +, mSkip_empty_lines(skip_empty_lines) +, mTrim(trim) { + mCur.reserve(1024); + operator++(); + mIdx = 0; +} + +inline +LineSplitter::~LineSplitter() { + // empty +} + +inline +LineSplitter& LineSplitter::operator++() { + if (mSwallow) { + mSwallow = false; + return *this; + } + + if (!*this) { + throw std::logic_error("End of file, no more lines to be retrieved."); + } + + char s; + mCur.clear(); + while (mStream.GetRemainingSize() && (s = mStream.GetI1(), 1)) { + if (s == '\n' || s == '\r') { + if (mSkip_empty_lines) { + while (mStream.GetRemainingSize() && ((s = mStream.GetI1()) == ' ' || s == '\r' || s == '\n')); + if (mStream.GetRemainingSize()) { + mStream.IncPtr(-1); + } + } else { + // skip both potential line terminators but don't read past this line. + if (mStream.GetRemainingSize() && (s == '\r' && mStream.GetI1() != '\n')) { + mStream.IncPtr(-1); + } + if (mTrim) { + while (mStream.GetRemainingSize() && ((s = mStream.GetI1()) == ' ' || s == '\t')); + if (mStream.GetRemainingSize()) { + mStream.IncPtr(-1); + } + } + } + break; + } + mCur += s; + } + ++mIdx; + + return *this; +} + +inline +LineSplitter &LineSplitter::operator++(int) { + return ++(*this); +} + +inline +const char *LineSplitter::operator[] (size_t idx) const { + const char* s = operator->()->c_str(); + + SkipSpaces(&s); + for (size_t i = 0; i < idx; ++i) { + + for (; !IsSpace(*s); ++s) { + if (IsLineEnd(*s)) { + throw std::range_error("Token index out of range, EOL reached"); + } + } + SkipSpaces(&s); + } + return s; +} + +template +inline +void LineSplitter::get_tokens(const char* (&tokens)[N]) const { + const char* s = operator->()->c_str(); + + SkipSpaces(&s); + for (size_t i = 0; i < N; ++i) { + if (IsLineEnd(*s)) { + throw std::range_error("Token count out of range, EOL reached"); + } + tokens[i] = s; + + for (; *s && !IsSpace(*s); ++s); + SkipSpaces(&s); + } +} + +inline +const std::string* LineSplitter::operator -> () const { + return &mCur; +} + +inline +std::string LineSplitter::operator* () const { + return mCur; +} + +inline +LineSplitter::operator bool() const { + return mStream.GetRemainingSize() > 0; +} + +inline +LineSplitter::operator line_idx() const { + return mIdx; +} + +inline +LineSplitter::line_idx LineSplitter::get_index() const { + return mIdx; +} + +inline +StreamReaderLE &LineSplitter::get_stream() { + return mStream; +} + +inline +bool LineSplitter::match_start(const char* check) { + const size_t len = ::strlen(check); + + return len <= mCur.length() && std::equal(check, check + len, mCur.begin()); +} + +inline +void LineSplitter::swallow_next_increment() { + mSwallow = true; +} + +} // Namespace Assimp + +#endif // INCLUDED_LINE_SPLITTER_H diff --git a/tools/ZAPD/ZAPD/assimp/LogAux.h b/tools/ZAPD/ZAPD/assimp/LogAux.h new file mode 100644 index 0000000000..558485272e --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/LogAux.h @@ -0,0 +1,131 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file LogAux.h + * @brief Common logging usage patterns for importer implementations + */ +#ifndef INCLUDED_AI_LOGAUX_H +#define INCLUDED_AI_LOGAUX_H + +#include +#include +#include + +namespace Assimp { + +template +class LogFunctions { +public: + // ------------------------------------------------------------------------------------------------ + static void ThrowException(const std::string& msg) + { + throw DeadlyImportError(Prefix()+msg); + } + + // ------------------------------------------------------------------------------------------------ + static void LogWarn(const Formatter::format& message) { + if (!DefaultLogger::isNullLogger()) { + ASSIMP_LOG_WARN(Prefix()+(std::string)message); + } + } + + // ------------------------------------------------------------------------------------------------ + static void LogError(const Formatter::format& message) { + if (!DefaultLogger::isNullLogger()) { + ASSIMP_LOG_ERROR(Prefix()+(std::string)message); + } + } + + // ------------------------------------------------------------------------------------------------ + static void LogInfo(const Formatter::format& message) { + if (!DefaultLogger::isNullLogger()) { + ASSIMP_LOG_INFO(Prefix()+(std::string)message); + } + } + + // ------------------------------------------------------------------------------------------------ + static void LogDebug(const Formatter::format& message) { + if (!DefaultLogger::isNullLogger()) { + ASSIMP_LOG_DEBUG(Prefix()+(std::string)message); + } + } + + // https://sourceforge.net/tracker/?func=detail&atid=1067632&aid=3358562&group_id=226462 +#if !defined(__GNUC__) || !defined(__APPLE__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) + + // ------------------------------------------------------------------------------------------------ + static void LogWarn (const char* message) { + if (!DefaultLogger::isNullLogger()) { + LogWarn(Formatter::format(message)); + } + } + + // ------------------------------------------------------------------------------------------------ + static void LogError (const char* message) { + if (!DefaultLogger::isNullLogger()) { + LogError(Formatter::format(message)); + } + } + + // ------------------------------------------------------------------------------------------------ + static void LogInfo (const char* message) { + if (!DefaultLogger::isNullLogger()) { + LogInfo(Formatter::format(message)); + } + } + + // ------------------------------------------------------------------------------------------------ + static void LogDebug (const char* message) { + if (!DefaultLogger::isNullLogger()) { + LogDebug(Formatter::format(message)); + } + } + +#endif + +private: + static const char* Prefix(); + +}; +} // ! Assimp + +#endif diff --git a/tools/ZAPD/ZAPD/assimp/LogStream.hpp b/tools/ZAPD/ZAPD/assimp/LogStream.hpp new file mode 100644 index 0000000000..d0281e2d02 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/LogStream.hpp @@ -0,0 +1,111 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file LogStream.hpp + * @brief Abstract base class 'LogStream', representing an output log stream. + */ +#ifndef INCLUDED_AI_LOGSTREAM_H +#define INCLUDED_AI_LOGSTREAM_H + +#include "types.h" + +namespace Assimp { + +class IOSystem; + +// ------------------------------------------------------------------------------------ +/** @brief CPP-API: Abstract interface for log stream implementations. + * + * Several default implementations are provided, see #aiDefaultLogStream for more + * details. Writing your own implementation of LogStream is just necessary if these + * are not enough for your purpose. */ +class ASSIMP_API LogStream +#ifndef SWIG + : public Intern::AllocateFromAssimpHeap +#endif +{ +protected: + /** @brief Default constructor */ + LogStream() AI_NO_EXCEPT; + +public: + /** @brief Virtual destructor */ + virtual ~LogStream(); + + // ------------------------------------------------------------------- + /** @brief Overwrite this for your own output methods + * + * Log messages *may* consist of multiple lines and you shouldn't + * expect a consistent formatting. If you want custom formatting + * (e.g. generate HTML), supply a custom instance of Logger to + * #DefaultLogger:set(). Usually you can *expect* that a log message + * is exactly one line and terminated with a single \n character. + * @param message Message to be written */ + virtual void write(const char* message) = 0; + + // ------------------------------------------------------------------- + /** @brief Creates a default log stream + * @param streams Type of the default stream + * @param name For aiDefaultLogStream_FILE: name of the output file + * @param io For aiDefaultLogStream_FILE: IOSystem to be used to open the output + * file. Pass NULL for the default implementation. + * @return New LogStream instance. */ + static LogStream* createDefaultStream(aiDefaultLogStream stream, + const char* name = "AssimpLog.txt", + IOSystem* io = nullptr ); + +}; // !class LogStream + +inline +LogStream::LogStream() AI_NO_EXCEPT { + // empty +} + +inline +LogStream::~LogStream() { + // empty +} + +// ------------------------------------------------------------------------------------ +} // Namespace Assimp + +#endif diff --git a/tools/ZAPD/ZAPD/assimp/Logger.hpp b/tools/ZAPD/ZAPD/assimp/Logger.hpp new file mode 100644 index 0000000000..89cade6c33 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/Logger.hpp @@ -0,0 +1,305 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file Logger.hpp + * @brief Abstract base class 'Logger', base of the logging system. + */ +#ifndef INCLUDED_AI_LOGGER_H +#define INCLUDED_AI_LOGGER_H + +#include +#include + +namespace Assimp { + +class LogStream; + +// Maximum length of a log message. Longer messages are rejected. +#define MAX_LOG_MESSAGE_LENGTH 1024u + +// ---------------------------------------------------------------------------------- +/** @brief CPP-API: Abstract interface for logger implementations. + * Assimp provides a default implementation and uses it for almost all + * logging stuff ('DefaultLogger'). This class defines just basic logging + * behavior and is not of interest for you. Instead, take a look at #DefaultLogger. */ +class ASSIMP_API Logger +#ifndef SWIG + : public Intern::AllocateFromAssimpHeap +#endif +{ +public: + + // ---------------------------------------------------------------------- + /** @enum LogSeverity + * @brief Log severity to describe the granularity of logging. + */ + enum LogSeverity { + NORMAL, //!< Normal granularity of logging + VERBOSE //!< Debug infos will be logged, too + }; + + // ---------------------------------------------------------------------- + /** @enum ErrorSeverity + * @brief Description for severity of a log message. + * + * Every LogStream has a bitwise combination of these flags. + * A LogStream doesn't receive any messages of a specific type + * if it doesn't specify the corresponding ErrorSeverity flag. + */ + enum ErrorSeverity { + Debugging = 1, //!< Debug log message + Info = 2, //!< Info log message + Warn = 4, //!< Warn log message + Err = 8 //!< Error log message + }; + +public: + + /** @brief Virtual destructor */ + virtual ~Logger(); + + // ---------------------------------------------------------------------- + /** @brief Writes a debug message + * @param message Debug message*/ + void debug(const char* message); + void debug(const std::string &message); + + // ---------------------------------------------------------------------- + /** @brief Writes a info message + * @param message Info message*/ + void info(const char* message); + void info(const std::string &message); + + // ---------------------------------------------------------------------- + /** @brief Writes a warning message + * @param message Warn message*/ + void warn(const char* message); + void warn(const std::string &message); + + // ---------------------------------------------------------------------- + /** @brief Writes an error message + * @param message Error message*/ + void error(const char* message); + void error(const std::string &message); + + // ---------------------------------------------------------------------- + /** @brief Set a new log severity. + * @param log_severity New severity for logging*/ + void setLogSeverity(LogSeverity log_severity); + + // ---------------------------------------------------------------------- + /** @brief Get the current log severity*/ + LogSeverity getLogSeverity() const; + + // ---------------------------------------------------------------------- + /** @brief Attach a new log-stream + * + * The logger takes ownership of the stream and is responsible + * for its destruction (which is done using ::delete when the logger + * itself is destroyed). Call detachStream to detach a stream and to + * gain ownership of it again. + * @param pStream Log-stream to attach + * @param severity Message filter, specified which types of log + * messages are dispatched to the stream. Provide a bitwise + * combination of the ErrorSeverity flags. + * @return true if the stream has been attached, false otherwise.*/ + virtual bool attachStream(LogStream *pStream, + unsigned int severity = Debugging | Err | Warn | Info) = 0; + + // ---------------------------------------------------------------------- + /** @brief Detach a still attached stream from the logger (or + * modify the filter flags bits) + * @param pStream Log-stream instance for detaching + * @param severity Provide a bitwise combination of the ErrorSeverity + * flags. This value is &~ed with the current flags of the stream, + * if the result is 0 the stream is detached from the Logger and + * the caller retakes the possession of the stream. + * @return true if the stream has been detached, false otherwise.*/ + virtual bool detatchStream(LogStream *pStream, + unsigned int severity = Debugging | Err | Warn | Info) = 0; + +protected: + /** + * Default constructor + */ + Logger() AI_NO_EXCEPT; + + /** + * Construction with a given log severity + */ + explicit Logger(LogSeverity severity); + + // ---------------------------------------------------------------------- + /** + * @brief Called as a request to write a specific debug message + * @param message Debug message. Never longer than + * MAX_LOG_MESSAGE_LENGTH characters (excluding the '0'). + * @note The message string is only valid until the scope of + * the function is left. + */ + virtual void OnDebug(const char* message)= 0; + + // ---------------------------------------------------------------------- + /** + * @brief Called as a request to write a specific info message + * @param message Info message. Never longer than + * MAX_LOG_MESSAGE_LENGTH characters (ecxluding the '0'). + * @note The message string is only valid until the scope of + * the function is left. + */ + virtual void OnInfo(const char* message) = 0; + + // ---------------------------------------------------------------------- + /** + * @brief Called as a request to write a specific warn message + * @param message Warn message. Never longer than + * MAX_LOG_MESSAGE_LENGTH characters (exluding the '0'). + * @note The message string is only valid until the scope of + * the function is left. + */ + virtual void OnWarn(const char* essage) = 0; + + // ---------------------------------------------------------------------- + /** + * @brief Called as a request to write a specific error message + * @param message Error message. Never longer than + * MAX_LOG_MESSAGE_LENGTH characters (exluding the '0'). + * @note The message string is only valid until the scope of + * the function is left. + */ + virtual void OnError(const char* message) = 0; + +protected: + LogSeverity m_Severity; +}; + +// ---------------------------------------------------------------------------------- +// Default constructor +inline +Logger::Logger() AI_NO_EXCEPT +: m_Severity(NORMAL) { + // empty +} + +// ---------------------------------------------------------------------------------- +// Virtual destructor +inline +Logger::~Logger() { + // empty +} + +// ---------------------------------------------------------------------------------- +// Construction with given logging severity +inline +Logger::Logger(LogSeverity severity) +: m_Severity(severity) { + // empty +} + +// ---------------------------------------------------------------------------------- +// Log severity setter +inline +void Logger::setLogSeverity(LogSeverity log_severity){ + m_Severity = log_severity; +} + +// ---------------------------------------------------------------------------------- +// Log severity getter +inline +Logger::LogSeverity Logger::getLogSeverity() const { + return m_Severity; +} + +// ---------------------------------------------------------------------------------- +inline +void Logger::debug(const std::string &message) { + return debug(message.c_str()); +} + +// ---------------------------------------------------------------------------------- +inline +void Logger::error(const std::string &message) { + return error(message.c_str()); +} + +// ---------------------------------------------------------------------------------- +inline +void Logger::warn(const std::string &message) { + return warn(message.c_str()); +} + +// ---------------------------------------------------------------------------------- +inline +void Logger::info(const std::string &message) { + return info(message.c_str()); +} + +// ------------------------------------------------------------------------------------------------ +#define ASSIMP_LOG_WARN_F(string,...)\ + DefaultLogger::get()->warn((Formatter::format(string),__VA_ARGS__)) + +#define ASSIMP_LOG_ERROR_F(string,...)\ + DefaultLogger::get()->error((Formatter::format(string),__VA_ARGS__)) + +#define ASSIMP_LOG_DEBUG_F(string,...)\ + DefaultLogger::get()->debug((Formatter::format(string),__VA_ARGS__)) + +#define ASSIMP_LOG_INFO_F(string,...)\ + DefaultLogger::get()->info((Formatter::format(string),__VA_ARGS__)) + + +#define ASSIMP_LOG_WARN(string)\ + DefaultLogger::get()->warn(string) + +#define ASSIMP_LOG_ERROR(string)\ + DefaultLogger::get()->error(string) + +#define ASSIMP_LOG_DEBUG(string)\ + DefaultLogger::get()->debug(string) + +#define ASSIMP_LOG_INFO(string)\ + DefaultLogger::get()->info(string) + + +} // Namespace Assimp + +#endif // !! INCLUDED_AI_LOGGER_H diff --git a/tools/ZAPD/ZAPD/assimp/Macros.h b/tools/ZAPD/ZAPD/assimp/Macros.h new file mode 100644 index 0000000000..6515303372 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/Macros.h @@ -0,0 +1,49 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/* Helper macro to set a pointer to NULL in debug builds + */ +#if (defined ASSIMP_BUILD_DEBUG) +# define AI_DEBUG_INVALIDATE_PTR(x) x = NULL; +#else +# define AI_DEBUG_INVALIDATE_PTR(x) +#endif + diff --git a/tools/ZAPD/ZAPD/assimp/MathFunctions.h b/tools/ZAPD/ZAPD/assimp/MathFunctions.h new file mode 100644 index 0000000000..f49273bb34 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/MathFunctions.h @@ -0,0 +1,86 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2016, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +#pragma once + +/** @file MathFunctions.h +* @brief Implementation of math utility functions. + * +*/ + +#include + +namespace Assimp { +namespace Math { + +// TODO: use binary GCD for unsigned integers .... +template < typename IntegerType > +inline +IntegerType gcd( IntegerType a, IntegerType b ) { + const IntegerType zero = (IntegerType)0; + while ( true ) { + if ( a == zero ) + return b; + b %= a; + + if ( b == zero ) + return a; + a %= b; + } +} + +template < typename IntegerType > +inline +IntegerType lcm( IntegerType a, IntegerType b ) { + const IntegerType t = gcd (a,b); + if (!t) + return t; + return a / t * b; +} + +template +inline +T getEpsilon() { + return std::numeric_limits::epsilon(); +} + +} +} diff --git a/tools/ZAPD/ZAPD/assimp/MemoryIOWrapper.h b/tools/ZAPD/ZAPD/assimp/MemoryIOWrapper.h new file mode 100644 index 0000000000..c522787184 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/MemoryIOWrapper.h @@ -0,0 +1,244 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file MemoryIOWrapper.h + * Handy IOStream/IOSystem implemetation to read directly from a memory buffer */ +#ifndef AI_MEMORYIOSTREAM_H_INC +#define AI_MEMORYIOSTREAM_H_INC + +#include +#include +#include +#include + +namespace Assimp { + +#define AI_MEMORYIO_MAGIC_FILENAME "$$$___magic___$$$" +#define AI_MEMORYIO_MAGIC_FILENAME_LENGTH 17 + +// ---------------------------------------------------------------------------------- +/** Implementation of IOStream to read directly from a memory buffer */ +// ---------------------------------------------------------------------------------- +class MemoryIOStream : public IOStream { +public: + MemoryIOStream (const uint8_t* buff, size_t len, bool own = false) + : buffer (buff) + , length(len) + , pos((size_t)0) + , own(own) { + // empty + } + + ~MemoryIOStream () { + if(own) { + delete[] buffer; + } + } + + // ------------------------------------------------------------------- + // Read from stream + size_t Read(void* pvBuffer, size_t pSize, size_t pCount) { + ai_assert(nullptr != pvBuffer); + ai_assert(0 != pSize); + + const size_t cnt = std::min( pCount, (length-pos) / pSize); + const size_t ofs = pSize * cnt; + + ::memcpy(pvBuffer,buffer+pos,ofs); + pos += ofs; + + return cnt; + } + + // ------------------------------------------------------------------- + // Write to stream + size_t Write(const void* /*pvBuffer*/, size_t /*pSize*/,size_t /*pCount*/) { + ai_assert(false); // won't be needed + return 0; + } + + // ------------------------------------------------------------------- + // Seek specific position + aiReturn Seek(size_t pOffset, aiOrigin pOrigin) { + if (aiOrigin_SET == pOrigin) { + if (pOffset > length) { + return AI_FAILURE; + } + pos = pOffset; + } else if (aiOrigin_END == pOrigin) { + if (pOffset > length) { + return AI_FAILURE; + } + pos = length-pOffset; + } else { + if (pOffset+pos > length) { + return AI_FAILURE; + } + pos += pOffset; + } + return AI_SUCCESS; + } + + // ------------------------------------------------------------------- + // Get current seek position + size_t Tell() const { + return pos; + } + + // ------------------------------------------------------------------- + // Get size of file + size_t FileSize() const { + return length; + } + + // ------------------------------------------------------------------- + // Flush file contents + void Flush() { + ai_assert(false); // won't be needed + } + +private: + const uint8_t* buffer; + size_t length,pos; + bool own; +}; + +// --------------------------------------------------------------------------- +/** Dummy IO system to read from a memory buffer */ +class MemoryIOSystem : public IOSystem { +public: + /** Constructor. */ + MemoryIOSystem(const uint8_t* buff, size_t len, IOSystem* io) + : buffer(buff) + , length(len) + , existing_io(io) + , created_streams() { + // empty + } + + /** Destructor. */ + ~MemoryIOSystem() { + } + + // ------------------------------------------------------------------- + /** Tests for the existence of a file at the given path. */ + bool Exists(const char* pFile) const override { + if (0 == strncmp( pFile, AI_MEMORYIO_MAGIC_FILENAME, AI_MEMORYIO_MAGIC_FILENAME_LENGTH ) ) { + return true; + } + return existing_io ? existing_io->Exists(pFile) : false; + } + + // ------------------------------------------------------------------- + /** Returns the directory separator. */ + char getOsSeparator() const override { + return existing_io ? existing_io->getOsSeparator() + : '/'; // why not? it doesn't care + } + + // ------------------------------------------------------------------- + /** Open a new file with a given path. */ + IOStream* Open(const char* pFile, const char* pMode = "rb") override { + if ( 0 == strncmp( pFile, AI_MEMORYIO_MAGIC_FILENAME, AI_MEMORYIO_MAGIC_FILENAME_LENGTH ) ) { + created_streams.emplace_back(new MemoryIOStream(buffer, length)); + return created_streams.back(); + } + return existing_io ? existing_io->Open(pFile, pMode) : NULL; + } + + // ------------------------------------------------------------------- + /** Closes the given file and releases all resources associated with it. */ + void Close( IOStream* pFile) override { + auto it = std::find(created_streams.begin(), created_streams.end(), pFile); + if (it != created_streams.end()) { + delete pFile; + created_streams.erase(it); + } else if (existing_io) { + existing_io->Close(pFile); + } + } + + // ------------------------------------------------------------------- + /** Compare two paths */ + bool ComparePaths(const char* one, const char* second) const override { + return existing_io ? existing_io->ComparePaths(one, second) : false; + } + + bool PushDirectory( const std::string &path ) override { + return existing_io ? existing_io->PushDirectory(path) : false; + } + + const std::string &CurrentDirectory() const override { + static std::string empty; + return existing_io ? existing_io->CurrentDirectory() : empty; + } + + size_t StackSize() const override { + return existing_io ? existing_io->StackSize() : 0; + } + + bool PopDirectory() override { + return existing_io ? existing_io->PopDirectory() : false; + } + + bool CreateDirectory( const std::string &path ) override { + return existing_io ? existing_io->CreateDirectory(path) : false; + } + + bool ChangeDirectory( const std::string &path ) override { + return existing_io ? existing_io->ChangeDirectory(path) : false; + } + + bool DeleteFile( const std::string &file ) override { + return existing_io ? existing_io->DeleteFile(file) : false; + } + +private: + const uint8_t* buffer; + size_t length; + IOSystem* existing_io; + std::vector created_streams; +}; + +} // end namespace Assimp + +#endif diff --git a/tools/ZAPD/ZAPD/assimp/NullLogger.hpp b/tools/ZAPD/ZAPD/assimp/NullLogger.hpp new file mode 100644 index 0000000000..c45d01bd48 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/NullLogger.hpp @@ -0,0 +1,99 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file NullLogger.hpp + * @brief Dummy logger +*/ + +#ifndef INCLUDED_AI_NULLLOGGER_H +#define INCLUDED_AI_NULLLOGGER_H + +#include "Logger.hpp" + +namespace Assimp { + +// --------------------------------------------------------------------------- +/** @brief CPP-API: Empty logging implementation. + * + * Does nothing! Used by default if the application hasn't requested a + * custom logger via #DefaultLogger::set() or #DefaultLogger::create(); */ +class ASSIMP_API NullLogger + : public Logger { + +public: + + /** @brief Logs a debug message */ + void OnDebug(const char* message) { + (void)message; //this avoids compiler warnings + } + + /** @brief Logs an info message */ + void OnInfo(const char* message) { + (void)message; //this avoids compiler warnings + } + + /** @brief Logs a warning message */ + void OnWarn(const char* message) { + (void)message; //this avoids compiler warnings + } + + /** @brief Logs an error message */ + void OnError(const char* message) { + (void)message; //this avoids compiler warnings + } + + /** @brief Detach a still attached stream from logger */ + bool attachStream(LogStream *pStream, unsigned int severity) { + (void)pStream; (void)severity; //this avoids compiler warnings + return false; + } + + /** @brief Detach a still attached stream from logger */ + bool detatchStream(LogStream *pStream, unsigned int severity) { + (void)pStream; (void)severity; //this avoids compiler warnings + return false; + } + +private: +}; +} +#endif // !! AI_NULLLOGGER_H_INCLUDED diff --git a/tools/ZAPD/ZAPD/assimp/ParsingUtils.h b/tools/ZAPD/ZAPD/assimp/ParsingUtils.h new file mode 100644 index 0000000000..6b9574fc67 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/ParsingUtils.h @@ -0,0 +1,259 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + + +/** @file ParsingUtils.h + * @brief Defines helper functions for text parsing + */ +#ifndef AI_PARSING_UTILS_H_INC +#define AI_PARSING_UTILS_H_INC + +#include "StringComparison.h" +#include "StringUtils.h" +#include + +namespace Assimp { + +// NOTE: the functions below are mostly intended as replacement for +// std::upper, std::lower, std::isupper, std::islower, std::isspace. +// we don't bother of locales. We don't want them. We want reliable +// (i.e. identical) results across all locales. + +// The functions below accept any character type, but know only +// about ASCII. However, UTF-32 is the only safe ASCII superset to +// use since it doesn't have multi-byte sequences. + +static const unsigned int BufferSize = 4096; + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE +char_t ToLower( char_t in ) { + return (in >= (char_t)'A' && in <= (char_t)'Z') ? (char_t)(in+0x20) : in; +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE +char_t ToUpper( char_t in) { + return (in >= (char_t)'a' && in <= (char_t)'z') ? (char_t)(in-0x20) : in; +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE +bool IsUpper( char_t in) { + return (in >= (char_t)'A' && in <= (char_t)'Z'); +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE +bool IsLower( char_t in) { + return (in >= (char_t)'a' && in <= (char_t)'z'); +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE +bool IsSpace( char_t in) { + return (in == (char_t)' ' || in == (char_t)'\t'); +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE +bool IsLineEnd( char_t in) { + return (in==(char_t)'\r'||in==(char_t)'\n'||in==(char_t)'\0'||in==(char_t)'\f'); +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE +bool IsSpaceOrNewLine( char_t in) { + return IsSpace(in) || IsLineEnd(in); +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE +bool SkipSpaces( const char_t* in, const char_t** out) { + while( *in == ( char_t )' ' || *in == ( char_t )'\t' ) { + ++in; + } + *out = in; + return !IsLineEnd(*in); +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE +bool SkipSpaces( const char_t** inout) { + return SkipSpaces(*inout,inout); +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE +bool SkipLine( const char_t* in, const char_t** out) { + while( *in != ( char_t )'\r' && *in != ( char_t )'\n' && *in != ( char_t )'\0' ) { + ++in; + } + + // files are opened in binary mode. Ergo there are both NL and CR + while( *in == ( char_t )'\r' || *in == ( char_t )'\n' ) { + ++in; + } + *out = in; + return *in != (char_t)'\0'; +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE +bool SkipLine( const char_t** inout) { + return SkipLine(*inout,inout); +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE +bool SkipSpacesAndLineEnd( const char_t* in, const char_t** out) { + while( *in == ( char_t )' ' || *in == ( char_t )'\t' || *in == ( char_t )'\r' || *in == ( char_t )'\n' ) { + ++in; + } + *out = in; + return *in != '\0'; +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE +bool SkipSpacesAndLineEnd( const char_t** inout) { + return SkipSpacesAndLineEnd(*inout,inout); +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE +bool GetNextLine( const char_t*& buffer, char_t out[ BufferSize ] ) { + if( ( char_t )'\0' == *buffer ) { + return false; + } + + char* _out = out; + char* const end = _out + BufferSize; + while( !IsLineEnd( *buffer ) && _out < end ) { + *_out++ = *buffer++; + } + *_out = (char_t)'\0'; + + while( IsLineEnd( *buffer ) && '\0' != *buffer ) { + ++buffer; + } + + return true; +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE bool IsNumeric( char_t in) { + return ( in >= '0' && in <= '9' ) || '-' == in || '+' == in; +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE +bool TokenMatch(char_t*& in, const char* token, unsigned int len) +{ + if (!::strncmp(token,in,len) && IsSpaceOrNewLine(in[len])) { + if (in[len] != '\0') { + in += len+1; + } else { + // If EOF after the token make sure we don't go past end of buffer + in += len; + } + return true; + } + + return false; +} +// --------------------------------------------------------------------------------- +/** @brief Case-ignoring version of TokenMatch + * @param in Input + * @param token Token to check for + * @param len Number of characters to check + */ +AI_FORCE_INLINE +bool TokenMatchI(const char*& in, const char* token, unsigned int len) { + if (!ASSIMP_strincmp(token,in,len) && IsSpaceOrNewLine(in[len])) { + in += len+1; + return true; + } + return false; +} + +// --------------------------------------------------------------------------------- +AI_FORCE_INLINE +void SkipToken(const char*& in) { + SkipSpaces(&in); + while ( !IsSpaceOrNewLine( *in ) ) { + ++in; + } +} + +// --------------------------------------------------------------------------------- +AI_FORCE_INLINE +std::string GetNextToken(const char*& in) { + SkipSpacesAndLineEnd(&in); + const char* cur = in; + while ( !IsSpaceOrNewLine( *in ) ) { + ++in; + } + return std::string(cur,(size_t)(in-cur)); +} + +// --------------------------------------------------------------------------------- + +} // ! namespace Assimp + +#endif // ! AI_PARSING_UTILS_H_INC diff --git a/tools/ZAPD/ZAPD/assimp/Profiler.h b/tools/ZAPD/ZAPD/assimp/Profiler.h new file mode 100644 index 0000000000..6ff9d41c0a --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/Profiler.h @@ -0,0 +1,99 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file Profiler.h + * @brief Utility to measure the respective runtime of each import step + */ +#ifndef INCLUDED_PROFILER_H +#define INCLUDED_PROFILER_H + +#include +#include +#include "TinyFormatter.h" + +#include + +namespace Assimp { +namespace Profiling { + +using namespace Formatter; + +// ------------------------------------------------------------------------------------------------ +/** Simple wrapper around boost::timer to simplify reporting. Timings are automatically + * dumped to the log file. + */ +class Profiler { +public: + Profiler() { + // empty + } + +public: + + /** Start a named timer */ + void BeginRegion(const std::string& region) { + regions[region] = std::chrono::system_clock::now(); + ASSIMP_LOG_DEBUG((format("START `"),region,"`")); + } + + + /** End a specific named timer and write its end time to the log */ + void EndRegion(const std::string& region) { + RegionMap::const_iterator it = regions.find(region); + if (it == regions.end()) { + return; + } + + std::chrono::duration elapsedSeconds = std::chrono::system_clock::now() - regions[region]; + ASSIMP_LOG_DEBUG((format("END `"),region,"`, dt= ", elapsedSeconds.count()," s")); + } + +private: + typedef std::map> RegionMap; + RegionMap regions; +}; + +} +} + +#endif + diff --git a/tools/ZAPD/ZAPD/assimp/ProgressHandler.hpp b/tools/ZAPD/ZAPD/assimp/ProgressHandler.hpp new file mode 100644 index 0000000000..4e47f1d0a6 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/ProgressHandler.hpp @@ -0,0 +1,145 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file ProgressHandler.hpp + * @brief Abstract base class 'ProgressHandler'. + */ +#pragma once +#ifndef AI_PROGRESSHANDLER_H_INC +#define AI_PROGRESSHANDLER_H_INC + +#include "types.h" + +namespace Assimp { + +// ------------------------------------------------------------------------------------ +/** @brief CPP-API: Abstract interface for custom progress report receivers. + * + * Each #Importer instance maintains its own #ProgressHandler. The default + * implementation provided by Assimp doesn't do anything at all. */ +class ASSIMP_API ProgressHandler +#ifndef SWIG + : public Intern::AllocateFromAssimpHeap +#endif +{ +protected: + /// @brief Default constructor + ProgressHandler () AI_NO_EXCEPT { + // empty + } + +public: + /// @brief Virtual destructor. + virtual ~ProgressHandler () { + } + + // ------------------------------------------------------------------- + /** @brief Progress callback. + * @param percentage An estimate of the current loading progress, + * in percent. Or -1.f if such an estimate is not available. + * + * There are restriction on what you may do from within your + * implementation of this method: no exceptions may be thrown and no + * non-const #Importer methods may be called. It is + * not generally possible to predict the number of callbacks + * fired during a single import. + * + * @return Return false to abort loading at the next possible + * occasion (loaders and Assimp are generally allowed to perform + * all needed cleanup tasks prior to returning control to the + * caller). If the loading is aborted, #Importer::ReadFile() + * returns always NULL. + * */ + virtual bool Update(float percentage = -1.f) = 0; + + // ------------------------------------------------------------------- + /** @brief Progress callback for file loading steps + * @param numberOfSteps The number of total post-processing + * steps + * @param currentStep The index of the current post-processing + * step that will run, or equal to numberOfSteps if all of + * them has finished. This number is always strictly monotone + * increasing, although not necessarily linearly. + * + * @note This is currently only used at the start and the end + * of the file parsing. + * */ + virtual void UpdateFileRead(int currentStep /*= 0*/, int numberOfSteps /*= 0*/) { + float f = numberOfSteps ? currentStep / (float)numberOfSteps : 1.0f; + Update( f * 0.5f ); + } + + // ------------------------------------------------------------------- + /** @brief Progress callback for post-processing steps + * @param numberOfSteps The number of total post-processing + * steps + * @param currentStep The index of the current post-processing + * step that will run, or equal to numberOfSteps if all of + * them has finished. This number is always strictly monotone + * increasing, although not necessarily linearly. + * */ + virtual void UpdatePostProcess(int currentStep /*= 0*/, int numberOfSteps /*= 0*/) { + float f = numberOfSteps ? currentStep / (float)numberOfSteps : 1.0f; + Update( f * 0.5f + 0.5f ); + } + + + // ------------------------------------------------------------------- + /** @brief Progress callback for export steps. + * @param numberOfSteps The number of total processing + * steps + * @param currentStep The index of the current post-processing + * step that will run, or equal to numberOfSteps if all of + * them has finished. This number is always strictly monotone + * increasing, although not necessarily linearly. + * */ + virtual void UpdateFileWrite(int currentStep /*= 0*/, int numberOfSteps /*= 0*/) { + float f = numberOfSteps ? currentStep / (float)numberOfSteps : 1.0f; + Update(f * 0.5f); + } +}; // !class ProgressHandler + +// ------------------------------------------------------------------------------------ + +} // Namespace Assimp + +#endif // AI_PROGRESSHANDLER_H_INC diff --git a/tools/ZAPD/ZAPD/assimp/RemoveComments.h b/tools/ZAPD/ZAPD/assimp/RemoveComments.h new file mode 100644 index 0000000000..404b496719 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/RemoveComments.h @@ -0,0 +1,91 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file Declares a helper class, "CommentRemover", which can be + * used to remove comments (single and multi line) from a text file. + */ +#ifndef AI_REMOVE_COMMENTS_H_INC +#define AI_REMOVE_COMMENTS_H_INC + + +#include + +namespace Assimp { + +// --------------------------------------------------------------------------- +/** \brief Helper class to remove single and multi line comments from a file + * + * Some mesh formats like MD5 have comments that are quite similar + * to those in C or C++ so this code has been moved to a separate + * module. + */ +class ASSIMP_API CommentRemover +{ + // class cannot be instanced + CommentRemover() {} + +public: + + //! Remove single-line comments. The end of a line is + //! expected to be either NL or CR or NLCR. + //! \param szComment The start sequence of the comment, e.g. "//" + //! \param szBuffer Buffer to work with + //! \param chReplacement Character to be used as replacement + //! for commented lines. By default this is ' ' + static void RemoveLineComments(const char* szComment, + char* szBuffer, char chReplacement = ' '); + + //! Remove multi-line comments. The end of a line is + //! expected to be either NL or CR or NLCR. Multi-line comments + //! may not be nested (as in C). + //! \param szCommentStart The start sequence of the comment, e.g. "/*" + //! \param szCommentEnd The end sequence of the comment, e.g. "*/" + //! \param szBuffer Buffer to work with + //! \param chReplacement Character to be used as replacement + //! for commented lines. By default this is ' ' + static void RemoveMultiLineComments(const char* szCommentStart, + const char* szCommentEnd,char* szBuffer, + char chReplacement = ' '); +}; +} // ! Assimp + +#endif // !! AI_REMOVE_COMMENTS_H_INC diff --git a/tools/ZAPD/ZAPD/assimp/SGSpatialSort.h b/tools/ZAPD/ZAPD/assimp/SGSpatialSort.h new file mode 100644 index 0000000000..5b4f3f41f2 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/SGSpatialSort.h @@ -0,0 +1,150 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** Small helper classes to optimize finding vertices close to a given location + */ +#ifndef AI_D3DSSPATIALSORT_H_INC +#define AI_D3DSSPATIALSORT_H_INC + +#include +#include +#include + +namespace Assimp { + +// ---------------------------------------------------------------------------------- +/** Specialized version of SpatialSort to support smoothing groups + * This is used in by the 3DS, ASE and LWO loaders. 3DS and ASE share their + * normal computation code in SmoothingGroups.inl, the LWO loader has its own + * implementation to handle all details of its file format correctly. + */ +// ---------------------------------------------------------------------------------- +class ASSIMP_API SGSpatialSort +{ +public: + + SGSpatialSort(); + + // ------------------------------------------------------------------- + /** Construction from a given face array, handling smoothing groups + * properly + */ + explicit SGSpatialSort(const std::vector& vPositions); + + // ------------------------------------------------------------------- + /** Add a vertex to the spatial sort + * @param vPosition Vertex position to be added + * @param index Index of the vrtex + * @param smoothingGroup SmoothingGroup for this vertex + */ + void Add(const aiVector3D& vPosition, unsigned int index, + unsigned int smoothingGroup); + + // ------------------------------------------------------------------- + /** Prepare the spatial sorter for use. This step runs in O(logn) + */ + void Prepare(); + + /** Destructor */ + ~SGSpatialSort(); + + // ------------------------------------------------------------------- + /** Returns an iterator for all positions close to the given position. + * @param pPosition The position to look for vertices. + * @param pSG Only included vertices with at least one shared smooth group + * @param pRadius Maximal distance from the position a vertex may have + * to be counted in. + * @param poResults The container to store the indices of the found + * positions. Will be emptied by the call so it may contain anything. + * @param exactMatch Specifies whether smoothing groups are bit masks + * (false) or integral values (true). In the latter case, a vertex + * cannot belong to more than one smoothing group. + * @return An iterator to iterate over all vertices in the given area. + */ + // ------------------------------------------------------------------- + void FindPositions( const aiVector3D& pPosition, uint32_t pSG, + float pRadius, std::vector& poResults, + bool exactMatch = false) const; + +protected: + /** Normal of the sorting plane, normalized. The center is always at (0, 0, 0) */ + aiVector3D mPlaneNormal; + + // ------------------------------------------------------------------- + /** An entry in a spatially sorted position array. Consists of a + * vertex index, its position and its pre-calculated distance from + * the reference plane */ + // ------------------------------------------------------------------- + struct Entry { + unsigned int mIndex; ///< The vertex referred by this entry + aiVector3D mPosition; ///< Position + uint32_t mSmoothGroups; + float mDistance; ///< Distance of this vertex to the sorting plane + + Entry() AI_NO_EXCEPT + : mIndex(0) + , mPosition() + , mSmoothGroups(0) + , mDistance(0.0f) { + // empty + } + + Entry( unsigned int pIndex, const aiVector3D& pPosition, float pDistance,uint32_t pSG) + : mIndex( pIndex) + , mPosition( pPosition) + , mSmoothGroups(pSG) + , mDistance( pDistance) { + // empty + } + + bool operator < (const Entry& e) const { + return mDistance < e.mDistance; + } + }; + + // all positions, sorted by distance to the sorting plane + std::vector mPositions; +}; + +} // end of namespace Assimp + +#endif // AI_SPATIALSORT_H_INC diff --git a/tools/ZAPD/ZAPD/assimp/SceneCombiner.h b/tools/ZAPD/ZAPD/assimp/SceneCombiner.h new file mode 100644 index 0000000000..f69a25f43b --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/SceneCombiner.h @@ -0,0 +1,403 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file Declares a helper class, "SceneCombiner" providing various + * utilities to merge scenes. + */ +#ifndef AI_SCENE_COMBINER_H_INC +#define AI_SCENE_COMBINER_H_INC + +#include +#include +#include +#include +#include +#include +#include + +#include + +struct aiScene; +struct aiNode; +struct aiMaterial; +struct aiTexture; +struct aiCamera; +struct aiLight; +struct aiMetadata; +struct aiBone; +struct aiMesh; +struct aiAnimMesh; +struct aiAnimation; +struct aiNodeAnim; + +namespace Assimp { + +// --------------------------------------------------------------------------- +/** \brief Helper data structure for SceneCombiner. + * + * Describes to which node a scene must be attached to. + */ +struct AttachmentInfo +{ + AttachmentInfo() + : scene (NULL) + , attachToNode (NULL) + {} + + AttachmentInfo(aiScene* _scene, aiNode* _attachToNode) + : scene (_scene) + , attachToNode (_attachToNode) + {} + + aiScene* scene; + aiNode* attachToNode; +}; + +// --------------------------------------------------------------------------- +struct NodeAttachmentInfo +{ + NodeAttachmentInfo() + : node (NULL) + , attachToNode (NULL) + , resolved (false) + , src_idx (SIZE_MAX) + {} + + NodeAttachmentInfo(aiNode* _scene, aiNode* _attachToNode,size_t idx) + : node (_scene) + , attachToNode (_attachToNode) + , resolved (false) + , src_idx (idx) + {} + + aiNode* node; + aiNode* attachToNode; + bool resolved; + size_t src_idx; +}; + +// --------------------------------------------------------------------------- +/** @def AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES + * Generate unique names for all named scene items + */ +#define AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES 0x1 + +/** @def AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES + * Generate unique names for materials, too. + * This is not absolutely required to pass the validation. + */ +#define AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES 0x2 + +/** @def AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY + * Use deep copies of duplicate scenes + */ +#define AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY 0x4 + +/** @def AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS + * If attachment nodes are not found in the given master scene, + * search the other imported scenes for them in an any order. + */ +#define AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS 0x8 + +/** @def AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY + * Can be combined with AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES. + * Unique names are generated, but only if this is absolutely + * required to avoid name conflicts. + */ +#define AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY 0x10 + +typedef std::pair BoneSrcIndex; + +// --------------------------------------------------------------------------- +/** @brief Helper data structure for SceneCombiner::MergeBones. + */ +struct BoneWithHash : public std::pair { + std::vector pSrcBones; +}; + +// --------------------------------------------------------------------------- +/** @brief Utility for SceneCombiner + */ +struct SceneHelper +{ + SceneHelper () + : scene (NULL) + , idlen (0) + { + id[0] = 0; + } + + explicit SceneHelper (aiScene* _scene) + : scene (_scene) + , idlen (0) + { + id[0] = 0; + } + + AI_FORCE_INLINE aiScene* operator-> () const + { + return scene; + } + + // scene we're working on + aiScene* scene; + + // prefix to be added to all identifiers in the scene ... + char id [32]; + + // and its strlen() + unsigned int idlen; + + // hash table to quickly check whether a name is contained in the scene + std::set hashes; +}; + +// --------------------------------------------------------------------------- +/** \brief Static helper class providing various utilities to merge two + * scenes. It is intended as internal utility and NOT for use by + * applications. + * + * The class is currently being used by various postprocessing steps + * and loaders (ie. LWS). + */ +class ASSIMP_API SceneCombiner { + // class cannot be instanced + SceneCombiner() { + // empty + } + + ~SceneCombiner() { + // empty + } + +public: + // ------------------------------------------------------------------- + /** Merges two or more scenes. + * + * @param dest Receives a pointer to the destination scene. If the + * pointer doesn't point to NULL when the function is called, the + * existing scene is cleared and refilled. + * @param src Non-empty list of scenes to be merged. The function + * deletes the input scenes afterwards. There may be duplicate scenes. + * @param flags Combination of the AI_INT_MERGE_SCENE flags defined above + */ + static void MergeScenes(aiScene** dest,std::vector& src, + unsigned int flags = 0); + + // ------------------------------------------------------------------- + /** Merges two or more scenes and attaches all scenes to a specific + * position in the node graph of the master scene. + * + * @param dest Receives a pointer to the destination scene. If the + * pointer doesn't point to NULL when the function is called, the + * existing scene is cleared and refilled. + * @param master Master scene. It will be deleted afterwards. All + * other scenes will be inserted in its node graph. + * @param src Non-empty list of scenes to be merged along with their + * corresponding attachment points in the master scene. The function + * deletes the input scenes afterwards. There may be duplicate scenes. + * @param flags Combination of the AI_INT_MERGE_SCENE flags defined above + */ + static void MergeScenes(aiScene** dest, aiScene* master, + std::vector& src, + unsigned int flags = 0); + + // ------------------------------------------------------------------- + /** Merges two or more meshes + * + * The meshes should have equal vertex formats. Only components + * that are provided by ALL meshes will be present in the output mesh. + * An exception is made for VColors - they are set to black. The + * meshes should have the same material indices, too. The output + * material index is always the material index of the first mesh. + * + * @param dest Destination mesh. Must be empty. + * @param flags Currently no parameters + * @param begin First mesh to be processed + * @param end Points to the mesh after the last mesh to be processed + */ + static void MergeMeshes(aiMesh** dest,unsigned int flags, + std::vector::const_iterator begin, + std::vector::const_iterator end); + + // ------------------------------------------------------------------- + /** Merges two or more bones + * + * @param out Mesh to receive the output bone list + * @param flags Currently no parameters + * @param begin First mesh to be processed + * @param end Points to the mesh after the last mesh to be processed + */ + static void MergeBones(aiMesh* out,std::vector::const_iterator it, + std::vector::const_iterator end); + + // ------------------------------------------------------------------- + /** Merges two or more materials + * + * The materials should be complementary as much as possible. In case + * of a property present in different materials, the first occurrence + * is used. + * + * @param dest Destination material. Must be empty. + * @param begin First material to be processed + * @param end Points to the material after the last material to be processed + */ + static void MergeMaterials(aiMaterial** dest, + std::vector::const_iterator begin, + std::vector::const_iterator end); + + // ------------------------------------------------------------------- + /** Builds a list of uniquely named bones in a mesh list + * + * @param asBones Receives the output list + * @param it First mesh to be processed + * @param end Last mesh to be processed + */ + static void BuildUniqueBoneList(std::list& asBones, + std::vector::const_iterator it, + std::vector::const_iterator end); + + // ------------------------------------------------------------------- + /** Add a name prefix to all nodes in a scene. + * + * @param Current node. This function is called recursively. + * @param prefix Prefix to be added to all nodes + * @param len STring length + */ + static void AddNodePrefixes(aiNode* node, const char* prefix, + unsigned int len); + + // ------------------------------------------------------------------- + /** Add an offset to all mesh indices in a node graph + * + * @param Current node. This function is called recursively. + * @param offset Offset to be added to all mesh indices + */ + static void OffsetNodeMeshIndices (aiNode* node, unsigned int offset); + + // ------------------------------------------------------------------- + /** Attach a list of node graphs to well-defined nodes in a master + * graph. This is a helper for MergeScenes() + * + * @param master Master scene + * @param srcList List of source scenes along with their attachment + * points. If an attachment point is NULL (or does not exist in + * the master graph), a scene is attached to the root of the master + * graph (as an additional child node) + * @duplicates List of duplicates. If elem[n] == n the scene is not + * a duplicate. Otherwise elem[n] links scene n to its first occurrence. + */ + static void AttachToGraph ( aiScene* master, + std::vector& srcList); + + static void AttachToGraph (aiNode* attach, + std::vector& srcList); + + + // ------------------------------------------------------------------- + /** Get a deep copy of a scene + * + * @param dest Receives a pointer to the destination scene + * @param src Source scene - remains unmodified. + */ + static void CopyScene(aiScene** dest,const aiScene* source,bool allocate = true); + + + // ------------------------------------------------------------------- + /** Get a flat copy of a scene + * + * Only the first hierarchy layer is copied. All pointer members of + * aiScene are shared by source and destination scene. If the + * pointer doesn't point to NULL when the function is called, the + * existing scene is cleared and refilled. + * @param dest Receives a pointer to the destination scene + * @param src Source scene - remains unmodified. + */ + static void CopySceneFlat(aiScene** dest,const aiScene* source); + + + // ------------------------------------------------------------------- + /** Get a deep copy of a mesh + * + * @param dest Receives a pointer to the destination mesh + * @param src Source mesh - remains unmodified. + */ + static void Copy (aiMesh** dest, const aiMesh* src); + + // similar to Copy(): + static void Copy (aiAnimMesh** dest, const aiAnimMesh* src); + static void Copy (aiMaterial** dest, const aiMaterial* src); + static void Copy (aiTexture** dest, const aiTexture* src); + static void Copy (aiAnimation** dest, const aiAnimation* src); + static void Copy (aiCamera** dest, const aiCamera* src); + static void Copy (aiBone** dest, const aiBone* src); + static void Copy (aiLight** dest, const aiLight* src); + static void Copy (aiNodeAnim** dest, const aiNodeAnim* src); + static void Copy (aiMetadata** dest, const aiMetadata* src); + + // recursive, of course + static void Copy (aiNode** dest, const aiNode* src); + + +private: + + // ------------------------------------------------------------------- + // Same as AddNodePrefixes, but with an additional check + static void AddNodePrefixesChecked(aiNode* node, const char* prefix, + unsigned int len, + std::vector& input, + unsigned int cur); + + // ------------------------------------------------------------------- + // Add node identifiers to a hashing set + static void AddNodeHashes(aiNode* node, std::set& hashes); + + + // ------------------------------------------------------------------- + // Search for duplicate names + static bool FindNameMatch(const aiString& name, + std::vector& input, unsigned int cur); +}; + +} + +#endif // !! AI_SCENE_COMBINER_H_INC diff --git a/tools/ZAPD/ZAPD/assimp/SkeletonMeshBuilder.h b/tools/ZAPD/ZAPD/assimp/SkeletonMeshBuilder.h new file mode 100644 index 0000000000..f9b8d9f55c --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/SkeletonMeshBuilder.h @@ -0,0 +1,125 @@ +/** Helper class to construct a dummy mesh for file formats containing only motion data */ + +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above +copyright notice, this list of conditions and the +following disclaimer. + +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other +materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its +contributors may be used to endorse or promote products +derived from this software without specific prior +written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file SkeletonMeshBuilder.h + * Declares SkeletonMeshBuilder, a tiny utility to build dummy meshes + * for animation skeletons. + */ + +#ifndef AI_SKELETONMESHBUILDER_H_INC +#define AI_SKELETONMESHBUILDER_H_INC + +#include +#include + +struct aiMaterial; +struct aiScene; +struct aiNode; + +namespace Assimp { + +// --------------------------------------------------------------------------- +/** + * This little helper class constructs a dummy mesh for a given scene + * the resembles the node hierarchy. This is useful for file formats + * that don't carry any mesh data but only animation data. + */ +class ASSIMP_API SkeletonMeshBuilder +{ +public: + + // ------------------------------------------------------------------- + /** The constructor processes the given scene and adds a mesh there. + * + * Does nothing if the scene already has mesh data. + * @param pScene The scene for which a skeleton mesh should be constructed. + * @param root The node to start with. NULL is the scene root + * @param bKnobsOnly Set this to true if you don't want the connectors + * between the knobs representing the nodes. + */ + SkeletonMeshBuilder( aiScene* pScene, aiNode* root = NULL, + bool bKnobsOnly = false); + +protected: + + // ------------------------------------------------------------------- + /** Recursively builds a simple mesh representation for the given node + * and also creates a joint for the node that affects this part of + * the mesh. + * @param pNode The node to build geometry for. + */ + void CreateGeometry( const aiNode* pNode); + + // ------------------------------------------------------------------- + /** Creates the mesh from the internally accumulated stuff and returns it. + */ + aiMesh* CreateMesh(); + + // ------------------------------------------------------------------- + /** Creates a dummy material and returns it. */ + aiMaterial* CreateMaterial(); + +protected: + /** space to assemble the mesh data: points */ + std::vector mVertices; + + /** faces */ + struct Face + { + unsigned int mIndices[3]; + Face(); + Face( unsigned int p0, unsigned int p1, unsigned int p2) + { mIndices[0] = p0; mIndices[1] = p1; mIndices[2] = p2; } + }; + std::vector mFaces; + + /** bones */ + std::vector mBones; + + bool mKnobsOnly; +}; + +} // end of namespace Assimp + +#endif // AI_SKELETONMESHBUILDER_H_INC diff --git a/tools/ZAPD/ZAPD/assimp/SmoothingGroups.h b/tools/ZAPD/ZAPD/assimp/SmoothingGroups.h new file mode 100644 index 0000000000..92d65cea02 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/SmoothingGroups.h @@ -0,0 +1,108 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file Defines the helper data structures for importing 3DS files. +http://www.jalix.org/ressources/graphics/3DS/_unofficials/3ds-unofficial.txt */ + +#ifndef AI_SMOOTHINGGROUPS_H_INC +#define AI_SMOOTHINGGROUPS_H_INC + +#include +#include +#include + +// --------------------------------------------------------------------------- +/** Helper structure representing a face with smoothing groups assigned */ +struct FaceWithSmoothingGroup { + FaceWithSmoothingGroup() AI_NO_EXCEPT + : mIndices() + , iSmoothGroup(0) { + // in debug builds set all indices to a common magic value +#ifdef ASSIMP_BUILD_DEBUG + this->mIndices[0] = 0xffffffff; + this->mIndices[1] = 0xffffffff; + this->mIndices[2] = 0xffffffff; +#endif + } + + + //! Indices. .3ds is using uint16. However, after + //! an unique vertex set has been generated, + //! individual index values might exceed 2^16 + uint32_t mIndices[3]; + + //! specifies to which smoothing group the face belongs to + uint32_t iSmoothGroup; +}; + +// --------------------------------------------------------------------------- +/** Helper structure representing a mesh whose faces have smoothing + groups assigned. This allows us to reuse the code for normal computations + from smoothings groups for several loaders (3DS, ASE). All of them + use face structures which inherit from #FaceWithSmoothingGroup, + but as they add extra members and need to be copied by value we + need to use a template here. + */ +template +struct MeshWithSmoothingGroups +{ + //! Vertex positions + std::vector mPositions; + + //! Face lists + std::vector mFaces; + + //! List of normal vectors + std::vector mNormals; +}; + +// --------------------------------------------------------------------------- +/** Computes normal vectors for the mesh + */ +template +void ComputeNormalsWithSmoothingsGroups(MeshWithSmoothingGroups& sMesh); + + +// include implementations +#include "SmoothingGroups.inl" + +#endif // !! AI_SMOOTHINGGROUPS_H_INC diff --git a/tools/ZAPD/ZAPD/assimp/SmoothingGroups.inl b/tools/ZAPD/ZAPD/assimp/SmoothingGroups.inl new file mode 100644 index 0000000000..84ea4a1b00 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/SmoothingGroups.inl @@ -0,0 +1,138 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file Generation of normal vectors basing on smoothing groups */ + +#ifndef AI_SMOOTHINGGROUPS_INL_INCLUDED +#define AI_SMOOTHINGGROUPS_INL_INCLUDED + +// internal headers +#include + +// CRT header +#include + +using namespace Assimp; + +// ------------------------------------------------------------------------------------------------ +template +void ComputeNormalsWithSmoothingsGroups(MeshWithSmoothingGroups& sMesh) +{ + // First generate face normals + sMesh.mNormals.resize(sMesh.mPositions.size(),aiVector3D()); + for( unsigned int a = 0; a < sMesh.mFaces.size(); a++) + { + T& face = sMesh.mFaces[a]; + + aiVector3D* pV1 = &sMesh.mPositions[face.mIndices[0]]; + aiVector3D* pV2 = &sMesh.mPositions[face.mIndices[1]]; + aiVector3D* pV3 = &sMesh.mPositions[face.mIndices[2]]; + + aiVector3D pDelta1 = *pV2 - *pV1; + aiVector3D pDelta2 = *pV3 - *pV1; + aiVector3D vNor = pDelta1 ^ pDelta2; + + for (unsigned int c = 0; c < 3;++c) + sMesh.mNormals[face.mIndices[c]] = vNor; + } + + // calculate the position bounds so we have a reliable epsilon to check position differences against + aiVector3D minVec( 1e10f, 1e10f, 1e10f), maxVec( -1e10f, -1e10f, -1e10f); + for( unsigned int a = 0; a < sMesh.mPositions.size(); a++) + { + minVec.x = std::min( minVec.x, sMesh.mPositions[a].x); + minVec.y = std::min( minVec.y, sMesh.mPositions[a].y); + minVec.z = std::min( minVec.z, sMesh.mPositions[a].z); + maxVec.x = std::max( maxVec.x, sMesh.mPositions[a].x); + maxVec.y = std::max( maxVec.y, sMesh.mPositions[a].y); + maxVec.z = std::max( maxVec.z, sMesh.mPositions[a].z); + } + const float posEpsilon = (maxVec - minVec).Length() * 1e-5f; + std::vector avNormals; + avNormals.resize(sMesh.mNormals.size()); + + // now generate the spatial sort tree + SGSpatialSort sSort; + for( typename std::vector::iterator i = sMesh.mFaces.begin(); + i != sMesh.mFaces.end();++i) + { + for (unsigned int c = 0; c < 3;++c) + sSort.Add(sMesh.mPositions[(*i).mIndices[c]],(*i).mIndices[c],(*i).iSmoothGroup); + } + sSort.Prepare(); + + std::vector vertexDone(sMesh.mPositions.size(),false); + for( typename std::vector::iterator i = sMesh.mFaces.begin(); + i != sMesh.mFaces.end();++i) + { + std::vector poResult; + for (unsigned int c = 0; c < 3;++c) + { + unsigned int idx = (*i).mIndices[c]; + if (vertexDone[idx])continue; + + sSort.FindPositions(sMesh.mPositions[idx],(*i).iSmoothGroup, + posEpsilon,poResult); + + aiVector3D vNormals; + for (std::vector::const_iterator + a = poResult.begin(); + a != poResult.end();++a) + { + vNormals += sMesh.mNormals[(*a)]; + } + vNormals.NormalizeSafe(); + + // write back into all affected normals + for (std::vector::const_iterator + a = poResult.begin(); + a != poResult.end();++a) + { + idx = *a; + avNormals [idx] = vNormals; + vertexDone[idx] = true; + } + } + } + sMesh.mNormals = avNormals; +} + +#endif // !! AI_SMOOTHINGGROUPS_INL_INCLUDED diff --git a/tools/ZAPD/ZAPD/assimp/SpatialSort.h b/tools/ZAPD/ZAPD/assimp/SpatialSort.h new file mode 100644 index 0000000000..61b345bcbf --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/SpatialSort.h @@ -0,0 +1,174 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** Small helper classes to optimise finding vertizes close to a given location */ +#ifndef AI_SPATIALSORT_H_INC +#define AI_SPATIALSORT_H_INC + +#include +#include + +namespace Assimp { + +// ------------------------------------------------------------------------------------------------ +/** A little helper class to quickly find all vertices in the epsilon environment of a given + * position. Construct an instance with an array of positions. The class stores the given positions + * by their indices and sorts them by their distance to an arbitrary chosen plane. + * You can then query the instance for all vertices close to a given position in an average O(log n) + * time, with O(n) worst case complexity when all vertices lay on the plane. The plane is chosen + * so that it avoids common planes in usual data sets. */ +// ------------------------------------------------------------------------------------------------ +class ASSIMP_API SpatialSort +{ +public: + + SpatialSort(); + + // ------------------------------------------------------------------------------------ + /** Constructs a spatially sorted representation from the given position array. + * Supply the positions in its layout in memory, the class will only refer to them + * by index. + * @param pPositions Pointer to the first position vector of the array. + * @param pNumPositions Number of vectors to expect in that array. + * @param pElementOffset Offset in bytes from the beginning of one vector in memory + * to the beginning of the next vector. */ + SpatialSort( const aiVector3D* pPositions, unsigned int pNumPositions, + unsigned int pElementOffset); + + /** Destructor */ + ~SpatialSort(); + +public: + + // ------------------------------------------------------------------------------------ + /** Sets the input data for the SpatialSort. This replaces existing data, if any. + * The new data receives new indices in ascending order. + * + * @param pPositions Pointer to the first position vector of the array. + * @param pNumPositions Number of vectors to expect in that array. + * @param pElementOffset Offset in bytes from the beginning of one vector in memory + * to the beginning of the next vector. + * @param pFinalize Specifies whether the SpatialSort's internal representation + * is finalized after the new data has been added. Finalization is + * required in order to use #FindPosition() or #GenerateMappingTable(). + * If you don't finalize yet, you can use #Append() to add data from + * other sources.*/ + void Fill( const aiVector3D* pPositions, unsigned int pNumPositions, + unsigned int pElementOffset, + bool pFinalize = true); + + + // ------------------------------------------------------------------------------------ + /** Same as #Fill(), except the method appends to existing data in the #SpatialSort. */ + void Append( const aiVector3D* pPositions, unsigned int pNumPositions, + unsigned int pElementOffset, + bool pFinalize = true); + + + // ------------------------------------------------------------------------------------ + /** Finalize the spatial hash data structure. This can be useful after + * multiple calls to #Append() with the pFinalize parameter set to false. + * This is finally required before one of #FindPositions() and #GenerateMappingTable() + * can be called to query the spatial sort.*/ + void Finalize(); + + // ------------------------------------------------------------------------------------ + /** Returns an iterator for all positions close to the given position. + * @param pPosition The position to look for vertices. + * @param pRadius Maximal distance from the position a vertex may have to be counted in. + * @param poResults The container to store the indices of the found positions. + * Will be emptied by the call so it may contain anything. + * @return An iterator to iterate over all vertices in the given area.*/ + void FindPositions( const aiVector3D& pPosition, ai_real pRadius, + std::vector& poResults) const; + + // ------------------------------------------------------------------------------------ + /** Fills an array with indices of all positions identical to the given position. In + * opposite to FindPositions(), not an epsilon is used but a (very low) tolerance of + * four floating-point units. + * @param pPosition The position to look for vertices. + * @param poResults The container to store the indices of the found positions. + * Will be emptied by the call so it may contain anything.*/ + void FindIdenticalPositions( const aiVector3D& pPosition, + std::vector& poResults) const; + + // ------------------------------------------------------------------------------------ + /** Compute a table that maps each vertex ID referring to a spatially close + * enough position to the same output ID. Output IDs are assigned in ascending order + * from 0...n. + * @param fill Will be filled with numPositions entries. + * @param pRadius Maximal distance from the position a vertex may have to + * be counted in. + * @return Number of unique vertices (n). */ + unsigned int GenerateMappingTable(std::vector& fill, + ai_real pRadius) const; + +protected: + /** Normal of the sorting plane, normalized. The center is always at (0, 0, 0) */ + aiVector3D mPlaneNormal; + + /** An entry in a spatially sorted position array. Consists of a vertex index, + * its position and its pre-calculated distance from the reference plane */ + struct Entry { + unsigned int mIndex; ///< The vertex referred by this entry + aiVector3D mPosition; ///< Position + ai_real mDistance; ///< Distance of this vertex to the sorting plane + + Entry() AI_NO_EXCEPT + : mIndex( 999999999 ), mPosition(), mDistance( 99999. ) { + // empty + } + Entry( unsigned int pIndex, const aiVector3D& pPosition, ai_real pDistance) + : mIndex( pIndex), mPosition( pPosition), mDistance( pDistance) { + // empty + } + + bool operator < (const Entry& e) const { return mDistance < e.mDistance; } + }; + + // all positions, sorted by distance to the sorting plane + std::vector mPositions; +}; + +} // end of namespace Assimp + +#endif // AI_SPATIALSORT_H_INC diff --git a/tools/ZAPD/ZAPD/assimp/StandardShapes.h b/tools/ZAPD/ZAPD/assimp/StandardShapes.h new file mode 100644 index 0000000000..3791569b83 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/StandardShapes.h @@ -0,0 +1,200 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file Declares a helper class, "StandardShapes" which generates + * vertices for standard shapes, such as cylnders, cones, spheres .. + */ +#ifndef AI_STANDARD_SHAPES_H_INC +#define AI_STANDARD_SHAPES_H_INC + +#include +#include + +struct aiMesh; + +namespace Assimp { + +// --------------------------------------------------------------------------- +/** \brief Helper class to generate vertex buffers for standard geometric + * shapes, such as cylinders, cones, boxes, spheres, elipsoids ... . + */ +class ASSIMP_API StandardShapes +{ + // class cannot be instanced + StandardShapes() {} + +public: + + + // ---------------------------------------------------------------- + /** Generates a mesh from an array of vertex positions. + * + * @param positions List of vertex positions + * @param numIndices Number of indices per primitive + * @return Output mesh + */ + static aiMesh* MakeMesh(const std::vector& positions, + unsigned int numIndices); + + + static aiMesh* MakeMesh ( unsigned int (*GenerateFunc) + (std::vector&)); + + static aiMesh* MakeMesh ( unsigned int (*GenerateFunc) + (std::vector&, bool)); + + static aiMesh* MakeMesh ( unsigned int n, void (*GenerateFunc) + (unsigned int,std::vector&)); + + // ---------------------------------------------------------------- + /** @brief Generates a hexahedron (cube) + * + * Hexahedrons can be scaled on all axes. + * @param positions Receives output triangles. + * @param polygons If you pass true here quads will be returned + * @return Number of vertices per face + */ + static unsigned int MakeHexahedron( + std::vector& positions, + bool polygons = false); + + // ---------------------------------------------------------------- + /** @brief Generates an icosahedron + * + * @param positions Receives output triangles. + * @return Number of vertices per face + */ + static unsigned int MakeIcosahedron( + std::vector& positions); + + + // ---------------------------------------------------------------- + /** @brief Generates a dodecahedron + * + * @param positions Receives output triangles + * @param polygons If you pass true here pentagons will be returned + * @return Number of vertices per face + */ + static unsigned int MakeDodecahedron( + std::vector& positions, + bool polygons = false); + + + // ---------------------------------------------------------------- + /** @brief Generates an octahedron + * + * @param positions Receives output triangles. + * @return Number of vertices per face + */ + static unsigned int MakeOctahedron( + std::vector& positions); + + + // ---------------------------------------------------------------- + /** @brief Generates a tetrahedron + * + * @param positions Receives output triangles. + * @return Number of vertices per face + */ + static unsigned int MakeTetrahedron( + std::vector& positions); + + + + // ---------------------------------------------------------------- + /** @brief Generates a sphere + * + * @param tess Number of subdivions - 0 generates a octahedron + * @param positions Receives output triangles. + */ + static void MakeSphere(unsigned int tess, + std::vector& positions); + + + // ---------------------------------------------------------------- + /** @brief Generates a cone or a cylinder, either open or closed. + * + * @code + * + * |-----| <- radius 1 + * + * __x__ <- ] ^ + * / \ | height | + * / \ | Y + * / \ | + * / \ | + * /______x______\ <- ] <- end cap + * + * |-------------| <- radius 2 + * + * @endcode + * + * @param height Height of the cone + * @param radius1 First radius + * @param radius2 Second radius + * @param tess Number of triangles. + * @param bOpened true for an open cone/cylinder. An open shape has + * no 'end caps' + * @param positions Receives output triangles + */ + static void MakeCone(ai_real height,ai_real radius1, + ai_real radius2,unsigned int tess, + std::vector& positions,bool bOpen= false); + + + // ---------------------------------------------------------------- + /** @brief Generates a flat circle + * + * The circle is constructed in the planned formed by the x,z + * axes of the cartesian coordinate system. + * + * @param radius Radius of the circle + * @param tess Number of segments. + * @param positions Receives output triangles. + */ + static void MakeCircle(ai_real radius, unsigned int tess, + std::vector& positions); + +}; +} // ! Assimp + +#endif // !! AI_STANDARD_SHAPES_H_INC diff --git a/tools/ZAPD/ZAPD/assimp/StreamReader.h b/tools/ZAPD/ZAPD/assimp/StreamReader.h new file mode 100644 index 0000000000..9116c14261 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/StreamReader.h @@ -0,0 +1,343 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file Defines the StreamReader class which reads data from + * a binary stream with a well-defined endianness. + */ + +#ifndef AI_STREAMREADER_H_INCLUDED +#define AI_STREAMREADER_H_INCLUDED + +#include +#include + +#include "ByteSwapper.h" +#include "Exceptional.h" +#include + +namespace Assimp { + +// -------------------------------------------------------------------------------------------- +/** Wrapper class around IOStream to allow for consistent reading of binary data in both + * little and big endian format. Don't attempt to instance the template directly. Use + * StreamReaderLE to read from a little-endian stream and StreamReaderBE to read from a + * BE stream. The class expects that the endianness of any input data is known at + * compile-time, which should usually be true (#BaseImporter::ConvertToUTF8 implements + * runtime endianness conversions for text files). + * + * XXX switch from unsigned int for size types to size_t? or ptrdiff_t?*/ +// -------------------------------------------------------------------------------------------- +template +class StreamReader { +public: + // FIXME: use these data types throughout the whole library, + // then change them to 64 bit values :-) + using diff = int; + using pos = unsigned int; + + // --------------------------------------------------------------------- + /** Construction from a given stream with a well-defined endianness. + * + * The StreamReader holds a permanent strong reference to the + * stream, which is released upon destruction. + * @param stream Input stream. The stream is not restarted if + * its file pointer is not at 0. Instead, the stream reader + * reads from the current position to the end of the stream. + * @param le If @c RuntimeSwitch is true: specifies whether the + * stream is in little endian byte order. Otherwise the + * endianness information is contained in the @c SwapEndianess + * template parameter and this parameter is meaningless. */ + StreamReader(std::shared_ptr stream, bool le = false) + : stream(stream) + , le(le) + { + ai_assert(stream); + InternBegin(); + } + + // --------------------------------------------------------------------- + StreamReader(IOStream* stream, bool le = false) + : stream(std::shared_ptr(stream)) + , le(le) + { + ai_assert(stream); + InternBegin(); + } + + // --------------------------------------------------------------------- + ~StreamReader() { + delete[] buffer; + } + + // deprecated, use overloaded operator>> instead + + // --------------------------------------------------------------------- + /** Read a float from the stream */ + float GetF4() + { + return Get(); + } + + // --------------------------------------------------------------------- + /** Read a double from the stream */ + double GetF8() { + return Get(); + } + + // --------------------------------------------------------------------- + /** Read a signed 16 bit integer from the stream */ + int16_t GetI2() { + return Get(); + } + + // --------------------------------------------------------------------- + /** Read a signed 8 bit integer from the stream */ + int8_t GetI1() { + return Get(); + } + + // --------------------------------------------------------------------- + /** Read an signed 32 bit integer from the stream */ + int32_t GetI4() { + return Get(); + } + + // --------------------------------------------------------------------- + /** Read a signed 64 bit integer from the stream */ + int64_t GetI8() { + return Get(); + } + + // --------------------------------------------------------------------- + /** Read a unsigned 16 bit integer from the stream */ + uint16_t GetU2() { + return Get(); + } + + // --------------------------------------------------------------------- + /** Read a unsigned 8 bit integer from the stream */ + uint8_t GetU1() { + return Get(); + } + + // --------------------------------------------------------------------- + /** Read an unsigned 32 bit integer from the stream */ + uint32_t GetU4() { + return Get(); + } + + // --------------------------------------------------------------------- + /** Read a unsigned 64 bit integer from the stream */ + uint64_t GetU8() { + return Get(); + } + + // --------------------------------------------------------------------- + /** Get the remaining stream size (to the end of the stream) */ + unsigned int GetRemainingSize() const { + return (unsigned int)(end - current); + } + + // --------------------------------------------------------------------- + /** Get the remaining stream size (to the current read limit). The + * return value is the remaining size of the stream if no custom + * read limit has been set. */ + unsigned int GetRemainingSizeToLimit() const { + return (unsigned int)(limit - current); + } + + // --------------------------------------------------------------------- + /** Increase the file pointer (relative seeking) */ + void IncPtr(intptr_t plus) { + current += plus; + if (current > limit) { + throw DeadlyImportError("End of file or read limit was reached"); + } + } + + // --------------------------------------------------------------------- + /** Get the current file pointer */ + int8_t* GetPtr() const { + return current; + } + + // --------------------------------------------------------------------- + /** Set current file pointer (Get it from #GetPtr). This is if you + * prefer to do pointer arithmetics on your own or want to copy + * large chunks of data at once. + * @param p The new pointer, which is validated against the size + * limit and buffer boundaries. */ + void SetPtr(int8_t* p) { + current = p; + if (current > limit || current < buffer) { + throw DeadlyImportError("End of file or read limit was reached"); + } + } + + // --------------------------------------------------------------------- + /** Copy n bytes to an external buffer + * @param out Destination for copying + * @param bytes Number of bytes to copy */ + void CopyAndAdvance(void* out, size_t bytes) { + int8_t* ur = GetPtr(); + SetPtr(ur+bytes); // fire exception if eof + + ::memcpy(out,ur,bytes); + } + + // --------------------------------------------------------------------- + /** Get the current offset from the beginning of the file */ + int GetCurrentPos() const { + return (unsigned int)(current - buffer); + } + + void SetCurrentPos(size_t pos) { + SetPtr(buffer + pos); + } + + // --------------------------------------------------------------------- + /** Setup a temporary read limit + * + * @param limit Maximum number of bytes to be read from + * the beginning of the file. Specifying UINT_MAX + * resets the limit to the original end of the stream. + * Returns the previously set limit. */ + unsigned int SetReadLimit(unsigned int _limit) { + unsigned int prev = GetReadLimit(); + if (UINT_MAX == _limit) { + limit = end; + return prev; + } + + limit = buffer + _limit; + if (limit > end) { + throw DeadlyImportError("StreamReader: Invalid read limit"); + } + return prev; + } + + // --------------------------------------------------------------------- + /** Get the current read limit in bytes. Reading over this limit + * accidentally raises an exception. */ + unsigned int GetReadLimit() const { + return (unsigned int)(limit - buffer); + } + + // --------------------------------------------------------------------- + /** Skip to the read limit in bytes. Reading over this limit + * accidentally raises an exception. */ + void SkipToReadLimit() { + current = limit; + } + + // --------------------------------------------------------------------- + /** overload operator>> and allow chaining of >> ops. */ + template + StreamReader& operator >> (T& f) { + f = Get(); + return *this; + } + + // --------------------------------------------------------------------- + /** Generic read method. ByteSwap::Swap(T*) *must* be defined */ + template + T Get() { + if ( current + sizeof(T) > limit) { + throw DeadlyImportError("End of file or stream limit was reached"); + } + + T f; + ::memcpy (&f, current, sizeof(T)); + Intern::Getter() (&f,le); + current += sizeof(T); + + return f; + } + +private: + // --------------------------------------------------------------------- + void InternBegin() { + if (!stream) { + // in case someone wonders: StreamReader is frequently invoked with + // no prior validation whether the input stream is valid. Since + // no one bothers changing the error message, this message here + // is passed down to the caller and 'unable to open file' + // simply describes best what happened. + throw DeadlyImportError("StreamReader: Unable to open file"); + } + + const size_t s = stream->FileSize() - stream->Tell(); + if (!s) { + throw DeadlyImportError("StreamReader: File is empty or EOF is already reached"); + } + + current = buffer = new int8_t[s]; + const size_t read = stream->Read(current,1,s); + // (read < s) can only happen if the stream was opened in text mode, in which case FileSize() is not reliable + ai_assert(read <= s); + end = limit = &buffer[read-1] + 1; + } + +private: + std::shared_ptr stream; + int8_t *buffer, *current, *end, *limit; + bool le; +}; + +// -------------------------------------------------------------------------------------------- +// `static` StreamReaders. Their byte order is fixed and they might be a little bit faster. +#ifdef AI_BUILD_BIG_ENDIAN + typedef StreamReader StreamReaderLE; + typedef StreamReader StreamReaderBE; +#else + typedef StreamReader StreamReaderBE; + typedef StreamReader StreamReaderLE; +#endif + +// `dynamic` StreamReader. The byte order of the input data is specified in the +// c'tor. This involves runtime branching and might be a little bit slower. +typedef StreamReader StreamReaderAny; + +} // end namespace Assimp + +#endif // !! AI_STREAMREADER_H_INCLUDED diff --git a/tools/ZAPD/ZAPD/assimp/StreamWriter.h b/tools/ZAPD/ZAPD/assimp/StreamWriter.h new file mode 100644 index 0000000000..c7cf6c0d74 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/StreamWriter.h @@ -0,0 +1,303 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file Defines the StreamWriter class which writes data to + * a binary stream with a well-defined endianness. */ + +#ifndef AI_STREAMWRITER_H_INCLUDED +#define AI_STREAMWRITER_H_INCLUDED + +#include "ByteSwapper.h" +#include + +#include +#include + +namespace Assimp { + +// -------------------------------------------------------------------------------------------- +/** Wrapper class around IOStream to allow for consistent writing of binary data in both + * little and big endian format. Don't attempt to instance the template directly. Use + * StreamWriterLE to write to a little-endian stream and StreamWriterBE to write to a + * BE stream. Alternatively, there is StreamWriterAny if the endianness of the output + * stream is to be determined at runtime. + */ +// -------------------------------------------------------------------------------------------- +template +class StreamWriter +{ + enum { + INITIAL_CAPACITY = 1024 + }; + +public: + + // --------------------------------------------------------------------- + /** Construction from a given stream with a well-defined endianness. + * + * The StreamReader holds a permanent strong reference to the + * stream, which is released upon destruction. + * @param stream Input stream. The stream is not re-seeked and writing + continues at the current position of the stream cursor. + * @param le If @c RuntimeSwitch is true: specifies whether the + * stream is in little endian byte order. Otherwise the + * endianness information is defined by the @c SwapEndianess + * template parameter and this parameter is meaningless. */ + StreamWriter(std::shared_ptr stream, bool le = false) + : stream(stream) + , le(le) + , cursor() + { + ai_assert(stream); + buffer.reserve(INITIAL_CAPACITY); + } + + // --------------------------------------------------------------------- + StreamWriter(IOStream* stream, bool le = false) + : stream(std::shared_ptr(stream)) + , le(le) + , cursor() + { + ai_assert(stream); + buffer.reserve(INITIAL_CAPACITY); + } + + // --------------------------------------------------------------------- + ~StreamWriter() { + stream->Write(buffer.data(), 1, buffer.size()); + stream->Flush(); + } + +public: + + // --------------------------------------------------------------------- + /** Flush the contents of the internal buffer, and the output IOStream */ + void Flush() + { + stream->Write(buffer.data(), 1, buffer.size()); + stream->Flush(); + buffer.clear(); + cursor = 0; + } + + // --------------------------------------------------------------------- + /** Seek to the given offset / origin in the output IOStream. + * + * Flushes the internal buffer and the output IOStream prior to seeking. */ + aiReturn Seek(size_t pOffset, aiOrigin pOrigin=aiOrigin_SET) + { + Flush(); + return stream->Seek(pOffset, pOrigin); + } + + // --------------------------------------------------------------------- + /** Tell the current position in the output IOStream. + * + * First flushes the internal buffer and the output IOStream. */ + size_t Tell() + { + Flush(); + return stream->Tell(); + } + +public: + + // --------------------------------------------------------------------- + /** Write a float to the stream */ + void PutF4(float f) + { + Put(f); + } + + // --------------------------------------------------------------------- + /** Write a double to the stream */ + void PutF8(double d) { + Put(d); + } + + // --------------------------------------------------------------------- + /** Write a signed 16 bit integer to the stream */ + void PutI2(int16_t n) { + Put(n); + } + + // --------------------------------------------------------------------- + /** Write a signed 8 bit integer to the stream */ + void PutI1(int8_t n) { + Put(n); + } + + // --------------------------------------------------------------------- + /** Write an signed 32 bit integer to the stream */ + void PutI4(int32_t n) { + Put(n); + } + + // --------------------------------------------------------------------- + /** Write a signed 64 bit integer to the stream */ + void PutI8(int64_t n) { + Put(n); + } + + // --------------------------------------------------------------------- + /** Write a unsigned 16 bit integer to the stream */ + void PutU2(uint16_t n) { + Put(n); + } + + // --------------------------------------------------------------------- + /** Write a unsigned 8 bit integer to the stream */ + void PutU1(uint8_t n) { + Put(n); + } + + // --------------------------------------------------------------------- + /** Write an unsigned 32 bit integer to the stream */ + void PutU4(uint32_t n) { + Put(n); + } + + // --------------------------------------------------------------------- + /** Write a unsigned 64 bit integer to the stream */ + void PutU8(uint64_t n) { + Put(n); + } + + // --------------------------------------------------------------------- + /** Write a single character to the stream */ + void PutChar(char c) { + Put(c); + } + + // --------------------------------------------------------------------- + /** Write an aiString to the stream */ + void PutString(const aiString& s) + { + // as Put(T f) below + if (cursor + s.length >= buffer.size()) { + buffer.resize(cursor + s.length); + } + void* dest = &buffer[cursor]; + ::memcpy(dest, s.C_Str(), s.length); + cursor += s.length; + } + + // --------------------------------------------------------------------- + /** Write a std::string to the stream */ + void PutString(const std::string& s) + { + // as Put(T f) below + if (cursor + s.size() >= buffer.size()) { + buffer.resize(cursor + s.size()); + } + void* dest = &buffer[cursor]; + ::memcpy(dest, s.c_str(), s.size()); + cursor += s.size(); + } + +public: + + // --------------------------------------------------------------------- + /** overload operator<< and allow chaining of MM ops. */ + template + StreamWriter& operator << (T f) { + Put(f); + return *this; + } + + // --------------------------------------------------------------------- + std::size_t GetCurrentPos() const { + return cursor; + } + + // --------------------------------------------------------------------- + void SetCurrentPos(std::size_t new_cursor) { + cursor = new_cursor; + } + + // --------------------------------------------------------------------- + /** Generic write method. ByteSwap::Swap(T*) *must* be defined */ + template + void Put(T f) { + Intern :: Getter() (&f, le); + + if (cursor + sizeof(T) >= buffer.size()) { + buffer.resize(cursor + sizeof(T)); + } + + void* dest = &buffer[cursor]; + + // reinterpret_cast + assignment breaks strict aliasing rules + // and generally causes trouble on platforms such as ARM that + // do not silently ignore alignment faults. + ::memcpy(dest, &f, sizeof(T)); + cursor += sizeof(T); + } + +private: + + std::shared_ptr stream; + bool le; + + std::vector buffer; + std::size_t cursor; +}; + + +// -------------------------------------------------------------------------------------------- +// `static` StreamWriter. Their byte order is fixed and they might be a little bit faster. +#ifdef AI_BUILD_BIG_ENDIAN + typedef StreamWriter StreamWriterLE; + typedef StreamWriter StreamWriterBE; +#else + typedef StreamWriter StreamWriterBE; + typedef StreamWriter StreamWriterLE; +#endif + +// `dynamic` StreamWriter. The byte order of the input data is specified in the +// c'tor. This involves runtime branching and might be a little bit slower. +typedef StreamWriter StreamWriterAny; + +} // end namespace Assimp + +#endif // !! AI_STREAMWriter_H_INCLUDED diff --git a/tools/ZAPD/ZAPD/assimp/StringComparison.h b/tools/ZAPD/ZAPD/assimp/StringComparison.h new file mode 100644 index 0000000000..8acef277b9 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/StringComparison.h @@ -0,0 +1,233 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file Definition of platform independent string workers: + + ASSIMP_itoa10 + ASSIMP_stricmp + ASSIMP_strincmp + + These functions are not consistently available on all platforms, + or the provided implementations behave too differently. +*/ +#ifndef INCLUDED_AI_STRING_WORKERS_H +#define INCLUDED_AI_STRING_WORKERS_H + +#include +#include +#include "StringComparison.h" + +#include +#include +#include + +namespace Assimp { + +// ------------------------------------------------------------------------------- +/** @brief itoa with a fixed base 10 + * 'itoa' is not consistently available on all platforms so it is quite useful + * to have a small replacement function here. No need to use a full sprintf() + * if we just want to print a number ... + * @param out Output buffer + * @param max Maximum number of characters to be written, including '\0'. + * This parameter may not be 0. + * @param number Number to be written + * @return Length of the output string, excluding the '\0' + */ +AI_FORCE_INLINE +unsigned int ASSIMP_itoa10( char* out, unsigned int max, int32_t number) { + ai_assert(NULL != out); + + // write the unary minus to indicate we have a negative number + unsigned int written = 1u; + if (number < 0 && written < max) { + *out++ = '-'; + ++written; + number = -number; + } + + // We begin with the largest number that is not zero. + int32_t cur = 1000000000; // 2147483648 + bool mustPrint = false; + while (written < max) { + + const unsigned int digit = number / cur; + if (mustPrint || digit > 0 || 1 == cur) { + // print all future zeroe's from now + mustPrint = true; + + *out++ = '0'+static_cast(digit); + + ++written; + number -= digit*cur; + if (1 == cur) { + break; + } + } + cur /= 10; + } + + // append a terminal zero + *out++ = '\0'; + return written-1; +} + +// ------------------------------------------------------------------------------- +/** @brief itoa with a fixed base 10 (Secure template overload) + * The compiler should choose this function if he or she is able to determine the + * size of the array automatically. + */ +template +AI_FORCE_INLINE +unsigned int ASSIMP_itoa10( char(& out)[length], int32_t number) { + return ASSIMP_itoa10(out,length,number); +} + +// ------------------------------------------------------------------------------- +/** @brief Helper function to do platform independent string comparison. + * + * This is required since stricmp() is not consistently available on + * all platforms. Some platforms use the '_' prefix, others don't even + * have such a function. + * + * @param s1 First input string + * @param s2 Second input string + * @return 0 if the given strings are identical + */ +AI_FORCE_INLINE +int ASSIMP_stricmp(const char *s1, const char *s2) { + ai_assert( NULL != s1 ); + ai_assert( NULL != s2 ); + +#if (defined _MSC_VER) + + return ::_stricmp(s1,s2); +#elif defined( __GNUC__ ) + + return ::strcasecmp(s1,s2); +#else + + char c1, c2; + do { + c1 = tolower(*s1++); + c2 = tolower(*s2++); + } + while ( c1 && (c1 == c2) ); + return c1 - c2; +#endif +} + +// ------------------------------------------------------------------------------- +/** @brief Case independent comparison of two std::strings + * + * @param a First string + * @param b Second string + * @return 0 if a == b + */ +AI_FORCE_INLINE +int ASSIMP_stricmp(const std::string& a, const std::string& b) { + int i = (int)b.length()-(int)a.length(); + return (i ? i : ASSIMP_stricmp(a.c_str(),b.c_str())); +} + +// ------------------------------------------------------------------------------- +/** @brief Helper function to do platform independent string comparison. + * + * This is required since strincmp() is not consistently available on + * all platforms. Some platforms use the '_' prefix, others don't even + * have such a function. + * + * @param s1 First input string + * @param s2 Second input string + * @param n Macimum number of characters to compare + * @return 0 if the given strings are identical + */ +AI_FORCE_INLINE +int ASSIMP_strincmp(const char *s1, const char *s2, unsigned int n) { + ai_assert( NULL != s1 ); + ai_assert( NULL != s2 ); + if ( !n ) { + return 0; + } + +#if (defined _MSC_VER) + + return ::_strnicmp(s1,s2,n); + +#elif defined( __GNUC__ ) + + return ::strncasecmp(s1,s2, n); + +#else + char c1, c2; + unsigned int p = 0; + do + { + if (p++ >= n)return 0; + c1 = tolower(*s1++); + c2 = tolower(*s2++); + } + while ( c1 && (c1 == c2) ); + + return c1 - c2; +#endif +} + + +// ------------------------------------------------------------------------------- +/** @brief Evaluates an integer power + * + * todo: move somewhere where it fits better in than here + */ +AI_FORCE_INLINE +unsigned int integer_pow( unsigned int base, unsigned int power ) { + unsigned int res = 1; + for ( unsigned int i = 0; i < power; ++i ) { + res *= base; + } + + return res; +} + +} // end of namespace + +#endif // ! AI_STRINGCOMPARISON_H_INC diff --git a/tools/ZAPD/ZAPD/assimp/StringUtils.h b/tools/ZAPD/ZAPD/assimp/StringUtils.h new file mode 100644 index 0000000000..d68b7fa479 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/StringUtils.h @@ -0,0 +1,143 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above +copyright notice, this list of conditions and the +following disclaimer. + +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other +materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its +contributors may be used to endorse or promote products +derived from this software without specific prior +written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ +#ifndef INCLUDED_AI_STRINGUTILS_H +#define INCLUDED_AI_STRINGUTILS_H + +#include + +#include +#include +#include + +/// @fn ai_snprintf +/// @brief The portable version of the function snprintf ( C99 standard ), which works on visual studio compilers 2013 and earlier. +/// @param outBuf The buffer to write in +/// @param size The buffer size +/// @param format The format string +/// @param ap The additional arguments. +/// @return The number of written characters if the buffer size was big enough. If an encoding error occurs, a negative number is returned. +#if defined(_MSC_VER) && _MSC_VER < 1900 + + AI_FORCE_INLINE + int c99_ai_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) { + int count(-1); + if (0 != size) { + count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap); + } + if (count == -1) { + count = _vscprintf(format, ap); + } + + return count; + } + + AI_FORCE_INLINE + int ai_snprintf(char *outBuf, size_t size, const char *format, ...) { + int count; + va_list ap; + + va_start(ap, format); + count = c99_ai_vsnprintf(outBuf, size, format, ap); + va_end(ap); + + return count; + } + +#else +# define ai_snprintf snprintf +#endif + +/// @fn to_string +/// @brief The portable version of to_string ( some gcc-versions on embedded devices are not supporting this). +/// @param value The value to write into the std::string. +/// @return The value as a std::string +template +AI_FORCE_INLINE +std::string to_string( T value ) { + std::ostringstream os; + os << value; + + return os.str(); +} + +/// @fn ai_strtof +/// @brief The portable version of strtof. +/// @param begin The first character of the string. +/// @param end The last character +/// @return The float value, 0.0f in cas of an error. +AI_FORCE_INLINE +float ai_strtof( const char *begin, const char *end ) { + if ( nullptr == begin ) { + return 0.0f; + } + float val( 0.0f ); + if ( nullptr == end ) { + val = static_cast< float >( ::atof( begin ) ); + } else { + std::string::size_type len( end - begin ); + std::string token( begin, len ); + val = static_cast< float >( ::atof( token.c_str() ) ); + } + + return val; +} + +/// @fn DecimalToHexa +/// @brief The portable to convert a decimal value into a hexadecimal string. +/// @param toConvert Value to convert +/// @return The hexadecimal string, is empty in case of an error. +template +AI_FORCE_INLINE +std::string DecimalToHexa( T toConvert ) { + std::string result; + std::stringstream ss; + ss << std::hex << toConvert; + ss >> result; + + for ( size_t i = 0; i < result.size(); ++i ) { + result[ i ] = toupper( result[ i ] ); + } + + return result; +} + +#endif // INCLUDED_AI_STRINGUTILS_H diff --git a/tools/ZAPD/ZAPD/assimp/Subdivision.h b/tools/ZAPD/ZAPD/assimp/Subdivision.h new file mode 100644 index 0000000000..43feb73b30 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/Subdivision.h @@ -0,0 +1,131 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file Defines a helper class to evaluate subdivision surfaces.*/ +#pragma once +#ifndef AI_SUBDISIVION_H_INC +#define AI_SUBDISIVION_H_INC + +#include +#include + +struct aiMesh; + +namespace Assimp { + +// ------------------------------------------------------------------------------ +/** Helper class to evaluate subdivision surfaces. Different algorithms + * are provided for choice. */ +// ------------------------------------------------------------------------------ +class ASSIMP_API Subdivider { +public: + + /** Enumerates all supported subvidision algorithms */ + enum Algorithm { + CATMULL_CLARKE = 0x1 + }; + + virtual ~Subdivider(); + + // --------------------------------------------------------------- + /** Create a subdivider of a specific type + * + * @param algo Algorithm to be used for subdivision + * @return Subdivider instance. */ + static Subdivider* Create (Algorithm algo); + + // --------------------------------------------------------------- + /** Subdivide a mesh using the selected algorithm + * + * @param mesh First mesh to be subdivided. Must be in verbose + * format. + * @param out Receives the output mesh, allocated by me. + * @param num Number of subdivisions to perform. + * @param discard_input If true is passed, the input mesh is + * deleted after the subdivision is complete. This can + * improve performance because it allows the optimization + * to reuse the existing mesh for intermediate results. + * @pre out!=mesh*/ + virtual void Subdivide ( aiMesh* mesh, + aiMesh*& out, unsigned int num, + bool discard_input = false) = 0; + + // --------------------------------------------------------------- + /** Subdivide multiple meshes using the selected algorithm. This + * avoids erroneous smoothing on objects consisting of multiple + * per-material meshes. Usually, most 3d modellers smooth on a + * per-object base, regardless the materials assigned to the + * meshes. + * + * @param smesh Array of meshes to be subdivided. Must be in + * verbose format. + * @param nmesh Number of meshes in smesh. + * @param out Receives the output meshes. The array must be + * sufficiently large (at least @c nmesh elements) and may not + * overlap the input array. Output meshes map one-to-one to + * their corresponding input meshes. The meshes are allocated + * by the function. + * @param discard_input If true is passed, input meshes are + * deleted after the subdivision is complete. This can + * improve performance because it allows the optimization + * of reusing existing meshes for intermediate results. + * @param num Number of subdivisions to perform. + * @pre nmesh != 0, smesh and out may not overlap*/ + virtual void Subdivide ( + aiMesh** smesh, + size_t nmesh, + aiMesh** out, + unsigned int num, + bool discard_input = false) = 0; + +}; + +inline +Subdivider::~Subdivider() { + // empty +} + +} // end namespace Assimp + + +#endif // !! AI_SUBDISIVION_H_INC + diff --git a/tools/ZAPD/ZAPD/assimp/TinyFormatter.h b/tools/ZAPD/ZAPD/assimp/TinyFormatter.h new file mode 100644 index 0000000000..1226b482e6 --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/TinyFormatter.h @@ -0,0 +1,166 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file TinyFormatter.h + * @brief Utility to format log messages more easily. Introduced + * to get rid of the boost::format dependency. Much slinker, + * basically just extends stringstream. + */ +#ifndef INCLUDED_TINY_FORMATTER_H +#define INCLUDED_TINY_FORMATTER_H + +#include + +namespace Assimp { +namespace Formatter { + +// ------------------------------------------------------------------------------------------------ +/** stringstream utility. Usage: + * @code + * void writelog(const std::string&s); + * void writelog(const std::wstring&s); + * ... + * writelog(format()<< "hi! this is a number: " << 4); + * writelog(wformat()<< L"hi! this is a number: " << 4); + * + * @endcode */ +template < typename T, + typename CharTraits = std::char_traits, + typename Allocator = std::allocator +> +class basic_formatter +{ + +public: + + typedef class std::basic_string< + T,CharTraits,Allocator + > string; + + typedef class std::basic_ostringstream< + T,CharTraits,Allocator + > stringstream; + +public: + + basic_formatter() {} + + /* Allow basic_formatter's to be used almost interchangeably + * with std::(w)string or const (w)char* arguments because the + * conversion c'tor is called implicitly. */ + template + basic_formatter(const TT& sin) { + underlying << sin; + } + + + // The problem described here: + // https://sourceforge.net/tracker/?func=detail&atid=1067632&aid=3358562&group_id=226462 + // can also cause trouble here. Apparently, older gcc versions sometimes copy temporaries + // being bound to const ref& function parameters. Copying streams is not permitted, though. + // This workaround avoids this by manually specifying a copy ctor. +#if !defined(__GNUC__) || !defined(__APPLE__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) + explicit basic_formatter(const basic_formatter& other) { + underlying << (string)other; + } +#endif + + +public: + + operator string () const { + return underlying.str(); + } + + + /* note - this is declared const because binding temporaries does only + * work for const references, so many function prototypes will + * include const basic_formatter& s but might still want to + * modify the formatted string without the need for a full copy.*/ + template + const basic_formatter& operator << (const TToken& s) const { + underlying << s; + return *this; + } + + template + basic_formatter& operator << (const TToken& s) { + underlying << s; + return *this; + } + + + // comma operator overloaded as well, choose your preferred way. + template + const basic_formatter& operator, (const TToken& s) const { + underlying << s; + return *this; + } + + template + basic_formatter& operator, (const TToken& s) { + underlying << s; + return *this; + } + + // Fix for MSVC8 + // See https://sourceforge.net/projects/assimp/forums/forum/817654/topic/4372824 + template + basic_formatter& operator, (TToken& s) { + underlying << s; + return *this; + } + + +private: + mutable stringstream underlying; +}; + + +typedef basic_formatter< char > format; +typedef basic_formatter< wchar_t > wformat; + +} // ! namespace Formatter + +} // ! namespace Assimp + +#endif diff --git a/tools/ZAPD/ZAPD/assimp/Vertex.h b/tools/ZAPD/ZAPD/assimp/Vertex.h new file mode 100644 index 0000000000..2a7f0256ad --- /dev/null +++ b/tools/ZAPD/ZAPD/assimp/Vertex.h @@ -0,0 +1,348 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ +/** @file Defines a helper class to represent an interleaved vertex + along with arithmetic operations to support vertex operations + such as subdivision, smoothing etc. + + While the code is kept as general as possible, arithmetic operations + that are not currently well-defined (and would cause compile errors + due to missing operators in the math library), are commented. + */ +#ifndef AI_VERTEX_H_INC +#define AI_VERTEX_H_INC + +#include +#include +#include +#include + +namespace Assimp { + + /////////////////////////////////////////////////////////////////////////// + // std::plus-family operates on operands with identical types - we need to + // support all the (vectype op float) combinations in vector maths. + // Providing T(float) would open the way to endless implicit conversions. + /////////////////////////////////////////////////////////////////////////// + namespace Intern { + template struct plus { + TRES operator() (const T0& t0, const T1& t1) const { + return t0+t1; + } + }; + template struct minus { + TRES operator() (const T0& t0, const T1& t1) const { + return t0-t1; + } + }; + template struct multiplies { + TRES operator() (const T0& t0, const T1& t1) const { + return t0*t1; + } + }; + template struct divides { + TRES operator() (const T0& t0, const T1& t1) const { + return t0/t1; + } + }; + } + +// ------------------------------------------------------------------------------------------------ +/** Intermediate description a vertex with all possible components. Defines a full set of + * operators, so you may use such a 'Vertex' in basic arithmetics. All operators are applied + * to *all* vertex components equally. This is useful for stuff like interpolation + * or subdivision, but won't work if special handling is required for some vertex components. */ +// ------------------------------------------------------------------------------------------------ +class Vertex +{ + friend Vertex operator + (const Vertex&,const Vertex&); + friend Vertex operator - (const Vertex&,const Vertex&); + +// friend Vertex operator + (const Vertex&,ai_real); +// friend Vertex operator - (const Vertex&,ai_real); + friend Vertex operator * (const Vertex&,ai_real); + friend Vertex operator / (const Vertex&,ai_real); + +// friend Vertex operator + (ai_real, const Vertex&); +// friend Vertex operator - (ai_real, const Vertex&); + friend Vertex operator * (ai_real, const Vertex&); +// friend Vertex operator / (ai_real, const Vertex&); + +public: + + Vertex() {} + + // ---------------------------------------------------------------------------- + /** Extract a particular vertex from a mesh and interleave all components */ + explicit Vertex(const aiMesh* msh, unsigned int idx) { + ai_assert(idx < msh->mNumVertices); + position = msh->mVertices[idx]; + + if (msh->HasNormals()) { + normal = msh->mNormals[idx]; + } + + if (msh->HasTangentsAndBitangents()) { + tangent = msh->mTangents[idx]; + bitangent = msh->mBitangents[idx]; + } + + for (unsigned int i = 0; msh->HasTextureCoords(i); ++i) { + texcoords[i] = msh->mTextureCoords[i][idx]; + } + + for (unsigned int i = 0; msh->HasVertexColors(i); ++i) { + colors[i] = msh->mColors[i][idx]; + } + } + + // ---------------------------------------------------------------------------- + /** Extract a particular vertex from a anim mesh and interleave all components */ + explicit Vertex(const aiAnimMesh* msh, unsigned int idx) { + ai_assert(idx < msh->mNumVertices); + position = msh->mVertices[idx]; + + if (msh->HasNormals()) { + normal = msh->mNormals[idx]; + } + + if (msh->HasTangentsAndBitangents()) { + tangent = msh->mTangents[idx]; + bitangent = msh->mBitangents[idx]; + } + + for (unsigned int i = 0; msh->HasTextureCoords(i); ++i) { + texcoords[i] = msh->mTextureCoords[i][idx]; + } + + for (unsigned int i = 0; msh->HasVertexColors(i); ++i) { + colors[i] = msh->mColors[i][idx]; + } + } + +public: + + Vertex& operator += (const Vertex& v) { + *this = *this+v; + return *this; + } + + Vertex& operator -= (const Vertex& v) { + *this = *this-v; + return *this; + } + + +/* + Vertex& operator += (ai_real v) { + *this = *this+v; + return *this; + } + + Vertex& operator -= (ai_real v) { + *this = *this-v; + return *this; + } +*/ + Vertex& operator *= (ai_real v) { + *this = *this*v; + return *this; + } + + Vertex& operator /= (ai_real v) { + *this = *this/v; + return *this; + } + +public: + + // ---------------------------------------------------------------------------- + /** Convert back to non-interleaved storage */ + void SortBack(aiMesh* out, unsigned int idx) const { + + ai_assert(idxmNumVertices); + out->mVertices[idx] = position; + + if (out->HasNormals()) { + out->mNormals[idx] = normal; + } + + if (out->HasTangentsAndBitangents()) { + out->mTangents[idx] = tangent; + out->mBitangents[idx] = bitangent; + } + + for(unsigned int i = 0; out->HasTextureCoords(i); ++i) { + out->mTextureCoords[i][idx] = texcoords[i]; + } + + for(unsigned int i = 0; out->HasVertexColors(i); ++i) { + out->mColors[i][idx] = colors[i]; + } + } + +private: + + // ---------------------------------------------------------------------------- + /** Construct from two operands and a binary operation to combine them */ + template