diff --git a/Makefile b/Makefile index 3d6283b5..f02873e0 100755 --- a/Makefile +++ b/Makefile @@ -144,15 +144,16 @@ GFX_PRECMP_DIR = 'precompressed/gfx_compressible' OBJS = $(BUILD_DIR)/$(GAME).o $(BUILD_DIR)/audio.o -# All .bin/.png gfx files and paths. Include _jp variants when building JP. +# All .bin/.png gfx files and paths. Include _ variants when building JP/EU. GFX_UNCMP_PATHS = $(GFX_UNCMP_DIR)/common $(GFX_UNCMP_DIR)/$(GAME) GFX_CMP_PATHS = $(GFX_CMP_DIR)/common $(GFX_CMP_DIR)/$(GAME) GFX_PRECMP_PATHS = $(GFX_PRECMP_DIR)/common $(GFX_PRECMP_DIR)/$(GAME) -ifeq ($(REGION), jp) -GFX_UNCMP_PATHS += $(GFX_UNCMP_DIR)/common_jp $(GFX_UNCMP_DIR)/$(GAME)_jp -GFX_CMP_PATHS += $(GFX_CMP_DIR)/common_jp $(GFX_CMP_DIR)/$(GAME)_jp -GFX_PRECMP_PATHS += $(GFX_PRECMP_DIR)/common_jp $(GFX_PRECMP_DIR)/$(GAME)_jp +ifneq ($(filter jp eu,$(REGION)),) +REGION_SUFFIX = _$(REGION) +GFX_UNCMP_PATHS += $(GFX_UNCMP_DIR)/common$(REGION_SUFFIX) $(GFX_UNCMP_DIR)/$(GAME)$(REGION_SUFFIX) +GFX_CMP_PATHS += $(GFX_CMP_DIR)/common$(REGION_SUFFIX) $(GFX_CMP_DIR)/$(GAME)$(REGION_SUFFIX) +GFX_PRECMP_PATHS += $(GFX_PRECMP_DIR)/common$(REGION_SUFFIX) $(GFX_PRECMP_DIR)/$(GAME)$(REGION_SUFFIX) endif # All .bin gfx files @@ -195,9 +196,9 @@ endif ROOMLAYOUTFILES = $(wildcard rooms/$(GAME)/small/*.bin) ROOMLAYOUTFILES += $(wildcard rooms/$(GAME)/large/*.bin) -ifeq ($(REGION), jp) -ROOMLAYOUTFILES += $(wildcard rooms/$(GAME)_jp/small/*.bin) -ROOMLAYOUTFILES += $(wildcard rooms/$(GAME)_jp/large/*.bin) +ifneq ($(filter jp eu,$(REGION)),) +ROOMLAYOUTFILES += $(wildcard rooms/$(GAME)$(REGION_SUFFIX)/small/*.bin) +ROOMLAYOUTFILES += $(wildcard rooms/$(GAME)$(REGION_SUFFIX)/large/*.bin) endif ROOMLAYOUTFILES := $(ROOMLAYOUTFILES:.bin=.cmp) @@ -206,8 +207,8 @@ ROOMLAYOUTFILES := $(foreach file, $(ROOMLAYOUTFILES), \ COLLISIONFILES = $(wildcard tileset_layouts/$(GAME)/tilesetCollisions*.bin) -ifeq ($(REGION), jp) -COLLISIONFILES += $(wildcard tileset_layouts/$(GAME)_jp/tilesetCollisions*.bin) +ifneq ($(filter jp eu,$(REGION)),) +COLLISIONFILES += $(wildcard tileset_layouts/$(GAME)$(REGION_SUFFIX)/tilesetCollisions*.bin) endif COLLISIONFILES := $(COLLISIONFILES:.bin=.cmp) @@ -216,8 +217,8 @@ COLLISIONFILES := $(foreach file, $(COLLISIONFILES), \ MAPPINGINDICESFILES = $(wildcard tileset_layouts/$(GAME)/tilesetMappings*.bin) -ifeq ($(REGION), jp) -MAPPINGINDICESFILES += $(wildcard tileset_layouts/$(GAME)_jp/tilesetMappings*.bin) +ifneq ($(filter jp eu,$(REGION)),) +MAPPINGINDICESFILES += $(wildcard tileset_layouts/$(GAME)$(REGION_SUFFIX)/tilesetMappings*.bin) endif MAPPINGINDICESFILES := $(foreach file, $(MAPPINGINDICESFILES), \ $(BUILD_DIR)/tileset_layouts/$(notdir $(file))) @@ -277,8 +278,8 @@ $(BUILD_DIR)/$(GAME).o: $(GAME).s $(TEXT_DATA_FILE) $(BUILD_DIR)/textDefines.s M $(BUILD_DIR)/%.o: code/%.s | $(BUILD_DIR) $(CC) -o $@ $(CFLAGS) $< -ifeq ($(REGION), jp) -$(BUILD_DIR)/rooms/%.cmp: rooms/$(GAME)_jp/small/%.bin | $(BUILD_DIR)/rooms +ifneq ($(filter jp eu,$(REGION)),) +$(BUILD_DIR)/rooms/%.cmp: rooms/$(GAME)$(REGION_SUFFIX)/small/%.bin | $(BUILD_DIR)/rooms @echo "Compressing $< to $@..." @$(PYTHON) tools/build/compressRoomLayout.py $< $@ $(OPTIMIZE) endif @@ -352,7 +353,7 @@ endif ifeq ($(BUILD_VANILLA),true) # Precompressed copy rules for vanilla builds. -# For JP, game_jp source rules are listed first to take priority over the +# For JP/EU, game_ source rules are listed first to take priority over the # generic game rules (which serve as fallback for shared files). define define_precmp_copy_rule $(BUILD_DIR)/$(1)/%.$(2): precompressed/$(1)/$(3)/%.$(2) | $(BUILD_DIR)/$(1) @@ -360,10 +361,10 @@ $(BUILD_DIR)/$(1)/%.$(2): precompressed/$(1)/$(3)/%.$(2) | $(BUILD_DIR)/$(1) @cp $$< $$@ endef -ifeq ($(REGION), jp) -$(eval $(call define_precmp_copy_rule,tileset_layouts,bin,$(GAME)_jp)) -$(eval $(call define_precmp_copy_rule,tileset_layouts,cmp,$(GAME)_jp)) -$(eval $(call define_precmp_copy_rule,rooms,cmp,$(GAME)_jp)) +ifneq ($(filter jp eu,$(REGION)),) +$(eval $(call define_precmp_copy_rule,tileset_layouts,bin,$(GAME)$(REGION_SUFFIX))) +$(eval $(call define_precmp_copy_rule,tileset_layouts,cmp,$(GAME)$(REGION_SUFFIX))) +$(eval $(call define_precmp_copy_rule,rooms,cmp,$(GAME)$(REGION_SUFFIX))) endif $(eval $(call define_precmp_copy_rule,tileset_layouts,bin,$(GAME))) @@ -406,10 +407,10 @@ $(BUILD_DIR)/tileset_layouts/tilesetCollisions%.cmp: tileset_layouts/$(GAME)/til @$(PYTHON) tools/build/compressTilesetLayoutData.py $< $@ 0 $(BUILD_DIR)/tileset_layouts/collisionsDictionary.bin # Generate large room compression rules for each group prefix (04, 05, 06). -# For JP, the _jp source directory rules are listed first to take priority. +# For JP/EU, the _ source directory rules are listed first to take priority. define define_large_room_rules -ifeq ($(REGION), jp) -$(BUILD_DIR)/rooms/room$(1)%.cmp: rooms/$(GAME)_jp/large/room$(1)%.bin | $(BUILD_DIR)/rooms +ifneq ($(filter jp eu,$(REGION)),) +$(BUILD_DIR)/rooms/room$(1)%.cmp: rooms/$(GAME)$(REGION_SUFFIX)/large/room$(1)%.bin | $(BUILD_DIR)/rooms @echo "Compressing $$< to $$@..." @$$(PYTHON) tools/build/compressRoomLayout.py $$< $$@ -d rooms/$(GAME)/dictionary$(2).bin endif diff --git a/code/bank0.s b/code/bank0.s index 0df634ae..90b8b881 100644 --- a/code/bank0.s +++ b/code/bank0.s @@ -222,9 +222,13 @@ bitTable: .ifdef REGION_JP .ASC "AZ7J" - .else + .endif + .ifdef REGION_US .asc "AZ7E" .endif + .ifdef REGION_EU + .asc "AZ7P" + .endif .else ; ROM_AGES .asc "ZELDA NAYRU" @@ -1256,21 +1260,54 @@ loadGfxHeader: ldh a,(/dev/null +if md5sum -c ${FILENAME}.md5 2>/dev/null; then + exit 0 +fi + +# MD5 mismatch: do a bank-by-bank comparison with the reference ROM +GAME_CAP="$(echo "${GAME:0:1}" | tr '[:lower:]' '[:upper:]')${GAME:1}" +REGION_UP="$(echo "$REGION" | tr '[:lower:]' '[:upper:]')" +REFERENCE="../${GAME_CAP} ${REGION_UP} Reference.gbc" + +if [ ! -f "$REFERENCE" ]; then + echo "Reference ROM not found: $REFERENCE" + exit 1 +fi + +python3 - "${FILENAME}.gbc" "$REFERENCE" <<'EOF' +import sys + +BANK_SIZE = 0x4000 +built_path, ref_path = sys.argv[1], sys.argv[2] + +with open(built_path, 'rb') as f: + built = f.read() +with open(ref_path, 'rb') as f: + ref = f.read() + +total_banks = len(ref) // BANK_SIZE +print() +print("Bank-by-bank comparison vs reference ROM:") +print(" Bank | Match % | Bytes matched") +print("--------|-----------|---------------") +total_matched = 0 +total_bytes = total_banks * BANK_SIZE +for bank in range(total_banks): + s = bank * BANK_SIZE + e = s + BANK_SIZE + b = built[s:e] + r = ref[s:e] + n = min(len(b), len(r)) + matched = sum(b[i] == r[i] for i in range(n)) + total_matched += matched + pct = matched / BANK_SIZE * 100 + print(f" {bank:02x} | {pct:6.2f}% | [{matched}/{BANK_SIZE}]") +print("--------|-----------|---------------") +total_pct = total_matched / total_bytes * 100 +print(f" Total | {total_pct:6.2f}% | [{total_matched}/{total_bytes}]") +EOF