Super Mario 64 OpenGL port for PC. Mirror of https://github.com/sm64pc/sm64pc https://github.com/sm64pc/sm64pc
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.
 
 
 
 
 
 

761 lines
25 KiB

  1. # Makefile to rebuild SM64 split image
  2. ### Default target ###
  3. default: all
  4. ### Build Options ###
  5. # These options can either be changed by modifying the makefile, or
  6. # by building with 'make SETTING=value'. 'make clean' may be required.
  7. # Version of the game to build
  8. VERSION ?= us
  9. # Graphics microcode used
  10. GRUCODE ?= f3d_old
  11. # If COMPARE is 1, check the output sha1sum when building 'all'
  12. COMPARE ?= 1
  13. # If NON_MATCHING is 1, define the NON_MATCHING and AVOID_UB macros when building (recommended)
  14. NON_MATCHING ?= 1
  15. # Sane default until N64 build scripts rm'd
  16. TARGET_N64 = 0
  17. # Build and optimize for Raspberry Pi(s)
  18. TARGET_RPI ?= 0
  19. # Compiler to use (ido or gcc)
  20. COMPILER ?= ido
  21. # Disable better camera by default
  22. BETTERCAMERA ?= 0
  23. # Build for Emscripten/WebGL
  24. TARGET_WEB ?= 0
  25. # Specify the target you are building for, 0 means native
  26. TARGET_ARCH ?= native
  27. TARGET_BITS ?= 0
  28. ifneq ($(TARGET_BITS),0)
  29. BITS := -m$(TARGET_BITS)
  30. else
  31. BITS :=
  32. endif
  33. # Automatic settings for PC port(s)
  34. # WINDOWS_BUILD IS NOT FOR COMPILING A WINDOWS EXECUTABLE UNDER LINUX OR WSL!
  35. # USE THE WIKI GUIDE WITH MSYS2 FOR COMPILING A WINDOWS EXECUTABLE!
  36. NON_MATCHING := 1
  37. GRUCODE := f3dex2e
  38. WINDOWS_BUILD := 0
  39. ifeq ($(TARGET_WEB),0)
  40. ifeq ($(OS),Windows_NT)
  41. WINDOWS_BUILD := 1
  42. endif
  43. endif
  44. # Release (version) flag defs
  45. ifeq ($(VERSION),jp)
  46. VERSION_CFLAGS := -DVERSION_JP
  47. VERSION_ASFLAGS := --defsym VERSION_JP=1
  48. GRUCODE_CFLAGS := -DF3D_OLD
  49. GRUCODE_ASFLAGS := --defsym F3D_OLD=1
  50. TARGET := sm64.jp
  51. else
  52. ifeq ($(VERSION),us)
  53. VERSION_CFLAGS := -DVERSION_US
  54. VERSION_ASFLAGS := --defsym VERSION_US=1
  55. GRUCODE_CFLAGS := -DF3D_OLD
  56. GRUCODE_ASFLAGS := --defsym F3D_OLD=1
  57. TARGET := sm64.us
  58. else
  59. ifeq ($(VERSION),eu)
  60. VERSION_CFLAGS := -DVERSION_EU
  61. VERSION_ASFLAGS := --defsym VERSION_EU=1
  62. GRUCODE_CFLAGS := -DF3D_NEW
  63. GRUCODE_ASFLAGS := --defsym F3D_NEW=1
  64. TARGET := sm64.eu
  65. else
  66. ifeq ($(VERSION),sh)
  67. $(warning Building SH is experimental and is prone to breaking. Try at your own risk.)
  68. VERSION_CFLAGS := -DVERSION_SH
  69. VERSION_ASFLAGS := --defsym VERSION_SH=1
  70. GRUCODE_CFLAGS := -DF3D_NEW
  71. GRUCODE_ASFLAGS := --defsym F3D_NEW=1
  72. TARGET := sm64.sh
  73. # TODO: GET RID OF THIS!!! We should mandate assets for Shindou like EU but we dont have the addresses extracted yet so we'll just pretend you have everything extracted for now.
  74. NOEXTRACT := 1
  75. else
  76. $(error unknown version "$(VERSION)")
  77. endif
  78. endif
  79. endif
  80. endif
  81. # Microcode
  82. ifeq ($(GRUCODE),f3dex) # Fast3DEX
  83. GRUCODE_CFLAGS := -DF3DEX_GBI
  84. GRUCODE_ASFLAGS := --defsym F3DEX_GBI_SHARED=1 --defsym F3DEX_GBI=1
  85. TARGET := $(TARGET).f3dex
  86. COMPARE := 0
  87. else
  88. ifeq ($(GRUCODE), f3dex2) # Fast3DEX2
  89. GRUCODE_CFLAGS := -DF3DEX_GBI_2
  90. GRUCODE_ASFLAGS := --defsym F3DEX_GBI_SHARED=1 --defsym F3DEX_GBI_2=1
  91. TARGET := $(TARGET).f3dex2
  92. COMPARE := 0
  93. else
  94. ifeq ($(GRUCODE), f3dex2e) # Fast3DEX2 Extended (PC default)
  95. GRUCODE_CFLAGS := -DF3DEX_GBI_2E
  96. TARGET := $(TARGET).f3dex2e
  97. COMPARE := 0
  98. else
  99. ifeq ($(GRUCODE),f3d_new) # Fast3D 2.0H (Shindou)
  100. GRUCODE_CFLAGS := -DF3D_NEW
  101. GRUCODE_ASFLAGS := --defsym F3D_NEW=1
  102. TARGET := $(TARGET).f3d_new
  103. COMPARE := 0
  104. else
  105. ifeq ($(GRUCODE),f3dzex) # Fast3DZEX (2.0J / Animal Forest - Dōbutsu no Mori)
  106. $(warning Fast3DZEX is experimental. Try at your own risk.)
  107. GRUCODE_CFLAGS := -DF3DEX_GBI_2
  108. GRUCODE_ASFLAGS := --defsym F3DEX_GBI_SHARED=1 --defsym F3DZEX_GBI=1
  109. TARGET := $(TARGET).f3dzex
  110. COMPARE := 0
  111. endif
  112. endif
  113. endif
  114. endif
  115. endif
  116. # Default build is for PC now
  117. VERSION_CFLAGS := $(VERSION_CFLAGS) -DNON_MATCHING -DAVOID_UB
  118. ifeq ($(TARGET_RPI),1) # Define RPi to change SDL2 title & GLES2 hints
  119. VERSION_CFLAGS += -DUSE_GLES
  120. endif
  121. VERSION_ASFLAGS := --defsym AVOID_UB=1
  122. COMPARE := 0
  123. ifeq ($(TARGET_WEB),1)
  124. VERSION_CFLAGS := $(VERSION_CFLAGS) -DTARGET_WEB
  125. endif
  126. ################### Universal Dependencies ###################
  127. # (This is a bit hacky, but a lot of rules implicitly depend
  128. # on tools and assets, and we use directory globs further down
  129. # in the makefile that we want should cover assets.)
  130. ifneq ($(MAKECMDGOALS),clean)
  131. ifneq ($(MAKECMDGOALS),distclean)
  132. # Make sure assets exist
  133. NOEXTRACT ?= 0
  134. ifeq ($(NOEXTRACT),0)
  135. DUMMY != ./extract_assets.py $(VERSION) >&2 || echo FAIL
  136. ifeq ($(DUMMY),FAIL)
  137. $(error Failed to extract assets)
  138. endif
  139. endif
  140. # Make tools if out of date
  141. DUMMY != make -s -C tools >&2 || echo FAIL
  142. ifeq ($(DUMMY),FAIL)
  143. $(error Failed to build tools)
  144. endif
  145. endif
  146. endif
  147. ################ Target Executable and Sources ###############
  148. # BUILD_DIR is location where all build artifacts are placed
  149. BUILD_DIR_BASE := build
  150. ifeq ($(TARGET_WEB),1)
  151. BUILD_DIR := $(BUILD_DIR_BASE)/$(VERSION)_web
  152. else
  153. BUILD_DIR := $(BUILD_DIR_BASE)/$(VERSION)_pc
  154. endif
  155. LIBULTRA := $(BUILD_DIR)/libultra.a
  156. ifeq ($(TARGET_WEB),1)
  157. EXE := $(BUILD_DIR)/$(TARGET).html
  158. else
  159. ifeq ($(WINDOWS_BUILD),1)
  160. EXE := $(BUILD_DIR)/$(TARGET).exe
  161. else # Linux builds/binary namer
  162. ifeq ($(TARGET_RPI),1)
  163. EXE := $(BUILD_DIR)/$(TARGET).arm
  164. else
  165. EXE := $(BUILD_DIR)/$(TARGET)
  166. endif
  167. endif
  168. endif
  169. ELF := $(BUILD_DIR)/$(TARGET).elf
  170. LD_SCRIPT := sm64.ld
  171. MIO0_DIR := $(BUILD_DIR)/bin
  172. SOUND_BIN_DIR := $(BUILD_DIR)/sound
  173. TEXTURE_DIR := textures
  174. ACTOR_DIR := actors
  175. LEVEL_DIRS := $(patsubst levels/%,%,$(dir $(wildcard levels/*/header.h)))
  176. # Directories containing source files
  177. # Hi, I'm a PC
  178. SRC_DIRS := src src/engine src/game src/audio src/menu src/buffers actors levels bin data assets src/pc src/pc/gfx src/pc/audio src/pc/controller
  179. ASM_DIRS :=
  180. BIN_DIRS := bin bin/$(VERSION)
  181. ULTRA_SRC_DIRS := lib/src lib/src/math
  182. ULTRA_ASM_DIRS := lib/asm lib/data
  183. ULTRA_BIN_DIRS := lib/bin
  184. GODDARD_SRC_DIRS := src/goddard src/goddard/dynlists
  185. MIPSISET := -mips2
  186. MIPSBIT := -32
  187. ifeq ($(COMPILER),gcc)
  188. MIPSISET := -mips3
  189. endif
  190. ifeq ($(VERSION),eu)
  191. OPT_FLAGS := -O2
  192. else
  193. ifeq ($(VERSION),sh)
  194. OPT_FLAGS := -O2
  195. else
  196. OPT_FLAGS := -g
  197. endif
  198. endif
  199. # Set BITS (32/64) to compile for
  200. OPT_FLAGS += $(BITS)
  201. ifeq ($(TARGET_WEB),1)
  202. OPT_FLAGS := -O2 -g4 --source-map-base http://localhost:8080/
  203. endif
  204. # Use a default opt flag for gcc, then override if RPi
  205. ifeq ($(COMPILER),gcc)
  206. OPT_FLAGS := -O2 # Breaks sound on x86?
  207. endif
  208. ifeq ($(TARGET_RPI),1)
  209. machine = $(shell sh -c 'uname -m 2>/dev/null || echo unknown')
  210. # Raspberry Pi B+, Zero, etc
  211. ifneq (,$(findstring armv6l,$(machine)))
  212. OPT_FLAGS := -march=armv6zk+fp -mfpu=vfp -Ofast
  213. endif
  214. # Raspberry Pi 2 and 3 in ARM 32bit mode
  215. ifneq (,$(findstring armv7l,$(machine)))
  216. model = $(shell sh -c 'cat /sys/firmware/devicetree/base/model 2>/dev/null || echo unknown')
  217. ifneq (,$(findstring 3,$(model)))
  218. OPT_FLAGS := -march=armv8-a+crc -mtune=cortex-a53 -mfpu=neon-fp-armv8 -O3
  219. else
  220. OPT_FLAGS := -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -O3
  221. endif
  222. endif
  223. # RPi3 or RPi4, in ARM64 (aarch64) mode. NEEDS TESTING 32BIT.
  224. # DO NOT pass -mfpu stuff here, thats for 32bit ARM only and will fail for 64bit ARM.
  225. ifneq (,$(findstring aarch64,$(machine)))
  226. model = $(shell sh -c 'cat /sys/firmware/devicetree/base/model 2>/dev/null || echo unknown')
  227. ifneq (,$(findstring 3,$(model)))
  228. OPT_FLAGS := -march=armv8-a+crc -mtune=cortex-a53 -O3
  229. else ifneq (,$(findstring 4,$(model)))
  230. OPT_FLAGS := -march=armv8-a+crc+simd -mtune=cortex-a72 -O3
  231. endif
  232. endif
  233. endif
  234. # File dependencies and variables for specific files
  235. include Makefile.split
  236. # Source code files
  237. LEVEL_C_FILES := $(wildcard levels/*/leveldata.c) $(wildcard levels/*/script.c) $(wildcard levels/*/geo.c)
  238. C_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.c)) $(LEVEL_C_FILES)
  239. CXX_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.cpp))
  240. S_FILES := $(foreach dir,$(ASM_DIRS),$(wildcard $(dir)/*.s))
  241. ULTRA_C_FILES := $(foreach dir,$(ULTRA_SRC_DIRS),$(wildcard $(dir)/*.c))
  242. GODDARD_C_FILES := $(foreach dir,$(GODDARD_SRC_DIRS),$(wildcard $(dir)/*.c))
  243. GENERATED_C_FILES := $(BUILD_DIR)/assets/mario_anim_data.c $(BUILD_DIR)/assets/demo_data.c \
  244. $(addprefix $(BUILD_DIR)/bin/,$(addsuffix _skybox.c,$(notdir $(basename $(wildcard textures/skyboxes/*.png)))))
  245. ifeq ($(WINDOWS_BUILD),0)
  246. CXX_FILES :=
  247. endif
  248. # We need to keep this for now
  249. # If we're not N64 use below
  250. ULTRA_C_FILES_SKIP := \
  251. sqrtf.c \
  252. string.c \
  253. sprintf.c \
  254. _Printf.c \
  255. kdebugserver.c \
  256. osInitialize.c \
  257. func_802F7140.c \
  258. func_802F71F0.c \
  259. func_802F4A20.c \
  260. EU_D_802f4330.c \
  261. D_802F4380.c \
  262. osLeoDiskInit.c \
  263. osCreateThread.c \
  264. osDestroyThread.c \
  265. osStartThread.c \
  266. osSetThreadPri.c \
  267. osPiStartDma.c \
  268. osPiRawStartDma.c \
  269. osPiRawReadIo.c \
  270. osPiGetCmdQueue.c \
  271. osJamMesg.c \
  272. osSendMesg.c \
  273. osRecvMesg.c \
  274. osSetEventMesg.c \
  275. osTimer.c \
  276. osSetTimer.c \
  277. osSetTime.c \
  278. osCreateViManager.c \
  279. osViSetSpecialFeatures.c \
  280. osVirtualToPhysical.c \
  281. osViBlack.c \
  282. osViSetEvent.c \
  283. osViSetMode.c \
  284. osViSwapBuffer.c \
  285. osSpTaskLoadGo.c \
  286. osCreatePiManager.c \
  287. osGetTime.c \
  288. osEepromProbe.c \
  289. osEepromWrite.c \
  290. osEepromLongWrite.c \
  291. osEepromRead.c \
  292. osEepromLongRead.c \
  293. osContInit.c \
  294. osContStartReadData.c \
  295. osAiGetLength.c \
  296. osAiSetFrequency.c \
  297. osAiSetNextBuffer.c \
  298. __osViInit.c \
  299. __osSyncPutChars.c \
  300. __osAtomicDec.c \
  301. __osSiRawStartDma.c \
  302. __osViSwapContext.c \
  303. __osViGetCurrentContext.c \
  304. __osDevMgrMain.c
  305. C_FILES := $(filter-out src/game/main.c,$(C_FILES))
  306. ULTRA_C_FILES := $(filter-out $(addprefix lib/src/,$(ULTRA_C_FILES_SKIP)),$(ULTRA_C_FILES))
  307. # "If we're not N64, use the above"
  308. ifeq ($(VERSION),sh)
  309. SOUND_BANK_FILES := $(wildcard sound/sound_banks/*.json)
  310. SOUND_SEQUENCE_FILES := $(wildcard sound/sequences/jp/*.m64) \
  311. $(wildcard sound/sequences/*.m64) \
  312. $(foreach file,$(wildcard sound/sequences/jp/*.s),$(BUILD_DIR)/$(file:.s=.m64)) \
  313. $(foreach file,$(wildcard sound/sequences/*.s),$(BUILD_DIR)/$(file:.s=.m64))
  314. else
  315. SOUND_BANK_FILES := $(wildcard sound/sound_banks/*.json)
  316. SOUND_SEQUENCE_FILES := $(wildcard sound/sequences/$(VERSION)/*.m64) \
  317. $(wildcard sound/sequences/*.m64) \
  318. $(foreach file,$(wildcard sound/sequences/$(VERSION)/*.s),$(BUILD_DIR)/$(file:.s=.m64)) \
  319. $(foreach file,$(wildcard sound/sequences/*.s),$(BUILD_DIR)/$(file:.s=.m64))
  320. endif
  321. SOUND_SAMPLE_DIRS := $(wildcard sound/samples/*)
  322. SOUND_SAMPLE_AIFFS := $(foreach dir,$(SOUND_SAMPLE_DIRS),$(wildcard $(dir)/*.aiff))
  323. SOUND_SAMPLE_TABLES := $(foreach file,$(SOUND_SAMPLE_AIFFS),$(BUILD_DIR)/$(file:.aiff=.table))
  324. SOUND_SAMPLE_AIFCS := $(foreach file,$(SOUND_SAMPLE_AIFFS),$(BUILD_DIR)/$(file:.aiff=.aifc))
  325. SOUND_OBJ_FILES := $(SOUND_BIN_DIR)/sound_data.ctl.o \
  326. $(SOUND_BIN_DIR)/sound_data.tbl.o \
  327. $(SOUND_BIN_DIR)/sequences.bin.o \
  328. $(SOUND_BIN_DIR)/bank_sets.o
  329. # Object files
  330. O_FILES := $(foreach file,$(C_FILES),$(BUILD_DIR)/$(file:.c=.o)) \
  331. $(foreach file,$(CXX_FILES),$(BUILD_DIR)/$(file:.cpp=.o)) \
  332. $(foreach file,$(S_FILES),$(BUILD_DIR)/$(file:.s=.o)) \
  333. $(foreach file,$(GENERATED_C_FILES),$(file:.c=.o))
  334. ULTRA_O_FILES := $(foreach file,$(ULTRA_S_FILES),$(BUILD_DIR)/$(file:.s=.o)) \
  335. $(foreach file,$(ULTRA_C_FILES),$(BUILD_DIR)/$(file:.c=.o))
  336. GODDARD_O_FILES := $(foreach file,$(GODDARD_C_FILES),$(BUILD_DIR)/$(file:.c=.o))
  337. # Automatic dependency files
  338. DEP_FILES := $(O_FILES:.o=.d) $(ULTRA_O_FILES:.o=.d) $(GODDARD_O_FILES:.o=.d) $(BUILD_DIR)/$(LD_SCRIPT).d
  339. # Segment elf files
  340. SEG_FILES := $(SEGMENT_ELF_FILES) $(ACTOR_ELF_FILES) $(LEVEL_ELF_FILES)
  341. ##################### Compiler Options #######################
  342. INCLUDE_CFLAGS := -I include -I $(BUILD_DIR) -I $(BUILD_DIR)/include -I src -I .
  343. ENDIAN_BITWIDTH := $(BUILD_DIR)/endian-and-bitwidth
  344. # Huge deleted N64 section was here
  345. AS := as
  346. ifneq ($(TARGET_WEB),1) # As in, not-web PC port
  347. CC := $(CROSS)gcc
  348. CXX := $(CROSS)g++
  349. else
  350. CC := emcc
  351. endif
  352. ifeq ($(WINDOWS_BUILD),1)
  353. LD := $(CXX)
  354. else
  355. LD := $(CC)
  356. endif
  357. CPP := cpp -P
  358. OBJDUMP := objdump
  359. OBJCOPY := objcopy
  360. PYTHON := python3
  361. ifeq ($(WINDOWS_BUILD),1)
  362. CC_CHECK := $(CC) -fsyntax-only -fsigned-char $(INCLUDE_CFLAGS) -Wall -Wextra -Wno-format-security $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) `$(CROSS)sdl2-config --cflags`
  363. CFLAGS := $(OPT_FLAGS) $(INCLUDE_CFLAGS) $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -fno-strict-aliasing -fwrapv `$(CROSS)sdl2-config --cflags`
  364. else ifeq ($(TARGET_WEB),1)
  365. CC_CHECK := $(CC) -fsyntax-only -fsigned-char $(INCLUDE_CFLAGS) -Wall -Wextra -Wno-format-security $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -s USE_SDL=2
  366. CFLAGS := $(OPT_FLAGS) $(INCLUDE_CFLAGS) $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -fno-strict-aliasing -fwrapv -s USE_SDL=2
  367. # Linux / Other builds below
  368. else
  369. CC_CHECK := $(CC) -fsyntax-only -fsigned-char $(INCLUDE_CFLAGS) -Wall -Wextra -Wno-format-security $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) `$(CROSS)sdl2-config --cflags`
  370. CFLAGS := $(OPT_FLAGS) $(INCLUDE_CFLAGS) $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -fno-strict-aliasing -fwrapv `$(CROSS)sdl2-config --cflags`
  371. endif
  372. # Check for better camera option
  373. ifeq ($(BETTERCAMERA),1)
  374. CC_CHECK += -DBETTERCAMERA
  375. CFLAGS += -DBETTERCAMERA
  376. endif
  377. ASFLAGS := -I include -I $(BUILD_DIR) $(VERSION_ASFLAGS)
  378. ifeq ($(TARGET_WEB),1)
  379. LDFLAGS := -lm -lGL -lSDL2 -no-pie -s TOTAL_MEMORY=20MB -g4 --source-map-base http://localhost:8080/ -s "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain']"
  380. else
  381. ifeq ($(WINDOWS_BUILD),1)
  382. LDFLAGS := $(BITS) -march=$(TARGET_ARCH) -Llib -lpthread -lglew32 `$(CROSS)sdl2-config --static-libs` -lm -lglu32 -lsetupapi -ldinput8 -luser32 -lgdi32 -limm32 -lole32 -loleaut32 -lshell32 -lwinmm -lversion -luuid -lopengl32 -no-pie -static
  383. else
  384. # Linux / Other builds below
  385. ifeq ($(TARGET_RPI),1)
  386. LDFLAGS := $(OPT_FLAGS) -lm -lGLESv2 `$(CROSS)sdl2-config --libs` -no-pie
  387. else
  388. LDFLAGS := $(BITS) -march=$(TARGET_ARCH) -lm -lGL `$(CROSS)sdl2-config --libs` -no-pie -lpthread
  389. endif
  390. endif
  391. endif #Added for Pi ifeq
  392. # Prevent a crash with -sopt
  393. export LANG := C
  394. ####################### Other Tools #########################
  395. # N64 conversion tools
  396. TOOLS_DIR = tools
  397. MIO0TOOL = $(TOOLS_DIR)/mio0
  398. N64CKSUM = $(TOOLS_DIR)/n64cksum
  399. N64GRAPHICS = $(TOOLS_DIR)/n64graphics
  400. N64GRAPHICS_CI = $(TOOLS_DIR)/n64graphics_ci
  401. TEXTCONV = $(TOOLS_DIR)/textconv
  402. IPLFONTUTIL = $(TOOLS_DIR)/iplfontutil
  403. AIFF_EXTRACT_CODEBOOK = $(TOOLS_DIR)/aiff_extract_codebook
  404. VADPCM_ENC = $(TOOLS_DIR)/vadpcm_enc
  405. EXTRACT_DATA_FOR_MIO = $(TOOLS_DIR)/extract_data_for_mio
  406. SKYCONV = $(TOOLS_DIR)/skyconv
  407. EMULATOR = mupen64plus
  408. EMU_FLAGS = --noosd
  409. LOADER = loader64
  410. LOADER_FLAGS = -vwf
  411. SHA1SUM = sha1sum
  412. ###################### Dependency Check #####################
  413. # Stubbed
  414. ######################## Targets #############################
  415. all: $(EXE)
  416. clean:
  417. $(RM) -r $(BUILD_DIR_BASE)
  418. cleantools:
  419. $(MAKE) -s -C tools clean
  420. distclean:
  421. $(RM) -r $(BUILD_DIR_BASE)
  422. ./extract_assets.py --clean
  423. test: $(ROM)
  424. $(EMULATOR) $(EMU_FLAGS) $<
  425. load: $(ROM)
  426. $(LOADER) $(LOADER_FLAGS) $<
  427. libultra: $(BUILD_DIR)/libultra.a
  428. asm/boot.s: $(BUILD_DIR)/lib/bin/ipl3_font.bin
  429. $(BUILD_DIR)/lib/bin/ipl3_font.bin: lib/ipl3_font.png
  430. $(IPLFONTUTIL) e $< $@
  431. #Required so the compiler doesn't complain about this not existing.
  432. $(BUILD_DIR)/src/game/camera.o: $(BUILD_DIR)/include/text_strings.h
  433. $(BUILD_DIR)/include/text_strings.h: include/text_strings.h.in
  434. $(TEXTCONV) charmap.txt $< $@
  435. $(BUILD_DIR)/include/text_menu_strings.h: include/text_menu_strings.h.in
  436. $(TEXTCONV) charmap_menu.txt $< $@
  437. ifeq ($(VERSION),eu)
  438. TEXT_DIRS := text/de text/us text/fr
  439. # EU encoded text inserted into individual segment 0x19 files,
  440. # and course data also duplicated in leveldata.c
  441. $(BUILD_DIR)/bin/eu/translation_en.o: $(BUILD_DIR)/text/us/define_text.inc.c
  442. $(BUILD_DIR)/bin/eu/translation_de.o: $(BUILD_DIR)/text/de/define_text.inc.c
  443. $(BUILD_DIR)/bin/eu/translation_fr.o: $(BUILD_DIR)/text/fr/define_text.inc.c
  444. $(BUILD_DIR)/levels/menu/leveldata.o: $(BUILD_DIR)/text/us/define_courses.inc.c
  445. $(BUILD_DIR)/levels/menu/leveldata.o: $(BUILD_DIR)/text/de/define_courses.inc.c
  446. $(BUILD_DIR)/levels/menu/leveldata.o: $(BUILD_DIR)/text/fr/define_courses.inc.c
  447. else
  448. ifeq ($(VERSION),sh)
  449. TEXT_DIRS := text/jp
  450. $(BUILD_DIR)/bin/segment2.o: $(BUILD_DIR)/text/jp/define_text.inc.c
  451. else
  452. TEXT_DIRS := text/$(VERSION)
  453. # non-EU encoded text inserted into segment 0x02
  454. $(BUILD_DIR)/bin/segment2.o: $(BUILD_DIR)/text/$(VERSION)/define_text.inc.c
  455. endif
  456. endif
  457. $(BUILD_DIR)/text/%/define_courses.inc.c: text/define_courses.inc.c text/%/courses.h
  458. $(CPP) $(VERSION_CFLAGS) $< -o $@ -I text/$*/
  459. $(TEXTCONV) charmap.txt $@ $@
  460. $(BUILD_DIR)/text/%/define_text.inc.c: text/define_text.inc.c text/%/courses.h text/%/dialogs.h
  461. $(CPP) $(VERSION_CFLAGS) $< -o $@ -I text/$*/
  462. $(TEXTCONV) charmap.txt $@ $@
  463. ALL_DIRS := $(BUILD_DIR) $(addprefix $(BUILD_DIR)/,$(SRC_DIRS) $(ASM_DIRS) $(GODDARD_SRC_DIRS) $(ULTRA_SRC_DIRS) $(ULTRA_ASM_DIRS) $(ULTRA_BIN_DIRS) $(BIN_DIRS) $(TEXTURE_DIRS) $(TEXT_DIRS) $(SOUND_SAMPLE_DIRS) $(addprefix levels/,$(LEVEL_DIRS)) include) $(MIO0_DIR) $(addprefix $(MIO0_DIR)/,$(VERSION)) $(SOUND_BIN_DIR) $(SOUND_BIN_DIR)/sequences/$(VERSION)
  464. # Make sure build directory exists before compiling anything
  465. DUMMY != mkdir -p $(ALL_DIRS)
  466. $(BUILD_DIR)/include/text_strings.h: $(BUILD_DIR)/include/text_menu_strings.h
  467. ifeq ($(VERSION),eu)
  468. $(BUILD_DIR)/src/menu/file_select.o: $(BUILD_DIR)/include/text_strings.h $(BUILD_DIR)/bin/eu/translation_en.o $(BUILD_DIR)/bin/eu/translation_de.o $(BUILD_DIR)/bin/eu/translation_fr.o
  469. $(BUILD_DIR)/src/menu/star_select.o: $(BUILD_DIR)/include/text_strings.h $(BUILD_DIR)/bin/eu/translation_en.o $(BUILD_DIR)/bin/eu/translation_de.o $(BUILD_DIR)/bin/eu/translation_fr.o
  470. $(BUILD_DIR)/src/game/ingame_menu.o: $(BUILD_DIR)/include/text_strings.h $(BUILD_DIR)/bin/eu/translation_en.o $(BUILD_DIR)/bin/eu/translation_de.o $(BUILD_DIR)/bin/eu/translation_fr.o
  471. O_FILES += $(BUILD_DIR)/bin/eu/translation_en.o $(BUILD_DIR)/bin/eu/translation_de.o $(BUILD_DIR)/bin/eu/translation_fr.o
  472. else
  473. $(BUILD_DIR)/src/menu/file_select.o: $(BUILD_DIR)/include/text_strings.h
  474. $(BUILD_DIR)/src/menu/star_select.o: $(BUILD_DIR)/include/text_strings.h
  475. $(BUILD_DIR)/src/game/ingame_menu.o: $(BUILD_DIR)/include/text_strings.h
  476. endif
  477. ################################################################
  478. # TEXTURE GENERATION #
  479. ################################################################
  480. # RGBA32, RGBA16, IA16, IA8, IA4, IA1, I8, I4
  481. $(BUILD_DIR)/%: %.png
  482. $(N64GRAPHICS) -i $@ -g $< -f $(lastword $(subst ., ,$@))
  483. $(BUILD_DIR)/%.inc.c: $(BUILD_DIR)/% %.png
  484. hexdump -v -e '1/1 "0x%X,"' $< > $@
  485. echo >> $@
  486. # Color Index CI8
  487. $(BUILD_DIR)/%.ci8: %.ci8.png
  488. $(N64GRAPHICS_CI) -i $@ -g $< -f ci8
  489. # Color Index CI4
  490. $(BUILD_DIR)/%.ci4: %.ci4.png
  491. $(N64GRAPHICS_CI) -i $@ -g $< -f ci4
  492. ################################################################
  493. # compressed segment generation
  494. # PC Area
  495. $(BUILD_DIR)/%.table: %.aiff
  496. $(AIFF_EXTRACT_CODEBOOK) $< >$@
  497. $(BUILD_DIR)/%.aifc: $(BUILD_DIR)/%.table %.aiff
  498. $(VADPCM_ENC) -c $^ $@
  499. $(ENDIAN_BITWIDTH): tools/determine-endian-bitwidth.c
  500. $(CC) -c $(CFLAGS) -o $@.dummy2 $< 2>$@.dummy1; true
  501. grep -o 'msgbegin --endian .* --bitwidth .* msgend' $@.dummy1 > $@.dummy2
  502. head -n1 <$@.dummy2 | cut -d' ' -f2-5 > $@
  503. @rm $@.dummy1
  504. @rm $@.dummy2
  505. $(SOUND_BIN_DIR)/sound_data.ctl: sound/sound_banks/ $(SOUND_BANK_FILES) $(SOUND_SAMPLE_AIFCS) $(ENDIAN_BITWIDTH)
  506. $(PYTHON) tools/assemble_sound.py $(BUILD_DIR)/sound/samples/ sound/sound_banks/ $(SOUND_BIN_DIR)/sound_data.ctl $(SOUND_BIN_DIR)/sound_data.tbl $(VERSION_CFLAGS) $$(cat $(ENDIAN_BITWIDTH))
  507. $(SOUND_BIN_DIR)/sound_data.tbl: $(SOUND_BIN_DIR)/sound_data.ctl
  508. @true
  509. ifeq ($(VERSION),sh)
  510. $(SOUND_BIN_DIR)/sequences.bin: $(SOUND_BANK_FILES) sound/sequences.json sound/sequences/ sound/sequences/jp/ $(SOUND_SEQUENCE_FILES) $(ENDIAN_BITWIDTH)
  511. $(PYTHON) tools/assemble_sound.py --sequences $@ $(SOUND_BIN_DIR)/bank_sets sound/sound_banks/ sound/sequences.json $(SOUND_SEQUENCE_FILES) $(VERSION_CFLAGS) $$(cat $(ENDIAN_BITWIDTH))
  512. else
  513. $(SOUND_BIN_DIR)/sequences.bin: $(SOUND_BANK_FILES) sound/sequences.json sound/sequences/ sound/sequences/$(VERSION)/ $(SOUND_SEQUENCE_FILES) $(ENDIAN_BITWIDTH)
  514. $(PYTHON) tools/assemble_sound.py --sequences $@ $(SOUND_BIN_DIR)/bank_sets sound/sound_banks/ sound/sequences.json $(SOUND_SEQUENCE_FILES) $(VERSION_CFLAGS) $$(cat $(ENDIAN_BITWIDTH))
  515. endif
  516. $(SOUND_BIN_DIR)/bank_sets: $(SOUND_BIN_DIR)/sequences.bin
  517. @true
  518. $(SOUND_BIN_DIR)/%.m64: $(SOUND_BIN_DIR)/%.o
  519. $(OBJCOPY) -j .rodata $< -O binary $@
  520. $(SOUND_BIN_DIR)/%.o: $(SOUND_BIN_DIR)/%.s
  521. $(AS) $(ASFLAGS) -o $@ $<
  522. $(SOUND_BIN_DIR)/sound_data.ctl.c: $(SOUND_BIN_DIR)/sound_data.ctl
  523. echo "unsigned char gSoundDataADSR[] = {" > $@
  524. hexdump -v -e '1/1 "0x%X,"' $< >> $@
  525. echo "};" >> $@
  526. $(SOUND_BIN_DIR)/sound_data.tbl.c: $(SOUND_BIN_DIR)/sound_data.tbl
  527. echo "unsigned char gSoundDataRaw[] = {" > $@
  528. hexdump -v -e '1/1 "0x%X,"' $< >> $@
  529. echo "};" >> $@
  530. $(SOUND_BIN_DIR)/sequences.bin.c: $(SOUND_BIN_DIR)/sequences.bin
  531. echo "unsigned char gMusicData[] = {" > $@
  532. hexdump -v -e '1/1 "0x%X,"' $< >> $@
  533. echo "};" >> $@
  534. $(SOUND_BIN_DIR)/bank_sets.c: $(SOUND_BIN_DIR)/bank_sets
  535. echo "unsigned char gBankSetsData[0x100] = {" > $@
  536. hexdump -v -e '1/1 "0x%X,"' $< >> $@
  537. echo "};" >> $@
  538. $(BUILD_DIR)/levels/scripts.o: $(BUILD_DIR)/include/level_headers.h
  539. $(BUILD_DIR)/include/level_headers.h: levels/level_headers.h.in
  540. $(CPP) -I . levels/level_headers.h.in | $(PYTHON) tools/output_level_headers.py > $(BUILD_DIR)/include/level_headers.h
  541. $(BUILD_DIR)/assets/mario_anim_data.c: $(wildcard assets/anims/*.inc.c)
  542. $(PYTHON) tools/mario_anims_converter.py > $@
  543. $(BUILD_DIR)/assets/demo_data.c: assets/demo_data.json $(wildcard assets/demos/*.bin)
  544. $(PYTHON) tools/demo_data_converter.py assets/demo_data.json $(VERSION_CFLAGS) > $@
  545. ifeq ($(COMPILER),ido)
  546. # Source code
  547. $(BUILD_DIR)/levels/%/leveldata.o: OPT_FLAGS := -g
  548. $(BUILD_DIR)/actors/%.o: OPT_FLAGS := -g
  549. $(BUILD_DIR)/bin/%.o: OPT_FLAGS := -g
  550. $(BUILD_DIR)/src/goddard/%.o: OPT_FLAGS := -g
  551. $(BUILD_DIR)/src/goddard/%.o: MIPSISET := -mips1
  552. $(BUILD_DIR)/src/audio/%.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0
  553. $(BUILD_DIR)/src/audio/load.o: OPT_FLAGS := -O2 -framepointer -Wo,-loopunroll,0
  554. $(BUILD_DIR)/lib/src/%.o: OPT_FLAGS :=
  555. $(BUILD_DIR)/lib/src/math/ll%.o: MIPSISET := -mips3 -32
  556. $(BUILD_DIR)/lib/src/math/%.o: OPT_FLAGS := -O2
  557. $(BUILD_DIR)/lib/src/math/ll%.o: OPT_FLAGS :=
  558. $(BUILD_DIR)/lib/src/ldiv.o: OPT_FLAGS := -O2
  559. $(BUILD_DIR)/lib/src/string.o: OPT_FLAGS := -O2
  560. $(BUILD_DIR)/lib/src/gu%.o: OPT_FLAGS := -O3
  561. $(BUILD_DIR)/lib/src/al%.o: OPT_FLAGS := -O3
  562. ifeq ($(VERSION),eu)
  563. $(BUILD_DIR)/lib/src/_Litob.o: OPT_FLAGS := -O3
  564. $(BUILD_DIR)/lib/src/_Ldtob.o: OPT_FLAGS := -O3
  565. $(BUILD_DIR)/lib/src/_Printf.o: OPT_FLAGS := -O3
  566. $(BUILD_DIR)/lib/src/sprintf.o: OPT_FLAGS := -O3
  567. # enable loop unrolling except for external.c (external.c might also have used
  568. # unrolling, but it makes one loop harder to match)
  569. $(BUILD_DIR)/src/audio/%.o: OPT_FLAGS := -O2
  570. $(BUILD_DIR)/src/audio/load.o: OPT_FLAGS := -O2
  571. $(BUILD_DIR)/src/audio/external.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0
  572. else
  573. # The source-to-source optimizer copt is enabled for audio. This makes it use
  574. # acpp, which needs -Wp,-+ to handle C++-style comments.
  575. $(BUILD_DIR)/src/audio/effects.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0 -sopt,-inline=sequence_channel_process_sound,-scalaroptimize=1 -Wp,-+
  576. $(BUILD_DIR)/src/audio/synthesis.o: OPT_FLAGS := -O2 -sopt,-scalaroptimize=1 -Wp,-+
  577. # Add a target for build/eu/src/audio/*.copt to make it easier to see debug
  578. $(BUILD_DIR)/src/audio/%.acpp: src/audio/%.c
  579. $(QEMU_IRIX) -silent -L $(IRIX_ROOT) $(IRIX_ROOT)/usr/lib/acpp $(TARGET_CFLAGS) $(INCLUDE_CFLAGS) $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -D__sgi -+ $< > $@
  580. $(BUILD_DIR)/src/audio/%.copt: $(BUILD_DIR)/src/audio/%.acpp
  581. $(QEMU_IRIX) -silent -L $(IRIX_ROOT) $(IRIX_ROOT)/usr/lib/copt -signed -I=$< -CMP=$@ -cp=i -scalaroptimize=1
  582. endif
  583. endif
  584. # Rebuild files with 'GLOBAL_ASM' if the NON_MATCHING flag changes.
  585. $(GLOBAL_ASM_O_FILES): $(GLOBAL_ASM_DEP).$(NON_MATCHING)
  586. $(GLOBAL_ASM_DEP).$(NON_MATCHING):
  587. @rm -f $(GLOBAL_ASM_DEP).*
  588. touch $@
  589. $(BUILD_DIR)/%.o: %.cpp
  590. @$(CXX) -fsyntax-only $(CFLAGS) -MMD -MP -MT $@ -MF $(BUILD_DIR)/$*.d $<
  591. $(CXX) -c $(CFLAGS) -o $@ $<
  592. $(BUILD_DIR)/%.o: %.c
  593. @$(CC_CHECK) -MMD -MP -MT $@ -MF $(BUILD_DIR)/$*.d $<
  594. $(CC) -c $(CFLAGS) -o $@ $<
  595. $(BUILD_DIR)/%.o: $(BUILD_DIR)/%.c
  596. @$(CC_CHECK) -MMD -MP -MT $@ -MF $(BUILD_DIR)/$*.d $<
  597. $(CC) -c $(CFLAGS) -o $@ $<
  598. $(BUILD_DIR)/%.o: %.s
  599. $(AS) $(ASFLAGS) -MD $(BUILD_DIR)/$*.d -o $@ $<
  600. $(EXE): $(O_FILES) $(MIO0_FILES:.mio0=.o) $(SOUND_OBJ_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES)
  601. $(LD) -L $(BUILD_DIR) -o $@ $(O_FILES) $(SOUND_OBJ_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(LDFLAGS)
  602. .PHONY: all clean distclean default diff test load libultra
  603. .PRECIOUS: $(BUILD_DIR)/bin/%.elf $(SOUND_BIN_DIR)/%.ctl $(SOUND_BIN_DIR)/%.tbl $(SOUND_SAMPLE_TABLES) $(SOUND_BIN_DIR)/%.s $(BUILD_DIR)/%
  604. .DELETE_ON_ERROR:
  605. # Remove built-in rules, to improve performance
  606. MAKEFLAGS += --no-builtin-rules
  607. -include $(DEP_FILES)
  608. print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true