Super Mario 64s source code (from a leak on 4chan so be careful)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

432 lines
14 KiB

5 years ago
  1. # Makefile to rebuild SM64 split image
  2. ### Default target ###
  3. default: all
  4. ### Build Options ###
  5. # Version of the game to build and graphics microcode used
  6. VERSION ?= us
  7. GRUCODE ?= f3d_old
  8. # If COMPARE is 1, check the output sha1sum when building 'all'
  9. COMPARE ?= 1
  10. # If NON_MATCHING is 1, define the NON_MATCHING macro when building
  11. NON_MATCHING ?= 0
  12. # If ENDIAN_IND is 1, enable non-matching code changes that try to ensure
  13. # endianness independence
  14. ENDIAN_IND ?= 0
  15. # Release
  16. ifeq ($(VERSION),jp)
  17. VERSION_CFLAGS := -DVERSION_JP=1
  18. VERSION_ASFLAGS := --defsym VERSION_JP=1
  19. GRUCODE_CFLAGS := -DF3D_OLD
  20. GRUCODE_ASFLAGS := --defsym F3D_OLD=1
  21. TARGET := sm64.j
  22. else
  23. ifeq ($(VERSION),us)
  24. VERSION_CFLAGS := -DVERSION_US=1
  25. VERSION_ASFLAGS := --defsym VERSION_US=1
  26. GRUCODE_CFLAGS := -DF3D_OLD
  27. GRUCODE_ASFLAGS := --defsym F3D_OLD=1
  28. TARGET := sm64.u
  29. else
  30. ifeq ($(VERSION),eu)
  31. $(warning Building EU is experimental and is prone to breaking. Try at your own risk.)
  32. VERSION_CFLAGS := -DVERSION_EU=1
  33. VERSION_ASFLAGS := --defsym VERSION_US=1 --defsym VERSION_EU=1
  34. GRUCODE_CFLAGS := -DF3D_OLD
  35. GRUCODE_ASFLAGS := --defsym F3D_OLD=1
  36. TARGET := sm64.eu
  37. else
  38. $(error unknown version "$(VERSION)")
  39. endif
  40. endif
  41. endif
  42. # Microcode
  43. ifeq ($(GRUCODE),f3dex) # Fast3DEX
  44. GRUCODE_CFLAGS := -DF3DEX_GBI=1
  45. GRUCODE_ASFLAGS := --defsym F3DEX_GBI_SHARED=1 --defsym F3DEX_GBI=1
  46. TARGET := $(TARGET).f3dex
  47. COMPARE := 0
  48. else
  49. ifeq ($(GRUCODE), f3dex2) # Fast3DEX2
  50. GRUCODE_CFLAGS := -DF3DEX_GBI_2=1
  51. GRUCODE_ASFLAGS := --defsym F3DEX_GBI_SHARED=1 --defsym F3DEX_GBI_2=1
  52. TARGET := $(TARGET).f3dex2
  53. COMPARE := 0
  54. else
  55. ifeq ($(GRUCODE),f3d_new) # Fast3D 2.0H (Shindou)
  56. GRUCODE_CFLAGS := -DF3D_NEW
  57. GRUCODE_ASFLAGS := --defsym F3D_NEW=1
  58. TARGET := $(TARGET).f3d_new
  59. COMPARE := 0
  60. else
  61. ifeq ($(GRUCODE),f3dzex) # Fast3DZEX (2.0J / Animal Forest - Dōbutsu no Mori)
  62. $(warning Fast3DZEX is experimental. Try at your own risk.)
  63. GRUCODE_CFLAGS := -DF3DEX_GBI_2=1
  64. GRUCODE_ASFLAGS := --defsym F3DEX_GBI_SHARED=1 --defsym F3DZEX_GBI=1
  65. TARGET := $(TARGET).f3dzex
  66. COMPARE := 0
  67. endif
  68. endif
  69. endif
  70. endif
  71. ifeq ($(NON_MATCHING),1)
  72. VERSION_CFLAGS := $(VERSION_CFLAGS) -DNON_MATCHING=1
  73. COMPARE := 0
  74. endif
  75. ifeq ($(ENDIAN_IND),1)
  76. VERSION_CFLAGS := $(VERSION_CFLAGS) -DENDIAN_IND=1
  77. COMPARE := 0
  78. endif
  79. ################ Target Executable and Sources ###############
  80. # BUILD_DIR is location where all build artifacts are placed
  81. BUILD_DIR_BASE := build
  82. BUILD_DIR := $(BUILD_DIR_BASE)/$(VERSION)
  83. LIBULTRA := $(BUILD_DIR)/libultra.a
  84. ROM := $(BUILD_DIR)/$(TARGET).z64
  85. ELF := $(BUILD_DIR)/$(TARGET).elf
  86. LD_SCRIPT := sm64.ld
  87. MIO0_DIR := $(BUILD_DIR)/mio0
  88. TEXTURE_DIR := textures
  89. ACTOR_DIR := actors
  90. # Directories containing source files
  91. SRC_DIRS := src src/engine src/game src/goddard src/goddard/dynlists src/audio
  92. ASM_DIRS := asm actors lib data levels assets text
  93. BIN_DIRS := bin
  94. ULTRA_SRC_DIRS := lib/src lib/src/math
  95. ULTRA_ASM_DIRS := lib/asm lib/data
  96. ULTRA_BIN_DIRS := lib/bin
  97. LEVEL_DIRS := $(patsubst levels/%,%,$(dir $(wildcard levels/*/header.s)))
  98. MIPSISET := -mips2 -32
  99. ifeq ($(VERSION),eu)
  100. OPT_FLAGS := -O2
  101. else
  102. OPT_FLAGS := -g
  103. endif
  104. # File dependencies and variables for specific files
  105. include Makefile.split
  106. # Source code files
  107. C_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.c))
  108. S_FILES := $(foreach dir,$(ASM_DIRS),$(wildcard $(dir)/*.s))
  109. ULTRA_C_FILES := $(foreach dir,$(ULTRA_SRC_DIRS),$(wildcard $(dir)/*.c))
  110. ULTRA_S_FILES := $(foreach dir,$(ULTRA_ASM_DIRS),$(wildcard $(dir)/*.s))
  111. LEVEL_S_FILES := $(addsuffix header.s,$(addprefix bin/,$(LEVEL_DIRS)))
  112. SEG_IN_FILES := $(foreach dir,$(BIN_DIRS),$(wildcard $(dir)/*.s.in))
  113. SEG_S_FILES := $(foreach dir,$(BIN_DIRS),$(wildcard $(dir)/*.s)) \
  114. $(foreach file,$(SEG_IN_FILES),$(file:.s.in=.s))
  115. # Object files
  116. O_FILES := $(foreach file,$(C_FILES),$(BUILD_DIR)/$(file:.c=.o)) \
  117. $(foreach file,$(S_FILES),$(BUILD_DIR)/$(file:.s=.o)) \
  118. $(foreach file,$(LEVEL_S_FILES),$(BUILD_DIR)/$(file:.s=.o))
  119. ULTRA_O_FILES := $(foreach file,$(ULTRA_S_FILES),$(BUILD_DIR)/$(file:.s=.o)) \
  120. $(foreach file,$(ULTRA_C_FILES),$(BUILD_DIR)/$(file:.c=.o))
  121. # Automatic dependency files
  122. DEP_FILES := $(O_FILES:.o=.d) $(ULTRA_O_FILES:.o=.d)
  123. # Files with NON_MATCHING ifdefs
  124. NON_MATCHING_C_FILES != grep -rl NON_MATCHING $(wildcard src/audio/*.c)
  125. NON_MATCHING_O_FILES = $(foreach file,$(NON_MATCHING_C_FILES),$(BUILD_DIR)/$(file:.c=.o))
  126. NON_MATCHING_DEP = $(BUILD_DIR)/src/audio/non_matching_dep
  127. # Segment elf files
  128. SEG_FILES := $(foreach file,$(SEG_S_FILES),$(BUILD_DIR)/$(file:.s=.elf)) $(ACTOR_ELF_FILES) $(LEVEL_ELF_FILES)
  129. ##################### Compiler Options #######################
  130. IRIX_ROOT := tools/ido5.3_compiler
  131. ifeq ($(shell type mips-linux-gnu-ld >/dev/null 2>/dev/null; echo $$?), 0)
  132. CROSS := mips-linux-gnu-
  133. else
  134. CROSS := mips64-elf-
  135. endif
  136. AS := $(CROSS)as
  137. CC := $(QEMU_IRIX) -silent -L $(IRIX_ROOT) $(IRIX_ROOT)/usr/bin/cc
  138. CPP := cpp -P
  139. LD := $(CROSS)ld
  140. AR := $(CROSS)ar
  141. OBJDUMP := $(CROSS)objdump
  142. OBJCOPY := $(CROSS)objcopy
  143. # Check code syntax with host compiler
  144. CC_CHECK := gcc -fsyntax-only -fsigned-char -nostdinc -I include -I $(BUILD_DIR)/include -I src -std=gnu90 -Wall -Wextra -Wno-format-security -D_LANGUAGE_C $(VERSION_CFLAGS) $(GRUCODE_CFLAGS)
  145. ASFLAGS := -march=vr4300 -mabi=32 -I include -I $(BUILD_DIR) $(VERSION_ASFLAGS) $(GRUCODE_ASFLAGS)
  146. CFLAGS = -Wab,-r4300_mul -non_shared -G 0 -Xcpluscomm -Xfullwarn $(OPT_FLAGS) -signed -I include -I $(BUILD_DIR)/include -I src -D_LANGUAGE_C $(VERSION_CFLAGS) $(MIPSISET) $(GRUCODE_CFLAGS)
  147. OBJCOPYFLAGS := --pad-to=0x800000 --gap-fill=0xFF
  148. SYMBOL_LINKING_FLAGS := $(addprefix -R ,$(SEG_FILES))
  149. LDFLAGS := -T undefined_syms.txt -T $(BUILD_DIR)/$(LD_SCRIPT) -Map $(BUILD_DIR)/sm64.map --no-check-sections $(SYMBOL_LINKING_FLAGS)
  150. ifeq ($(shell getconf LONG_BIT), 32)
  151. # Work around memory allocation bug in QEMU
  152. export QEMU_GUEST_BASE := 1
  153. else
  154. # Ensure that gcc treats the code as 32-bit
  155. CC_CHECK += -m32
  156. endif
  157. ####################### Other Tools #########################
  158. # N64 tools
  159. TOOLS_DIR = tools
  160. MIO0TOOL = $(TOOLS_DIR)/mio0
  161. N64CKSUM = $(TOOLS_DIR)/n64cksum
  162. N64GRAPHICS = $(TOOLS_DIR)/n64graphics
  163. N64GRAPHICS_CI = $(TOOLS_DIR)/n64graphics_ci
  164. TEXTCONV = $(TOOLS_DIR)/textconv
  165. IPLFONTUTIL = $(TOOLS_DIR)/iplfontutil
  166. EMULATOR = mupen64plus
  167. EMU_FLAGS = --noosd
  168. LOADER = loader64
  169. LOADER_FLAGS = -vwf
  170. SHA1SUM = sha1sum
  171. # Make tools if out of date
  172. DUMMY != make -s -C tools >&2
  173. ###################### Dependency Check #####################
  174. BINUTILS_VER_MAJOR := $(shell $(LD) --version | grep ^GNU | sed 's/^.* //; s/\..*//g')
  175. BINUTILS_VER_MINOR := $(shell $(LD) --version | grep ^GNU | sed 's/^[^.]*\.//; s/\..*//g')
  176. BINUTILS_DEPEND := $(shell expr $(BINUTILS_VER_MAJOR) \>= 2 \& $(BINUTILS_VER_MINOR) \>= 27)
  177. ifeq ($(BINUTILS_DEPEND),0)
  178. $(error binutils version 2.27 required, version $(BINUTILS_VER_MAJOR).$(BINUTILS_VER_MINOR) detected)
  179. endif
  180. ifndef QEMU_IRIX
  181. $(error env variable QEMU_IRIX should point to the qemu-mips binary)
  182. endif
  183. ######################## Targets #############################
  184. all: $(ROM)
  185. ifeq ($(COMPARE),1)
  186. @$(SHA1SUM) -c $(TARGET).sha1
  187. endif
  188. clean:
  189. $(RM) -r $(BUILD_DIR_BASE)
  190. test: $(ROM)
  191. $(EMULATOR) $(EMU_FLAGS) $<
  192. load: $(ROM)
  193. $(LOADER) $(LOADER_FLAGS) $<
  194. libultra: $(BUILD_DIR)/libultra.a
  195. asm/boot.s: $(BUILD_DIR)/lib/bin/ipl3_font.bin
  196. $(BUILD_DIR)/lib/bin/ipl3_font.bin: lib/ipl3_font.png | $(BUILD_DIR)
  197. $(IPLFONTUTIL) e $< $@
  198. $(BUILD_DIR)/include/text_strings.h: include/text_strings.h.in | $(BUILD_DIR)
  199. $(TEXTCONV) charmap.txt $< $@
  200. $(BUILD_DIR)/text/%.s: text/$(VERSION)/%.s.in | $(BUILD_DIR)
  201. $(TEXTCONV) charmap.txt $< $@
  202. build/bin/segment2.o: bin/segment2.s
  203. bin/segment2.s: $(BUILD_DIR)/text/debug.s $(BUILD_DIR)/text/dialog.s $(BUILD_DIR)/text/level.s $(BUILD_DIR)/text/star.s
  204. touch bin/segment2.s
  205. $(MIO0_DIR)/%.mio0: bin/%.bin
  206. $(MIO0TOOL) $< $@
  207. ALL_DIRS := $(BUILD_DIR) $(addprefix $(BUILD_DIR)/,$(SRC_DIRS) $(ASM_DIRS) $(ULTRA_SRC_DIRS) $(ULTRA_ASM_DIRS) $(ULTRA_BIN_DIRS) $(BIN_DIRS) $(TEXTURE_DIRS) $(addprefix levels/,$(LEVEL_DIRS)) $(addprefix bin/,$(LEVEL_DIRS)) include) $(MIO0_DIR) $(addprefix $(MIO0_DIR)/,$(LEVEL_DIRS))
  208. # Make sure build directory exists before compiling anything
  209. DUMMY != mkdir -p $(ALL_DIRS)
  210. $(BUILD_DIR)/src/game/star_select.o: $(BUILD_DIR)/include/text_strings.h
  211. $(BUILD_DIR)/src/game/file_select.o: $(BUILD_DIR)/include/text_strings.h
  212. $(BUILD_DIR)/src/game/ingame_menu.o: $(BUILD_DIR)/include/text_strings.h
  213. # texture generation
  214. $(BUILD_DIR)/bin/%.rgba16: textures/%.rgba16.png
  215. $(N64GRAPHICS) -i $@ -g $< -f rgba16
  216. $(BUILD_DIR)/bin/%.ia16: textures/%.ia16.png
  217. $(N64GRAPHICS) -i $@ -g $< -f ia16
  218. $(BUILD_DIR)/bin/%.ia8: textures/%.ia8.png
  219. $(N64GRAPHICS) -i $@ -g $< -f ia8
  220. $(BUILD_DIR)/bin/%.ia4: textures/%.ia4.png
  221. $(N64GRAPHICS) -i $@ -g $< -f ia4
  222. $(BUILD_DIR)/bin/%.ia1: textures/%.ia1.png
  223. $(N64GRAPHICS) -i $@ -g $< -f ia1
  224. # Color index textures (not used by SM64)
  225. $(BUILD_DIR)/bin/%.ci8: textures/%.ci8.png
  226. $(N64GRAPHICS_CI) -i $@ -g $< -f ci8
  227. $(BUILD_DIR)/bin/%.ci4: textures/%.ci4.png
  228. $(N64GRAPHICS_CI) -i $@ -g $< -f ci4
  229. # texture generation 2nd method: rgba16s are preferred (and used
  230. # more often) over the ones listed below due to more colors.
  231. $(BUILD_DIR)/actors/%.rgba16: actors/%.rgba16.png
  232. $(N64GRAPHICS) -i $@ -g $< -f rgba16
  233. $(BUILD_DIR)/actors/%.ia16: actors/%.ia16.png
  234. $(N64GRAPHICS) -i $@ -g $< -f ia16
  235. $(BUILD_DIR)/actors/%.ia8: actors/%.ia8.png
  236. $(N64GRAPHICS) -i $@ -g $< -f ia8
  237. $(BUILD_DIR)/actors/%.ia4: actors/%.ia4.png
  238. $(N64GRAPHICS) -i $@ -g $< -f ia4
  239. $(BUILD_DIR)/actors/%.ia1: actors/%.ia1.png
  240. $(N64GRAPHICS) -i $@ -g $< -f ia1
  241. # Color index textures (not used by SM64)
  242. $(BUILD_DIR)/actors/%.ci8: actors/%.ci8.png
  243. $(N64GRAPHICS_CI) -i $@ -g $< -f ci8
  244. $(BUILD_DIR)/actors/%.ci4: actors/%.ci4.png
  245. $(N64GRAPHICS_CI) -i $@ -g $< -f ci4
  246. # texture generation 3rd method: rgba16s are preferred (and used
  247. # more often) over the ones listed below due to more colors.
  248. $(BUILD_DIR)/levels/%.rgba16: levels/%.rgba16.png
  249. $(N64GRAPHICS) -i $@ -g $< -f rgba16
  250. $(BUILD_DIR)/levels/%.ia16: levels/%.ia16.png
  251. $(N64GRAPHICS) -i $@ -g $< -f ia16
  252. $(BUILD_DIR)/levels/%.ia8: levels/%.ia8.png
  253. $(N64GRAPHICS) -i $@ -g $< -f ia8
  254. $(BUILD_DIR)/levels/%.ia4: levels/%.ia4.png
  255. $(N64GRAPHICS) -i $@ -g $< -f ia4
  256. $(BUILD_DIR)/levels/%.ia1: levels/%.ia1.png
  257. $(N64GRAPHICS) -i $@ -g $< -f ia1
  258. # Color index textures (not used by SM64)
  259. $(BUILD_DIR)/levels/%.ci8: levels/%.ci8.png
  260. $(N64GRAPHICS_CI) -i $@ -g $< -f ci8
  261. $(BUILD_DIR)/levels/%.ci4: levels/%.ci4.png
  262. $(N64GRAPHICS_CI) -i $@ -g $< -f ci4
  263. # compressed segment generation
  264. $(BUILD_DIR)/bin/%.o: bin/%.s
  265. $(AS) $(ASFLAGS) --no-pad-sections -o $@ $<
  266. # compressed segment generation (actors)
  267. $(BUILD_DIR)/bin/%.o: actors/%.s
  268. $(AS) $(ASFLAGS) --no-pad-sections -o $@ $<
  269. $(BUILD_DIR)/bin/%/leveldata.o: levels/%/leveldata.s
  270. $(AS) $(ASFLAGS) --no-pad-sections -o $@ $<
  271. $(BUILD_DIR)/bin/%/header.o: levels/%/header.s $(MIO0_DIR)/%/leveldata.mio0 levels/%/script.s
  272. $(AS) $(ASFLAGS) --no-pad-sections -o $@ $<
  273. # TODO: ideally this would be `-Trodata-segment=0x07000000` but that doesn't set the address
  274. $(BUILD_DIR)/bin/%.elf: $(BUILD_DIR)/bin/%.o
  275. $(LD) -e 0 -Ttext=$(SEGMENT_ADDRESS) -Map $@.map -o $@ $<
  276. # Override for level.elf, which otherwise matches the above pattern
  277. .SECONDEXPANSION:
  278. $(BUILD_DIR)/bin/%/leveldata.elf: $(BUILD_DIR)/bin/%/leveldata.o $(BUILD_DIR)/bin/$$(TEXTURE_BIN).elf
  279. $(LD) -e 0 -Ttext=$(SEGMENT_ADDRESS) -Map $@.map --just-symbols=$(BUILD_DIR)/bin/$(TEXTURE_BIN).elf -o $@ $<
  280. $(BUILD_DIR)/bin/%.bin: $(BUILD_DIR)/bin/%.elf
  281. $(OBJCOPY) -j .rodata $< -O binary $@
  282. $(MIO0_DIR)/%.mio0: $(BUILD_DIR)/bin/%.bin
  283. $(MIO0TOOL) $< $@
  284. $(MIO0_DIR)/%.mio0.o: $(MIO0_DIR)/%.mio0.s
  285. $(AS) $(ASFLAGS) -o $@ $<
  286. $(MIO0_DIR)/%.mio0.s: $(MIO0_DIR)/%.mio0
  287. printf ".section .data\n\n.incbin \"$<\"\n" > $@
  288. # Source code
  289. $(BUILD_DIR)/src/goddard/%.o: OPT_FLAGS := -g
  290. $(BUILD_DIR)/src/goddard/%.o: MIPSISET := -mips1
  291. $(BUILD_DIR)/src/audio/%.o: CC := python3 tools/asm_processor/build.py $(CC) -- $(AS) $(ASFLAGS) --
  292. $(BUILD_DIR)/src/audio/%.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0
  293. $(BUILD_DIR)/src/audio/dma.o: OPT_FLAGS := -O2 -framepointer -Wo,-loopunroll,0
  294. $(BUILD_DIR)/lib/src/%.o: OPT_FLAGS :=
  295. $(BUILD_DIR)/lib/src/math/ll%.o: MIPSISET := -mips3 -32
  296. $(BUILD_DIR)/lib/src/math/%.o: OPT_FLAGS := -O2
  297. $(BUILD_DIR)/lib/src/math/ll%.o: OPT_FLAGS :=
  298. $(BUILD_DIR)/lib/src/ldiv.o: OPT_FLAGS := -O2
  299. $(BUILD_DIR)/lib/src/string.o: OPT_FLAGS := -O2
  300. $(BUILD_DIR)/lib/src/gu%.o: OPT_FLAGS := -O3
  301. $(BUILD_DIR)/lib/src/al%.o: OPT_FLAGS := -O3
  302. # Rebuild files with '#ifdef NON_MATCHING' when that macro changes.
  303. $(NON_MATCHING_O_FILES): $(NON_MATCHING_DEP).$(NON_MATCHING)
  304. $(NON_MATCHING_DEP).$(NON_MATCHING):
  305. @rm -f $(NON_MATCHING_DEP).*
  306. touch $@
  307. $(BUILD_DIR)/lib/src/math/%.o: lib/src/math/%.c
  308. @$(CC_CHECK) -MMD -MP -MT $@ -MF $(BUILD_DIR)/lib/src/math/$*.d $<
  309. $(CC) -c $(CFLAGS) -o $@ $<
  310. tools/patch_libultra_math $@ || rm $@
  311. $(BUILD_DIR)/%.o: %.c
  312. @$(CC_CHECK) -MMD -MP -MT $@ -MF $(BUILD_DIR)/$*.d $<
  313. $(CC) -c $(CFLAGS) -o $@ $<
  314. $(BUILD_DIR)/%.o: %.s $(MIO0_FILES)
  315. $(AS) $(ASFLAGS) -MD $(BUILD_DIR)/$*.d -o $@ $<
  316. $(BUILD_DIR)/$(LD_SCRIPT): $(LD_SCRIPT)
  317. $(CPP) $(VERSION_CFLAGS) -I include/ -DBUILD_DIR=$(BUILD_DIR) -o $@ $<
  318. $(BUILD_DIR)/libultra.a: $(ULTRA_O_FILES)
  319. $(AR) rcs -o $@ $(ULTRA_O_FILES)
  320. $(ELF): $(O_FILES) $(MIO0_OBJ_FILES) $(SEG_FILES) $(BUILD_DIR)/$(LD_SCRIPT) undefined_syms.txt $(BUILD_DIR)/libultra.a
  321. $(LD) -L $(BUILD_DIR) $(LDFLAGS) -o $@ $(O_FILES)$(LIBS) -lultra
  322. $(ROM): $(ELF)
  323. $(OBJCOPY) $(OBJCOPYFLAGS) $< $(@:.z64=.bin) -O binary
  324. $(N64CKSUM) $(@:.z64=.bin) $@
  325. $(BUILD_DIR)/$(TARGET).objdump: $(ELF)
  326. $(OBJDUMP) -D $< > $@
  327. .PHONY: all clean default diff test load libultra
  328. .PRECIOUS: $(BUILD_DIR)/mio0/%.mio0 $(BUILD_DIR)/bin/%.elf $(BUILD_DIR)/mio0/%.mio0.s
  329. # Remove built-in rules, to improve performance
  330. MAKEFLAGS += --no-builtin-rules
  331. -include $(DEP_FILES)
  332. print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true