2019-08-25 00:46:40 -04:00
# Makefile to rebuild SM64 split image
2020-12-03 14:26:38 -05:00
i n c l u d e u t i l . m k
2019-08-25 00:46:40 -04:00
2020-12-03 14:26:38 -05:00
# Default target
2019-08-25 00:46:40 -04:00
default : all
2022-09-21 20:18:37 -05:00
TARGET_STRING := sm64
2020-12-03 14:26:38 -05:00
# Preprocessor definitions
DEFINES :=
2019-08-25 00:46:40 -04:00
2021-01-03 13:09:20 -05:00
SRC_DIRS :=
2021-04-16 20:02:56 -04:00
USE_DEBUG := 0
2021-01-03 13:09:20 -05:00
2020-12-03 14:26:38 -05:00
#==============================================================================#
# Build Options #
#==============================================================================#
# These options can either be set by building with 'make SETTING=value'.
# 'make clean' may be required first.
2019-12-01 21:52:53 -05:00
# Build for the N64 (turn this off for ports)
TARGET_N64 ?= 1
2020-12-03 14:26:38 -05:00
2021-01-02 22:48:12 -05:00
# CONSOLE - selects the console to target
2021-01-02 22:52:48 -05:00
# bb - Targets the iQue Player (codenamed BB)
# n64 - Targets the N64
2021-01-02 22:48:12 -05:00
CONSOLE ?= n64
2021-01-02 22:52:48 -05:00
$( eval $ ( call validate -option ,CONSOLE ,n 64 bb ) )
2021-01-02 22:48:12 -05:00
i f e q ( $( CONSOLE ) , n 6 4 )
INCLUDE_DIRS += include/n64
LIBS_DIR := lib/n64
2021-01-02 22:52:48 -05:00
e l s e i f e q ( $( CONSOLE ) , b b )
2021-01-02 22:48:12 -05:00
INCLUDE_DIRS += include/ique
LIBS_DIR := lib/ique
DEFINES += BBPLAYER = 1
e n d i f
2020-12-03 14:26:38 -05:00
# COMPILER - selects the C compiler to use
# gcc - uses the GNU C Compiler
2021-08-05 18:11:55 -04:00
# clang - uses clang C/C++ frontend for LLVM
2020-12-09 09:05:40 -05:00
COMPILER ?= gcc
2021-08-05 18:11:55 -04:00
$( eval $ ( call validate -option ,COMPILER ,gcc clang ) )
2020-04-03 14:57:26 -04:00
2019-08-25 00:46:40 -04:00
2021-07-09 19:20:25 -04:00
# LIBGCCDIR - selects the libgcc configuration for checking for dividing by zero
# trap - GCC default behavior, uses teq instructions which some emulators don't like
# divbreak - this is similar to IDO behavior, and is default.
# nocheck - never checks for dividing by 0. Technically fastest, but also UB so not recommended
LIBGCCDIR ?= divbreak
$( eval $ ( call validate -option ,LIBGCCDIR ,trap divbreak nocheck ) )
2021-01-11 00:46:56 -05:00
# SAVETYPE - selects the save type
# eep4k - uses EEPROM 4kbit
# eep16k - uses EEPROM 16kbit (There aren't any differences in syntax, but this is provided just in case)
# sram - uses SRAM 256Kbit
SAVETYPE ?= eep4k
$( eval $ ( call validate -option ,SAVETYPE ,eep 4k eep 16k sram ) )
i f e q ( $( SAVETYPE ) , e e p 4 k )
DEFINES += EEP = 1 EEP4K = 1
e l s e i f e q ( $( SAVETYPE ) , e e p 1 6 k )
DEFINES += EEP = 1 EEP16K = 1
e l s e i f e q ( $( SAVETYPE ) , s r a m )
DEFINES += SRAM = 1
e n d i f
2025-07-02 12:37:50 +08:00
DEFINES += NO_ERRNO_H = 1
2021-01-26 15:56:34 -05:00
2020-12-03 14:26:38 -05:00
# VERSION - selects the version of the game to build
# jp - builds the 1996 Japanese version
# us - builds the 1996 North American version
# eu - builds the 1997 PAL version
# sh - builds the 1997 Japanese Shindou version, with rumble pak support
VERSION ?= us
$( eval $ ( call validate -option ,VERSION ,jp us eu sh ) )
2019-08-25 00:46:40 -04:00
2020-12-03 14:26:38 -05:00
i f e q ( $( VERSION ) , j p )
2021-12-30 10:57:51 -06:00
DEFINES += VERSION_JP = 1
2020-12-03 14:26:38 -05:00
e l s e i f e q ( $( VERSION ) , u s )
2021-12-30 10:57:51 -06:00
DEFINES += VERSION_US = 1
2020-12-03 14:26:38 -05:00
e l s e i f e q ( $( VERSION ) , e u )
2021-12-30 10:57:51 -06:00
DEFINES += VERSION_EU = 1
2020-12-03 14:26:38 -05:00
e l s e i f e q ( $( VERSION ) , s h )
2021-12-30 10:57:51 -06:00
DEFINES += VERSION_SH = 1
2020-03-01 22:42:52 -05:00
e n d i f
2019-08-25 00:46:40 -04:00
2022-07-19 14:04:54 +01:00
# FIXLIGHTS - converts light objects to light color commands for assets, needed for vanilla-style lighting
FIXLIGHTS ?= 1
2021-09-20 17:17:09 -04:00
DEBUG_MAP_STACKTRACE_FLAG := -D DEBUG_MAP_STACKTRACE
2021-12-30 10:57:51 -06:00
TARGET := sm64
2020-06-02 12:44:34 -04:00
2019-08-25 00:46:40 -04:00
2020-12-03 14:26:38 -05:00
# GRUCODE - selects which RSP microcode to use.
# f3dex -
# f3dex2 -
2021-08-22 11:59:13 -04:00
# l3dex2 - F3DEX2 version that only renders in wireframe
2020-12-03 14:26:38 -05:00
# f3dzex - newer, experimental microcode used in Animal Crossing
2020-12-03 20:19:03 -05:00
# super3d - extremely experimental version of Fast3D lacking many features for speed
2021-12-30 10:57:51 -06:00
GRUCODE ?= f3dzex
2021-09-17 17:53:53 -04:00
$( eval $ ( call validate -option ,GRUCODE ,f 3dex f 3dex 2 f 3dex 2pl f 3dzex super 3d l 3dex 2) )
2020-12-03 14:26:38 -05:00
2021-09-17 17:53:53 -04:00
i f e q ( $( GRUCODE ) , f 3 d e x ) # Fast3DEX
2020-12-03 14:26:38 -05:00
DEFINES += F3DEX_GBI = 1 F3DEX_GBI_SHARED = 1
2020-12-03 20:19:03 -05:00
e l s e i f e q ( $( GRUCODE ) , f 3 d e x 2 ) # Fast3DEX2
2020-12-03 14:26:38 -05:00
DEFINES += F3DEX_GBI_2 = 1 F3DEX_GBI_SHARED = 1
2021-08-22 11:59:13 -04:00
e l s e i f e q ( $( GRUCODE ) , l 3 d e x 2 ) # Line3DEX2
DEFINES += L3DEX2_GBI = 1 L3DEX2_ALONE = 1 F3DEX_GBI_2 = 1 F3DEX_GBI_SHARED = 1
2021-05-08 22:40:59 -04:00
e l s e i f e q ( $( GRUCODE ) , f 3 d e x 2 p l ) # Fast3DEX2_PosLight
DEFINES += F3DEX2PL_GBI = 1 F3DEX_GBI_2 = 1 F3DEX_GBI_SHARED = 1
2020-12-03 20:19:03 -05:00
e l s e i f e q ( $( GRUCODE ) , f 3 d z e x ) # Fast3DZEX (2.08J / Animal Forest - Dōbutsu no Mori)
2022-01-14 22:13:40 -05:00
DEFINES += F3DZEX_NON_GBI_2 = 1 F3DEX_GBI_2 = 1 F3DEX_GBI_SHARED = 1
2020-12-03 20:19:03 -05:00
e l s e i f e q ( $( GRUCODE ) , s u p e r 3 d ) # Super3D
$( warning Super3D is experimental. Try at your own risk.)
DEFINES += SUPER3D_GBI = 1 F3D_NEW = 1
2019-08-25 00:46:40 -04:00
e n d i f
2021-06-02 07:20:08 -04:00
# TEXT ENGINES
# s2dex_text_engine - Text Engine by someone2639
TEXT_ENGINE := none
2022-10-01 00:54:07 +02:00
$( eval $ ( call validate -option ,TEXT_ENGINE ,none s 2dex_text_engine ) )
2021-12-30 10:57:51 -06:00
2023-06-17 16:51:03 -04:00
i f e q ( $( TEXT_ENGINE ) , s 2 d e x _ t e x t _ e n g i n e )
DEFINES += S2DEX_GBI_2 = 1 S2DEX_TEXT_ENGINE = 1
SRC_DIRS += src/s2d_engine
e n d i f
# add more text engines here
2021-12-30 10:57:51 -06:00
#==============================================================================#
# Optimization flags #
#==============================================================================#
# Default non-gcc opt flags
2025-11-19 19:14:37 +13:00
DEFAULT_OPT_FLAGS = -Os -ffinite-math-only -fno-signed-zeros -fno-math-errno
2022-12-12 14:40:55 -05:00
# Note: -fno-associative-math is used here to suppress warnings, ideally we would enable this as an optimization but
# this conflicts with -ftrapping-math apparently.
# TODO: Figure out how to allow -fassociative-math to be enabled
SAFETY_OPT_FLAGS = -ftrapping-math -fno-associative-math
2021-12-30 10:57:51 -06:00
# Main opt flags
GCC_MAIN_OPT_FLAGS = \
2022-12-12 14:40:55 -05:00
$( DEFAULT_OPT_FLAGS) $( SAFETY_OPT_FLAGS) \
2021-12-30 10:57:51 -06:00
--param case -values-threshold= 20 \
--param max-completely-peeled-insns= 10 \
--param max-unrolled-insns= 10 \
-finline-limit= 1 \
-freorder-blocks-algorithm= simple \
-ffunction-sections \
-fdata-sections
# Surface Collision
GCC_COLLISION_OPT_FLAGS = \
2022-12-12 14:40:55 -05:00
$( DEFAULT_OPT_FLAGS) $( SAFETY_OPT_FLAGS) \
2021-12-30 10:57:51 -06:00
--param case -values-threshold= 20 \
--param max-completely-peeled-insns= 100 \
--param max-unrolled-insns= 100 \
-finline-limit= 0 \
-fno-inline \
-freorder-blocks-algorithm= simple \
-ffunction-sections \
-fdata-sections \
-falign-functions= 32
# Math Util
GCC_MATH_UTIL_OPT_FLAGS = \
2022-12-12 14:40:55 -05:00
$( DEFAULT_OPT_FLAGS) $( SAFETY_OPT_FLAGS) \
2021-12-30 10:57:51 -06:00
-fno-unroll-loops \
-fno-peel-loops \
--param case -values-threshold= 20 \
-ffunction-sections \
-fdata-sections \
-falign-functions= 32
# - setting any sort of -finline-limit has shown to worsen performance with math_util.c,
# lower values were the worst, the higher you go - the closer performance gets to not setting it at all
# Rendering graph node
GCC_GRAPH_NODE_OPT_FLAGS = \
2022-12-12 14:40:55 -05:00
$( DEFAULT_OPT_FLAGS) $( SAFETY_OPT_FLAGS) \
2021-12-30 10:57:51 -06:00
--param case -values-threshold= 20 \
--param max-completely-peeled-insns= 100 \
--param max-unrolled-insns= 100 \
-finline-limit= 0 \
-freorder-blocks-algorithm= simple \
-ffunction-sections \
-fdata-sections \
-falign-functions= 32
#==============================================================================#
2021-02-01 18:23:36 -05:00
i f e q ( $( COMPILER ) , g c c )
2020-12-03 14:26:38 -05:00
MIPSISET := -mips3
2021-12-30 10:57:51 -06:00
OPT_FLAGS := $( GCC_MAIN_OPT_FLAGS)
COLLISION_OPT_FLAGS = $( GCC_COLLISION_OPT_FLAGS)
MATH_UTIL_OPT_FLAGS = $( GCC_MATH_UTIL_OPT_FLAGS)
GRAPH_NODE_OPT_FLAGS = $( GCC_GRAPH_NODE_OPT_FLAGS)
2021-08-05 18:11:55 -04:00
e l s e i f e q ( $( COMPILER ) , c l a n g )
# clang doesn't support ABI 'o32' for 'mips3'
MIPSISET := -mips2
2021-12-30 10:57:51 -06:00
OPT_FLAGS := $( DEFAULT_OPT_FLAGS)
COLLISION_OPT_FLAGS = $( DEFAULT_OPT_FLAGS)
MATH_UTIL_OPT_FLAGS = $( DEFAULT_OPT_FLAGS)
GRAPH_NODE_OPT_FLAGS = $( DEFAULT_OPT_FLAGS)
2020-12-03 14:26:38 -05:00
e n d i f
2020-12-09 16:38:26 -05:00
# UNF - whether to use UNFLoader flashcart library
# 1 - includes code in ROM
2022-07-19 14:04:54 +01:00
# 0 - does not
2020-12-09 16:38:26 -05:00
UNF ?= 0
$( eval $ ( call validate -option ,UNF ,0 1) )
2022-09-30 17:40:50 -05:00
# if `unf` is a target, make sure that UNF is set
i f n e q ( $( filter unf ,$ ( MAKECMDGOALS ) ) , )
UNF = 1
e n d i f
2020-12-09 16:38:26 -05:00
i f e q ( $( UNF ) , 1 )
DEFINES += UNF = 1
2021-09-28 18:03:24 +01:00
SRC_DIRS += src/usb
2021-04-11 20:49:21 -04:00
e n d i f
# ISVPRINT - whether to fake IS-Viewer presence,
# allowing for usage of CEN64 (and possibly Project64) to print messages to terminal.
# 1 - includes code in ROM
2022-07-19 14:04:54 +01:00
# 0 - does not
2021-04-11 20:49:21 -04:00
ISVPRINT ?= 0
$( eval $ ( call validate -option ,ISVPRINT ,0 1) )
i f e q ( $( ISVPRINT ) , 1 )
DEFINES += ISVPRINT = 1
2021-04-16 20:02:56 -04:00
USE_DEBUG := 1
e n d i f
i f e q ( $( USE_DEBUG ) , 1 )
2021-04-11 20:49:21 -04:00
ULTRALIB := ultra_d
2023-01-26 10:03:07 -05:00
DEFINES += DEBUG = 1 OVERWRITE_OSPRINT = 1
e l s e i f e q ( $( UNF ) , 1 )
ULTRALIB := ultra
DEFINES += _FINALROM = 1 NDEBUG = 1 OVERWRITE_OSPRINT = 1
2021-04-11 20:49:21 -04:00
e l s e
ULTRALIB := ultra_rom
2023-01-26 10:03:07 -05:00
DEFINES += _FINALROM = 1 NDEBUG = 1 OVERWRITE_OSPRINT = 0
2021-01-02 21:19:27 -05:00
e n d i f
# HVQM - whether to use HVQM fmv library
# 1 - includes code in ROM
2022-07-19 14:04:54 +01:00
# 0 - does not
2021-01-02 21:19:27 -05:00
HVQM ?= 0
$( eval $ ( call validate -option ,HVQM ,0 1) )
i f e q ( $( HVQM ) , 1 )
DEFINES += HVQM = 1
2021-03-28 20:54:54 -04:00
SRC_DIRS += src/hvqm
e n d i f
2024-02-02 22:08:34 -05:00
# LIBPL - whether to include libpl library for interfacing with Parallel Launcher
# (library will be pulled into repo after building with this enabled for the first time)
# 1 - includes code in ROM
# 0 - does not
LIBPL ?= 0
LIBPL_DIR := lib/libpl
$( eval $ ( call validate -option ,LIBPL ,0 1) )
i f e q ( $( LIBPL ) , 1 )
DEFINES += LIBPL = 1
SRC_DIRS += $( LIBPL_DIR)
e n d i f
2021-12-30 10:57:51 -06:00
BUILD_DIR_BASE := build
# BUILD_DIR is the location where all build artifacts are placed
BUILD_DIR := $( BUILD_DIR_BASE) /$( VERSION) _$( CONSOLE)
2024-12-29 19:33:28 +08:00
COMPRESS ?= lz4t
$( eval $ ( call validate -option ,COMPRESS ,mio 0 yay 0 lz 4t gzip rnc 1 rnc 2 uncomp ) )
2021-12-30 10:57:51 -06:00
i f e q ( $( COMPRESS ) , g z i p )
DEFINES += GZIP = 1
e l s e i f e q ( $( COMPRESS ) , r n c 1 )
DEFINES += RNC1 = 1
e l s e i f e q ( $( COMPRESS ) , r n c 2 )
DEFINES += RNC2 = 1
e l s e i f e q ( $( COMPRESS ) , y a y 0 )
DEFINES += YAY0 = 1
e l s e i f e q ( $( COMPRESS ) , m i o 0 )
DEFINES += MIO0 = 1
2024-12-29 19:33:28 +08:00
e l s e i f e q ( $( COMPRESS ) , l z 4 t )
DEFINES += LZ4T = 1
2021-12-30 10:57:51 -06:00
e l s e i f e q ( $( COMPRESS ) , u n c o m p )
DEFINES += UNCOMPRESSED = 1
e n d i f
2020-12-03 14:26:38 -05:00
# Whether to hide commands or not
VERBOSE ?= 0
i f e q ( $( VERBOSE ) , 0 )
V := @
e n d i f
# Whether to colorize build messages
COLOR ?= 1
#==============================================================================#
# Universal Dependencies #
#==============================================================================#
TOOLS_DIR := tools
2019-08-25 00:46:40 -04:00
2020-12-03 20:19:03 -05:00
2019-08-25 00:46:40 -04:00
# (This is a bit hacky, but a lot of rules implicitly depend
# on tools and assets, and we use directory globs further down
# in the makefile that we want should cover assets.)
2020-12-03 14:26:38 -05:00
PYTHON := python3
2019-08-25 00:46:40 -04:00
2020-12-03 14:26:38 -05:00
i f e q ( $( filter clean distclean print -%,$ ( MAKECMDGOALS ) ) , )
2019-08-25 00:46:40 -04:00
2025-11-02 19:39:34 -05:00
# Extract assets if necessary
2020-12-03 14:26:38 -05:00
NOEXTRACT ?= 0
ifeq ( $( NOEXTRACT) ,0)
2025-11-02 19:39:34 -05:00
DUMMY != $( PYTHON) extract_assets.py >& 2 || echo FAIL
2020-12-03 14:26:38 -05:00
ifeq ( $( DUMMY) ,FAIL)
2025-11-02 19:39:34 -05:00
$( error Failed to extract assets from found baseroms)
2020-12-03 14:26:38 -05:00
endif
endif
# Make tools if out of date
$( info Building tools...)
2026-01-17 17:51:06 +11:00
DUMMY != " $( MAKE) " -s -C $( TOOLS_DIR) >& 2 || echo FAIL
2020-12-03 14:26:38 -05:00
ifeq ( $( DUMMY) ,FAIL)
$( error Failed to build tools)
endif
2024-02-02 22:08:34 -05:00
# Clone any needed submodules
ifeq ( $( LIBPL) ,1)
2024-02-27 10:29:47 -05:00
ifeq ( $( wildcard $( LIBPL_DIR) /*.h) ,)
2024-02-02 22:08:34 -05:00
$( info Cloning libpl submodule...)
DUMMY != git submodule update --init $( LIBPL_DIR) > /dev/null || echo FAIL
ifeq ( $( DUMMY) ,FAIL)
$( error Failed to clone libpl submodule)
endif
endif
endif
2020-12-03 14:26:38 -05:00
$( info Building ROM...)
2019-08-25 00:46:40 -04:00
e n d i f
2020-12-03 14:26:38 -05:00
#==============================================================================#
# Target Executable and Sources #
#==============================================================================#
2019-08-25 00:46:40 -04:00
BUILD_DIR_BASE := build
2020-12-03 14:26:38 -05:00
# BUILD_DIR is the location where all build artifacts are placed
2021-12-30 10:57:51 -06:00
BUILD_DIR := $( BUILD_DIR_BASE) /$( VERSION) _$( CONSOLE)
2020-12-08 19:28:12 -05:00
ROM := $( BUILD_DIR) /$( TARGET_STRING) .z64
ELF := $( BUILD_DIR) /$( TARGET_STRING) .elf
2020-12-03 14:26:38 -05:00
LD_SCRIPT := sm64.ld
2020-12-03 20:19:03 -05:00
YAY0_DIR := $( BUILD_DIR) /bin
2020-12-03 14:26:38 -05:00
SOUND_BIN_DIR := $( BUILD_DIR) /sound
TEXTURE_DIR := textures
ACTOR_DIR := actors
LEVEL_DIRS := $( patsubst levels/%,%,$( dir $( wildcard levels/*/header.h) ) )
2019-08-25 00:46:40 -04:00
# Directories containing source files
2025-07-02 12:37:50 +08:00
SRC_DIRS += src src/boot src/boot/deflate src/game src/engine src/audio src/menu src/buffers lib/librtc actors levels bin data assets asm lib sound
2021-01-25 22:55:36 -05:00
LIBZ_SRC_DIRS := src/libz
2021-03-28 20:54:54 -04:00
GODDARD_SRC_DIRS := src/goddard src/goddard/dynlists
2019-08-25 00:46:40 -04:00
BIN_DIRS := bin bin/$( VERSION)
# File dependencies and variables for specific files
i n c l u d e M a k e f i l e . s p l i t
# Source code files
2020-12-03 14:26:38 -05:00
LEVEL_C_FILES := $( wildcard levels/*/leveldata.c) $( wildcard levels/*/script.c) $( wildcard levels/*/geo.c)
C_FILES := $( foreach dir,$( SRC_DIRS) ,$( wildcard $( dir) /*.c) ) $( LEVEL_C_FILES)
2023-09-25 14:41:51 -05:00
CPP_FILES := $( foreach dir,$( SRC_DIRS) ,$( wildcard $( dir) /*.cpp) )
2021-03-28 20:54:54 -04:00
GODDARD_C_FILES := $( foreach dir,$( GODDARD_SRC_DIRS) ,$( wildcard $( dir) /*.c) )
2020-12-03 14:26:38 -05:00
S_FILES := $( foreach dir,$( SRC_DIRS) ,$( wildcard $( dir) /*.s) )
2019-11-03 14:36:27 -05:00
GENERATED_C_FILES := $( BUILD_DIR) /assets/mario_anim_data.c $( BUILD_DIR) /assets/demo_data.c
2019-08-25 00:46:40 -04:00
2024-04-21 17:13:47 -04:00
# Ignore all .inc.c files
C_FILES := $( filter-out %.inc.c,$( C_FILES) )
2020-12-03 14:26:38 -05:00
# Sound files
SOUND_BANK_FILES := $( wildcard sound/sound_banks/*.json)
SOUND_SAMPLE_DIRS := $( wildcard sound/samples/*)
SOUND_SAMPLE_AIFFS := $( foreach dir,$( SOUND_SAMPLE_DIRS) ,$( wildcard $( dir) /*.aiff) )
2019-08-25 00:46:40 -04:00
SOUND_SAMPLE_TABLES := $( foreach file,$( SOUND_SAMPLE_AIFFS) ,$( BUILD_DIR) /$( file:.aiff= .table) )
2020-12-03 14:26:38 -05:00
SOUND_SAMPLE_AIFCS := $( foreach file,$( SOUND_SAMPLE_AIFFS) ,$( BUILD_DIR) /$( file:.aiff= .aifc) )
SOUND_SEQUENCE_DIRS := sound/sequences sound/sequences/$( VERSION)
# all .m64 files in SOUND_SEQUENCE_DIRS, plus all .m64 files that are generated from .s files in SOUND_SEQUENCE_DIRS
SOUND_SEQUENCE_FILES := \
$( foreach dir,$( SOUND_SEQUENCE_DIRS) ,\
$( wildcard $( dir) /*.m64) \
$( foreach file,$( wildcard $( dir) /*.s) ,$( BUILD_DIR) /$( file:.s= .m64) ) \
)
2019-08-25 00:46:40 -04:00
# Object files
O_FILES := $( foreach file,$( C_FILES) ,$( BUILD_DIR) /$( file:.c= .o) ) \
2023-09-25 14:41:51 -05:00
$( foreach file,$( CPP_FILES) ,$( BUILD_DIR) /$( file:.cpp= .o) ) \
2019-08-25 00:46:40 -04:00
$( foreach file,$( S_FILES) ,$( BUILD_DIR) /$( file:.s= .o) ) \
2020-12-08 21:41:03 -05:00
$( foreach file,$( GENERATED_C_FILES) ,$( file:.c= .o) ) \
lib/PR/hvqm/hvqm2sp1.o lib/PR/hvqm/hvqm2sp2.o
2019-08-25 00:46:40 -04:00
2021-03-28 20:54:54 -04:00
GODDARD_O_FILES := $( foreach file,$( GODDARD_C_FILES) ,$( BUILD_DIR) /$( file:.c= .o) )
2021-01-25 22:55:36 -05:00
2019-08-25 00:46:40 -04:00
# Automatic dependency files
2025-07-02 12:37:50 +08:00
DEP_FILES := $( O_FILES:.o= .d) $( GODDARD_O_FILES:.o= .d) $( BUILD_DIR) /$( LD_SCRIPT) .d
2019-08-25 00:46:40 -04:00
2020-12-03 14:26:38 -05:00
#==============================================================================#
# Compiler Options #
#==============================================================================#
2019-08-25 00:46:40 -04:00
2025-11-01 01:26:49 -07:00
CROSS := $( call find-mips-toolchain)
2019-10-05 15:08:05 -04:00
2025-07-02 12:37:50 +08:00
LIBRARIES := nustd hvqm2 goddard
2022-10-01 00:54:07 +02:00
LINK_LIBRARIES = $( foreach i,$( LIBRARIES) ,-l$( i) )
2020-12-03 20:19:03 -05:00
export LD_LIBRARY_PATH = ./tools
2019-08-25 00:46:40 -04:00
AS := $( CROSS) as
2020-12-03 14:26:38 -05:00
i f e q ( $( COMPILER ) , g c c )
CC := $( CROSS) gcc
2023-09-25 14:41:51 -05:00
CXX := $( CROSS) g++
2021-09-28 17:39:49 +01:00
$( BUILD_DIR) /actors/%.o: OPT_FLAGS := -Ofast -mlong-calls
$( BUILD_DIR) /levels/%.o: OPT_FLAGS := -Ofast -mlong-calls
2021-08-05 18:11:55 -04:00
e l s e i f e q ( $( COMPILER ) , c l a n g )
CC := clang
2023-09-25 14:41:51 -05:00
CXX := clang++
2020-12-03 14:26:38 -05:00
e n d i f
2025-01-19 11:17:45 +00:00
ARCH := $( shell uname -p)
# Check processor architecture. ARM users need a different binutils package.
i f e q ( $( ARCH ) , a r m )
LD := tools/mips64-elf-ld-arm
2020-12-03 14:26:38 -05:00
e l s e
2025-01-19 11:17:45 +00:00
ifneq ( $( call find-command,mips-n64-ld) ,)
LD := mips-n64-ld
else
LD := tools/mips64-elf-ld
endif
2021-01-23 13:28:35 -05:00
e n d i f
2019-08-25 00:46:40 -04:00
AR := $( CROSS) ar
OBJDUMP := $( CROSS) objdump
OBJCOPY := $( CROSS) objcopy
2020-04-03 14:57:26 -04:00
2023-09-22 13:06:39 -04:00
i f e q ( $( LD ) , t o o l s / m i p s 6 4 - e l f - l d )
ifeq ( $( shell ls -la tools/mips64-elf-ld | awk '{print $1}' | grep x) ,)
$( warning [ ERROR] : A required file in this repository is no longer executable.)
$( error * Please run: 'chmod +x tools/mips64-elf-ld' , then run ` make` again)
endif
e n d i f
2019-12-01 21:52:53 -05:00
i f e q ( $( TARGET_N 64) , 1 )
2020-12-03 14:26:38 -05:00
TARGET_CFLAGS := -nostdinc -DTARGET_N64 -D_LANGUAGE_C
2019-12-01 21:52:53 -05:00
CC_CFLAGS := -fno-builtin
e n d i f
2021-01-02 22:48:12 -05:00
INCLUDE_DIRS += include $( BUILD_DIR) $( BUILD_DIR) /include src . include/hvqm
2020-12-03 14:26:38 -05:00
i f e q ( $( TARGET_N 64) , 1 )
INCLUDE_DIRS += include/libc
e n d i f
C_DEFINES := $( foreach d,$( DEFINES) ,-D$( d) )
DEF_INC_CFLAGS := $( foreach i,$( INCLUDE_DIRS) ,-I$( i) ) $( C_DEFINES)
2019-11-03 14:36:27 -05:00
2025-01-19 11:17:45 +00:00
# Prefer gcc's cpp if installed on the system
i f n e q ( , $( call find -command ,clang ) )
CPP := clang
CPPFLAGS := -E -P -x c -Wno-trigraphs $( DEF_INC_CFLAGS)
e l s e i f n e q ( , $( call find -command ,cpp -10) )
CPP := cpp-10
CPPFLAGS := -P -Wno-trigraphs $( DEF_INC_CFLAGS)
e l s e
CPP := cpp
CPPFLAGS := -P -Wno-trigraphs $( DEF_INC_CFLAGS)
e n d i f
2020-12-03 14:26:38 -05:00
# C compiler options
2025-11-05 02:12:44 -05:00
CFLAGS = -std= gnu17 -G 0 $( OPT_FLAGS) $( TARGET_CFLAGS) $( MIPSISET) $( DEF_INC_CFLAGS)
2020-04-03 14:57:26 -04:00
i f e q ( $( COMPILER ) , g c c )
2021-12-30 10:57:51 -06:00
CFLAGS += -mno-shared -march= vr4300 -mfix4300 -mabi= 32 -mhard-float -mdivide-breaks -fno-stack-protector -fno-common -fno-zero-initialized-in-bss -fno-PIC -mno-abicalls -fno-strict-aliasing -fno-inline-functions -ffreestanding -fwrapv -Wall -Wextra
CFLAGS += -Wno-missing-braces
2021-08-05 18:11:55 -04:00
e l s e i f e q ( $( COMPILER ) , c l a n g )
2021-12-30 10:57:51 -06:00
CFLAGS += -mfpxx -target mips -mabi= 32 -G 0 -mhard-float -fomit-frame-pointer -fno-stack-protector -fno-common -I include -I src/ -I $( BUILD_DIR) /include -fno-PIC -mno-abicalls -fno-strict-aliasing -fno-inline-functions -ffreestanding -fwrapv -Wall -Wextra
CFLAGS += -Wno-missing-braces
2020-12-03 14:26:38 -05:00
e l s e
CFLAGS += -non_shared -Wab,-r4300_mul -Xcpluscomm -Xfullwarn -signed -32
2020-04-03 14:57:26 -04:00
e n d i f
2021-08-05 18:11:55 -04:00
ASMFLAGS = -G 0 $( OPT_FLAGS) $( TARGET_CFLAGS) -mips3 $( DEF_INC_CFLAGS) -mno-shared -march= vr4300 -mfix4300 -mabi= 32 -mhard-float -mdivide-breaks -fno-stack-protector -fno-common -fno-zero-initialized-in-bss -fno-PIC -mno-abicalls -fno-strict-aliasing -fno-inline-functions -ffreestanding -fwrapv -Wall -Wextra
2020-04-03 14:57:26 -04:00
2020-12-03 14:26:38 -05:00
ASFLAGS := -march= vr4300 -mabi= 32 $( foreach i,$( INCLUDE_DIRS) ,-I$( i) ) $( foreach d,$( DEFINES) ,--defsym $( d) )
RSPASMFLAGS := $( foreach d,$( DEFINES) ,-definelabel $( subst = , ,$( d) ) )
# C preprocessor flags
#==============================================================================#
# Miscellaneous Tools #
#==============================================================================#
2019-08-25 00:46:40 -04:00
# N64 tools
2020-12-03 20:19:03 -05:00
YAY0TOOL := $( TOOLS_DIR) /slienc
2021-03-23 17:41:15 -04:00
MIO0TOOL := $( TOOLS_DIR) /mio0
2024-12-29 19:33:28 +08:00
LZ4TPACK := $( TOOLS_DIR) /lz4tpack
2025-07-02 12:37:50 +08:00
DEFLATEPACK := $( TOOLS_DIR) /deflatepack
2021-01-25 22:21:15 -05:00
RNCPACK := $( TOOLS_DIR) /rncpack
2021-01-04 00:44:54 -05:00
FILESIZER := $( TOOLS_DIR) /filesizer
2020-12-03 14:26:38 -05:00
N64CKSUM := $( TOOLS_DIR) /n64cksum
N64GRAPHICS := $( TOOLS_DIR) /n64graphics
N64GRAPHICS_CI := $( TOOLS_DIR) /n64graphics_ci
2021-09-12 20:14:45 -04:00
BINPNG := $( TOOLS_DIR) /BinPNG.py
2020-12-03 14:26:38 -05:00
TEXTCONV := $( TOOLS_DIR) /textconv
AIFF_EXTRACT_CODEBOOK := $( TOOLS_DIR) /aiff_extract_codebook
VADPCM_ENC := $( TOOLS_DIR) /vadpcm_enc
EXTRACT_DATA_FOR_MIO := $( TOOLS_DIR) /extract_data_for_mio
SKYCONV := $( TOOLS_DIR) /skyconv
2022-07-19 14:04:54 +01:00
FIXLIGHTS_PY := $( TOOLS_DIR) /fixlights.py
2023-06-05 17:02:58 -05:00
FLIPS := $( TOOLS_DIR) /flips
2020-12-03 14:26:38 -05:00
# Use the system installed armips if available. Otherwise use the one provided with this repository.
i f n e q ( , $( call find -command ,armips ) )
RSPASM := armips
e l s e
RSPASM := $( TOOLS_DIR) /armips
e n d i f
2024-04-29 19:42:13 -04:00
i f n e q ( , $( call find -command ,wslview ) )
EMULATOR = "/mnt/c/Program Files (x86)/parallel-launcher/parallel-launcher.exe"
e l s e
EMULATOR = parallel-launcher
e n d i f
2021-09-23 13:37:03 -07:00
EMU_FLAGS =
2022-09-30 17:40:50 -05:00
2024-08-03 19:09:22 -04:00
# Adding a txt file to this location will then reference a UNFLoader path specified in the file, instead of locally.
# This is expecially important for WSL users because UNFLoader.exe is incredibly slow when run within WSL's filesystem, so this can be used to point to the C drive.
# The file should only contain the directory path that contains UNFLoader[.exe] (do not specify the filename).
LOADER_DIR_FILE_SPECIFICATION_PATH = ~/.local/share/HackerSM64/UNFLoader-dir.txt
LOADER_DIR = ./$( TOOLS_DIR)
i f n e q ( , $( wildcard $ ( LOADER_DIR_FILE_SPECIFICATION_PATH ) ) )
LOADER_DIR = $( shell cat $( LOADER_DIR_FILE_SPECIFICATION_PATH) )
e n d i f
2022-09-30 17:40:50 -05:00
i f n e q ( , $( call find -command ,wslview ) )
2025-06-21 02:24:19 -05:00
UNFLOADER_EXEC = $( LOADER_DIR) /UNFLoader.exe
2022-09-30 17:40:50 -05:00
e l s e
2025-06-21 02:24:19 -05:00
UNFLOADER_EXEC = $( LOADER_DIR) /UNFLoader
2022-09-30 17:40:50 -05:00
e n d i f
2019-08-25 00:46:40 -04:00
SHA1SUM = sha1sum
2020-12-03 14:26:38 -05:00
PRINT = printf
2019-08-25 00:46:40 -04:00
2020-12-03 14:26:38 -05:00
i f e q ( $( COLOR ) , 1 )
NO_COL := \0 33[ 0m
RED := \0 33[ 0; 31m
GREEN := \0 33[ 0; 32m
BLUE := \0 33[ 0; 34m
YELLOW := \0 33[ 0; 33m
2021-12-30 10:57:51 -06:00
BLINK := \0 33[ 32; 5m
2020-06-02 12:44:34 -04:00
e n d i f
2021-08-05 18:11:55 -04:00
# For non-IDO, use objcopy instead of extract_data_for_mio
i f n e q ( $( COMPILER ) , i d o )
2020-12-03 14:26:38 -05:00
EXTRACT_DATA_FOR_MIO := $( OBJCOPY) -O binary --only-section= .data
2020-04-03 14:57:26 -04:00
e n d i f
2020-12-03 14:26:38 -05:00
# Common build print status function
d e f i n e p r i n t
@$( PRINT) " $( GREEN) $( 1) $( YELLOW) $( 2) $( GREEN) -> $( BLUE) $( 3) $( NO_COL) \n "
e n d e f
#==============================================================================#
# Main Targets #
#==============================================================================#
2019-08-25 00:46:40 -04:00
all : $( ROM )
2021-07-20 05:57:51 -05:00
@$( SHA1SUM) $( ROM)
2021-12-30 10:57:51 -06:00
@$( PRINT) " ${ BLINK } Build succeeded.\n $( NO_COL) "
@$( PRINT) " ==== Build Options ==== $( NO_COL) \n "
@$( PRINT) " ${ GREEN } Version: $( BLUE) $( VERSION) $( NO_COL) \n "
@$( PRINT) " ${ GREEN } Microcode: $( BLUE) $( GRUCODE) $( NO_COL) \n "
@$( PRINT) " ${ GREEN } Console: $( BLUE) $( CONSOLE) $( NO_COL) \n "
2019-08-25 00:46:40 -04:00
clean :
$( RM) -r $( BUILD_DIR_BASE)
2023-09-11 14:15:22 -07:00
rebuildtools :
2026-01-17 17:51:06 +11:00
" $( MAKE) " -C tools distclean
" $( MAKE) " -C tools
2023-09-11 14:15:22 -07:00
2020-12-03 14:26:38 -05:00
distclean : clean
$( PYTHON) extract_assets.py --clean
2026-01-17 17:51:06 +11:00
" $( MAKE) " -C $( TOOLS_DIR) clean
2019-08-25 00:46:40 -04:00
test : $( ROM )
$( EMULATOR) $( EMU_FLAGS) $<
2021-12-30 10:57:51 -06:00
test-pj64 : $( ROM )
wine ~/Desktop/new64/Project64.exe $<
# someone2639
2022-09-30 17:40:50 -05:00
# download and extract most recent unfloader build if needed
2025-06-21 02:24:19 -05:00
$(UNFLOADER_EXEC) :
i f e q ( , $( wildcard $ ( UNFLOADER_EXEC ) ) )
2022-09-30 17:40:50 -05:00
@$( PRINT) " Downloading latest UNFLoader... $( NO_COL) \n "
2024-08-03 19:09:22 -04:00
$( PYTHON) $( TOOLS_DIR) /get_latest_unfloader.py $( LOADER_DIR)
2022-09-30 17:40:50 -05:00
e n d i f
2025-06-21 02:24:19 -05:00
load : $( ROM ) $( UNFLOADER_EXEC )
$( UNFLOADER_EXEC) -r $<
2022-09-30 17:40:50 -05:00
2025-06-21 02:24:19 -05:00
unf : $( ROM ) $( UNFLOADER_EXEC )
$( UNFLOADER_EXEC) -d -r $<
2019-08-25 00:46:40 -04:00
libultra : $( BUILD_DIR ) /libultra .a
2023-06-05 17:02:58 -05:00
patch : $( ROM )
2025-01-19 11:17:45 +00:00
ifeq ( $( shell uname) , Darwin)
ifeq ( $( MAKECMDGOALS) , patch)
$( error "The 'make patch' command is not supported on macOS." )
endif
else
2025-02-25 18:26:26 -05:00
$( FLIPS) --create --bps " $( shell python3 tools/detect_baseroms.py $( VERSION) ) " " $( ROM) " " $( BUILD_DIR) / $( TARGET_STRING) .bps "
2025-01-19 11:17:45 +00:00
endif
2020-12-03 14:26:38 -05:00
# Extra object file dependencies
2023-06-26 13:35:52 -04:00
$(BUILD_DIR)/asm/ipl3.o : $( IPL 3_RAW_FILES )
2020-06-02 12:44:34 -04:00
$(BUILD_DIR)/src/game/crash_screen.o : $( CRASH_TEXTURE_C_FILES )
2024-11-05 13:11:01 +11:00
$(BUILD_DIR)/src/game/fasttext.o : $( FASTTEXT_TEXTURE_C_FILES )
2021-01-01 15:42:01 -05:00
$(BUILD_DIR)/src/game/version.o : $( BUILD_DIR ) /src /game /version_data .h
2021-12-30 10:57:51 -06:00
$(BUILD_DIR)/lib/aspMain.o : $( BUILD_DIR ) /rsp /audio .bin
2021-07-13 12:10:53 -04:00
$(SOUND_BIN_DIR)/sound_data.o : $( SOUND_BIN_DIR ) /sound_data .ctl $( SOUND_BIN_DIR ) /sound_data .tbl $( SOUND_BIN_DIR ) /sequences .bin $( SOUND_BIN_DIR ) /bank_sets
2020-12-03 14:26:38 -05:00
$(BUILD_DIR)/levels/scripts.o : $( BUILD_DIR ) /include /level_headers .h
2019-08-25 00:46:40 -04:00
2020-12-03 14:26:38 -05:00
i f e q ( $( VERSION ) , s h )
2021-07-12 23:17:54 -04:00
$( BUILD_DIR) /src/audio/load_sh.o: $( SOUND_BIN_DIR) /bank_sets.inc.c $( SOUND_BIN_DIR) /sequences_header.inc.c $( SOUND_BIN_DIR) /ctl_header.inc.c $( SOUND_BIN_DIR) /tbl_header.inc.c
2020-12-03 14:26:38 -05:00
e n d i f
2019-08-25 00:46:40 -04:00
2020-12-03 14:26:38 -05:00
$(CRASH_TEXTURE_C_FILES) : TEXTURE_ENCODING := u 32
2019-10-05 15:08:05 -04:00
2019-08-25 00:46:40 -04:00
i f e q ( $( VERSION ) , e u )
2020-12-03 14:26:38 -05:00
TEXT_DIRS := text/de text/us text/fr
2019-12-01 21:52:53 -05:00
2020-12-03 14:26:38 -05:00
# EU encoded text inserted into individual segment 0x19 files,
# and course data also duplicated in leveldata.c
$( BUILD_DIR) /bin/eu/translation_en.o: $( BUILD_DIR) /text/us/define_text.inc.c
$( BUILD_DIR) /bin/eu/translation_de.o: $( BUILD_DIR) /text/de/define_text.inc.c
$( BUILD_DIR) /bin/eu/translation_fr.o: $( BUILD_DIR) /text/fr/define_text.inc.c
$( BUILD_DIR) /levels/menu/leveldata.o: $( BUILD_DIR) /include/text_strings.h
$( BUILD_DIR) /levels/menu/leveldata.o: $( BUILD_DIR) /text/us/define_courses.inc.c
$( BUILD_DIR) /levels/menu/leveldata.o: $( BUILD_DIR) /text/de/define_courses.inc.c
$( BUILD_DIR) /levels/menu/leveldata.o: $( BUILD_DIR) /text/fr/define_courses.inc.c
2020-03-01 22:42:52 -05:00
e l s e
2020-12-03 14:26:38 -05:00
ifeq ( $( VERSION) ,sh)
TEXT_DIRS := text/jp
$( BUILD_DIR) /bin/segment2.o: $( BUILD_DIR) /text/jp/define_text.inc.c
else
TEXT_DIRS := text/$( VERSION)
# non-EU encoded text inserted into segment 0x02
$( BUILD_DIR) /bin/segment2.o: $( BUILD_DIR) /text/$( VERSION) /define_text.inc.c
endif
2020-03-01 22:42:52 -05:00
e n d i f
2019-08-25 00:46:40 -04:00
2020-12-09 16:38:26 -05:00
$(BUILD_DIR)/src/usb/usb.o : OPT_FLAGS := -O 0
$(BUILD_DIR)/src/usb/usb.o : CFLAGS += -Wno -unused -variable -Wno -sign -compare -Wno -unused -function
$(BUILD_DIR)/src/usb/debug.o : OPT_FLAGS := -O 0
$(BUILD_DIR)/src/usb/debug.o : CFLAGS += -Wno -unused -parameter -Wno -maybe -uninitialized
2021-12-30 10:57:51 -06:00
# File specific opt flags
2022-03-18 14:15:08 -04:00
$(BUILD_DIR)/src/audio/heap.o : OPT_FLAGS := -Os -fno -jump -tables
$(BUILD_DIR)/src/audio/synthesis.o : OPT_FLAGS := -Os -fno -jump -tables
2021-12-30 10:57:51 -06:00
$(BUILD_DIR)/src/engine/surface_collision.o : OPT_FLAGS := $( COLLISION_OPT_FLAGS )
$(BUILD_DIR)/src/engine/math_util.o : OPT_FLAGS := $( MATH_UTIL_OPT_FLAGS )
$(BUILD_DIR)/src/game/rendering_graph_node.o : OPT_FLAGS := $( GRAPH_NODE_OPT_FLAGS )
# $(info OPT_FLAGS: $(OPT_FLAGS))
# $(info COLLISION_OPT_FLAGS: $(COLLISION_OPT_FLAGS))
# $(info MATH_UTIL_OPT_FLAGS: $(MATH_UTIL_OPT_FLAGS))
# $(info GRAPH_NODE_OPT_FLAGS: $(GRAPH_NODE_OPT_FLAGS))
2020-12-09 16:38:26 -05:00
2025-07-02 12:37:50 +08:00
ALL_DIRS := $( BUILD_DIR) $( addprefix $( BUILD_DIR) /,$( SRC_DIRS) asm/debug $( GODDARD_SRC_DIRS) $( ULTRA_BIN_DIRS) $( BIN_DIRS) $( TEXTURE_DIRS) $( TEXT_DIRS) $( SOUND_SAMPLE_DIRS) $( addprefix levels/,$( LEVEL_DIRS) ) rsp include) $( YAY0_DIR) $( addprefix $( YAY0_DIR) /,$( VERSION) ) $( SOUND_BIN_DIR) $( SOUND_BIN_DIR) /sequences/$( VERSION)
2019-08-25 00:46:40 -04:00
# Make sure build directory exists before compiling anything
DUMMY != mkdir -p $( ALL_DIRS)
2019-10-05 19:40:22 -04:00
$(BUILD_DIR)/include/text_strings.h : $( BUILD_DIR ) /include /text_menu_strings .h
$(BUILD_DIR)/src/menu/file_select.o : $( BUILD_DIR ) /include /text_strings .h
$(BUILD_DIR)/src/menu/star_select.o : $( BUILD_DIR ) /include /text_strings .h
2019-08-25 00:46:40 -04:00
$(BUILD_DIR)/src/game/ingame_menu.o : $( BUILD_DIR ) /include /text_strings .h
2021-12-30 10:57:51 -06:00
$(BUILD_DIR)/src/game/puppycam2.o : $( BUILD_DIR ) /include /text_strings .h
2019-08-25 00:46:40 -04:00
2021-09-28 18:44:57 +01:00
2020-12-03 14:26:38 -05:00
#==============================================================================#
# Texture Generation #
#==============================================================================#
TEXTURE_ENCODING := u8
# Convert PNGs to RGBA32, RGBA16, IA16, IA8, IA4, IA1, I8, I4 binary files
2019-08-25 00:46:40 -04:00
$(BUILD_DIR)/% : %.png
2020-12-03 14:26:38 -05:00
$( call print,Converting:,$<,$@ )
$( V) $( N64GRAPHICS) -s raw -i $@ -g $< -f $( lastword $( subst ., ,$@ ) )
2019-08-25 00:46:40 -04:00
2024-11-05 13:11:01 +11:00
$(BUILD_DIR)/%.preswap.inc.c : %.preswap .png
$( call print,Converting:,$<,$@ )
$( V) $( N64GRAPHICS) -s $( TEXTURE_ENCODING) -i $@ -g $< -f $( lastword ,$( subst ., ,$* ) ) -S
2020-12-03 14:26:38 -05:00
$(BUILD_DIR)/%.inc.c : %.png
$( call print,Converting:,$<,$@ )
2024-11-05 13:11:01 +11:00
$( V) $( N64GRAPHICS) -s $( TEXTURE_ENCODING) -i $@ -g $< -f $( lastword ,$( subst ., ,$* ) )
2019-11-03 14:36:27 -05:00
2019-08-25 00:46:40 -04:00
# Color Index CI8
2021-09-12 20:14:45 -04:00
$(BUILD_DIR)/%.ci8.inc.c : %.ci 8.png
$( call print,Converting CI:,$<,$@ )
$( V) $( BINPNG) $< $@ 8
2019-08-25 00:46:40 -04:00
# Color Index CI4
2021-09-12 20:14:45 -04:00
$(BUILD_DIR)/%.ci4.inc.c : %.ci 4.png
$( call print,Converting CI:,$<,$@ )
$( V) $( BINPNG) $< $@ 4
2019-08-25 00:46:40 -04:00
2020-12-03 14:26:38 -05:00
#==============================================================================#
# Compressed Segment Generation #
#==============================================================================#
2019-08-25 00:46:40 -04:00
2020-12-03 14:26:38 -05:00
# Link segment file to resolve external labels
2019-08-25 00:46:40 -04:00
# TODO: ideally this would be `-Trodata-segment=0x07000000` but that doesn't set the address
2020-12-03 14:26:38 -05:00
$(BUILD_DIR)/%.elf : $( BUILD_DIR ) /%.o
$( call print,Linking ELF file:,$<,$@ )
$( V) $( LD) -e 0 -Ttext= $( SEGMENT_ADDRESS) -Map $@ .map -o $@ $<
2023-03-06 23:19:15 -05:00
# Override for leveldata.elf, which otherwise matches the above pattern.
# Has to be a static pattern rule for make-4.4 and above to trigger the second
# expansion.
2019-08-25 00:46:40 -04:00
.SECONDEXPANSION :
2023-03-06 23:19:15 -05:00
$(LEVEL_ELF_FILES) : $( BUILD_DIR ) /levels /%/leveldata .elf : $( BUILD_DIR ) /levels /%/leveldata .o $( BUILD_DIR ) /bin /$$( TEXTURE_BIN ) .elf
2020-12-03 14:26:38 -05:00
$( call print,Linking ELF file:,$<,$@ )
$( V) $( LD) -e 0 -Ttext= $( SEGMENT_ADDRESS) -Map $@ .map --just-symbols= $( BUILD_DIR) /bin/$( TEXTURE_BIN) .elf -o $@ $<
2019-08-25 00:46:40 -04:00
2020-12-03 14:26:38 -05:00
$(BUILD_DIR)/%.bin : $( BUILD_DIR ) /%.elf
2021-03-21 15:44:17 +00:00
$( call print,Extracting compressible data from:,$<,$@ )
2020-12-03 14:26:38 -05:00
$( V) $( EXTRACT_DATA_FOR_MIO) $< $@
2019-11-03 14:36:27 -05:00
$(BUILD_DIR)/levels/%/leveldata.bin : $( BUILD_DIR ) /levels /%/leveldata .elf
2021-03-21 15:44:17 +00:00
$( call print,Extracting compressible data from:,$<,$@ )
2020-12-03 14:26:38 -05:00
$( V) $( EXTRACT_DATA_FOR_MIO) $< $@
2019-11-03 14:36:27 -05:00
2021-01-03 13:09:20 -05:00
i f e q ( $( COMPRESS ) , g z i p )
2022-09-21 20:18:37 -05:00
i n c l u d e c o m p r e s s i o n / g z i p r u l e s . m k
2021-01-25 22:21:15 -05:00
e l s e i f e q ( $( COMPRESS ) , r n c 1 )
2022-09-21 20:18:37 -05:00
i n c l u d e c o m p r e s s i o n / r n c 1 r u l e s . m k
2021-01-25 22:21:15 -05:00
e l s e i f e q ( $( COMPRESS ) , r n c 2 )
2022-09-21 20:18:37 -05:00
i n c l u d e c o m p r e s s i o n / r n c 2 r u l e s . m k
2021-02-01 18:54:23 -05:00
e l s e i f e q ( $( COMPRESS ) , y a y 0 )
2022-09-21 20:18:37 -05:00
i n c l u d e c o m p r e s s i o n / y a y 0 r u l e s . m k
2021-03-23 17:41:15 -04:00
e l s e i f e q ( $( COMPRESS ) , m i o 0 )
2022-09-21 20:18:37 -05:00
i n c l u d e c o m p r e s s i o n / m i o 0 r u l e s . m k
2024-12-29 19:33:28 +08:00
e l s e i f e q ( $( COMPRESS ) , l z 4 t )
i n c l u d e c o m p r e s s i o n / l z 4 t r u l e s . m k
2021-04-18 13:37:52 -04:00
e l s e i f e q ( $( COMPRESS ) , u n c o m p )
2022-09-21 20:18:37 -05:00
i n c l u d e c o m p r e s s i o n / u n c o m p r u l e s . m k
2021-01-03 13:09:20 -05:00
e n d i f
2020-12-03 14:26:38 -05:00
#==============================================================================#
# Sound File Generation #
#==============================================================================#
2019-08-25 00:46:40 -04:00
$(BUILD_DIR)/%.table : %.aiff
2020-12-03 14:26:38 -05:00
$( call print,Extracting codebook:,$<,$@ )
2024-07-02 23:53:14 -04:00
$( V) $( AIFF_EXTRACT_CODEBOOK) $< $@
2019-08-25 00:46:40 -04:00
$(BUILD_DIR)/%.aifc : $( BUILD_DIR ) /%.table %.aiff
2021-07-12 23:17:54 -04:00
$( call print,Encoding ADPCM:,$( word 2,$^) ,$@ )
2020-12-03 14:26:38 -05:00
$( V) $( VADPCM_ENC) -c $^ $@
2019-08-25 00:46:40 -04:00
2023-09-01 15:08:24 -04:00
$(SOUND_BIN_DIR)/sound_data.ctl : sound /sound_banks / $( SOUND_BANK_FILES ) $( SOUND_SAMPLE_AIFCS )
2020-12-03 14:26:38 -05:00
@$( PRINT) " $( GREEN) Generating: $( BLUE) $@ $( NO_COL) \n "
2023-09-01 15:08:24 -04:00
$( V) $( PYTHON) $( TOOLS_DIR) /assemble_sound.py $( BUILD_DIR) /sound/samples/ sound/sound_banks/ $( SOUND_BIN_DIR) /sound_data.ctl $( SOUND_BIN_DIR) /ctl_header $( SOUND_BIN_DIR) /sound_data.tbl $( SOUND_BIN_DIR) /tbl_header $( C_DEFINES)
2019-08-25 00:46:40 -04:00
$(SOUND_BIN_DIR)/sound_data.tbl : $( SOUND_BIN_DIR ) /sound_data .ctl
2019-12-01 21:52:53 -05:00
@true
2019-08-25 00:46:40 -04:00
2020-12-03 14:26:38 -05:00
$(SOUND_BIN_DIR)/ctl_header : $( SOUND_BIN_DIR ) /sound_data .ctl
@true
$(SOUND_BIN_DIR)/tbl_header : $( SOUND_BIN_DIR ) /sound_data .ctl
@true
2023-09-01 15:08:24 -04:00
$(SOUND_BIN_DIR)/sequences.bin : $( SOUND_BANK_FILES ) sound /sequences .json $( SOUND_SEQUENCE_DIRS ) $( SOUND_SEQUENCE_FILES )
2020-12-03 14:26:38 -05:00
@$( PRINT) " $( GREEN) Generating: $( BLUE) $@ $( NO_COL) \n "
2023-09-01 15:08:24 -04:00
$( V) $( PYTHON) $( TOOLS_DIR) /assemble_sound.py --sequences $@ $( SOUND_BIN_DIR) /sequences_header $( SOUND_BIN_DIR) /bank_sets sound/sound_banks/ sound/sequences.json $( SOUND_SEQUENCE_FILES) $( C_DEFINES)
2019-09-01 15:50:50 -04:00
$(SOUND_BIN_DIR)/bank_sets : $( SOUND_BIN_DIR ) /sequences .bin
2019-12-01 21:52:53 -05:00
@true
2019-08-25 00:46:40 -04:00
2020-12-03 14:26:38 -05:00
$(SOUND_BIN_DIR)/sequences_header : $( SOUND_BIN_DIR ) /sequences .bin
@true
2019-08-25 00:46:40 -04:00
$(SOUND_BIN_DIR)/%.m64 : $( SOUND_BIN_DIR ) /%.o
2020-12-03 14:26:38 -05:00
$( call print,Converting to M64:,$<,$@ )
$( V) $( OBJCOPY) -j .rodata $< -O binary $@
2019-08-25 00:46:40 -04:00
2020-12-03 14:26:38 -05:00
#==============================================================================#
# Generated Source Code Files #
#==============================================================================#
2020-06-02 12:44:34 -04:00
2020-12-03 14:26:38 -05:00
# Convert binary file to a comma-separated list of byte values for inclusion in C code
$(BUILD_DIR)/%.inc.c : $( BUILD_DIR ) /%
2021-07-12 23:17:54 -04:00
$( call print,Converting to C:,$<,$@ )
2020-12-03 14:26:38 -05:00
$( V) hexdump -v -e '1/1 "0x%X,"' $< > $@
$( V) echo >> $@
2019-12-01 21:52:53 -05:00
2020-12-03 14:26:38 -05:00
# Generate animation data
2019-11-03 14:36:27 -05:00
$(BUILD_DIR)/assets/mario_anim_data.c : $( wildcard assets /anims /*.inc .c )
2020-12-03 14:26:38 -05:00
@$( PRINT) " $( GREEN) Generating animation data $( NO_COL) \n "
$( V) $( PYTHON) $( TOOLS_DIR) /mario_anims_converter.py > $@
2019-11-03 14:36:27 -05:00
2020-12-03 14:26:38 -05:00
# Generate demo input data
2019-11-03 14:36:27 -05:00
$(BUILD_DIR)/assets/demo_data.c : assets /demo_data .json $( wildcard assets /demos /*.bin )
2020-12-03 14:26:38 -05:00
@$( PRINT) " $( GREEN) Generating demo data $( NO_COL) \n "
$( V) $( PYTHON) $( TOOLS_DIR) /demo_data_converter.py assets/demo_data.json $( DEF_INC_CFLAGS) > $@
2019-11-03 14:36:27 -05:00
2020-12-03 14:26:38 -05:00
# Encode in-game text strings
$(BUILD_DIR)/include/text_strings.h : include /text_strings .h .in
$( call print,Encoding:,$<,$@ )
$( V) $( TEXTCONV) charmap.txt $< $@
$(BUILD_DIR)/include/text_menu_strings.h : include /text_menu_strings .h .in
$( call print,Encoding:,$<,$@ )
$( V) $( TEXTCONV) charmap_menu.txt $< $@
$(BUILD_DIR)/text/%/define_courses.inc.c : text /define_courses .inc .c text /%/courses .h
@$( PRINT) " $( GREEN) Preprocessing: $( BLUE) $@ $( NO_COL) \n "
$( V) $( CPP) $( CPPFLAGS) $< -o - -I text/$* / | $( TEXTCONV) charmap.txt - $@
$(BUILD_DIR)/text/%/define_text.inc.c : text /define_text .inc .c text /%/courses .h text /%/dialogs .h
@$( PRINT) " $( GREEN) Preprocessing: $( BLUE) $@ $( NO_COL) \n "
$( V) $( CPP) $( CPPFLAGS) $< -o - -I text/$* / | $( TEXTCONV) charmap.txt - $@
2019-08-25 00:46:40 -04:00
2020-12-03 14:26:38 -05:00
# Level headers
$(BUILD_DIR)/include/level_headers.h : levels /level_headers .h .in
$( call print,Preprocessing level headers:,$<,$@ )
2021-07-12 23:17:54 -04:00
$( V) $( CPP) $( CPPFLAGS) -I . $< | sed -E 's|(.+)|#include "\1"|' > $@
2019-08-25 00:46:40 -04:00
2021-01-01 15:42:01 -05:00
# Generate version_data.h
$(BUILD_DIR)/src/game/version_data.h : tools /make_version .sh
2021-01-02 21:19:27 -05:00
@$( PRINT) " $( GREEN) Generating: $( BLUE) $@ $( NO_COL) \n "
2023-09-22 13:06:39 -04:00
$( V) sh tools/make_version.sh $( CROSS) > $@
2020-12-03 14:26:38 -05:00
#==============================================================================#
# Compilation Recipes #
#==============================================================================#
# Compile C code
2022-07-19 14:04:54 +01:00
i f e q ( $( FIXLIGHTS ) , 1 )
# This must not be run multiple times at once, so we run it ahead of time rather than in a rule
2023-09-22 13:06:39 -04:00
DUMMY != $( PYTHON) $( FIXLIGHTS_PY) actors
DUMMY != $( PYTHON) $( FIXLIGHTS_PY) levels
2022-07-19 14:04:54 +01:00
e n d i f
2019-08-25 00:46:40 -04:00
$(BUILD_DIR)/%.o : %.c
2020-12-03 14:26:38 -05:00
$( call print,Compiling:,$<,$@ )
2020-12-08 19:28:12 -05:00
$( V) $( CC) -c $( CFLAGS) -MMD -MF $( BUILD_DIR) /$* .d -o $@ $<
2023-09-25 14:41:51 -05:00
$(BUILD_DIR)/%.o : %.cpp
$( call print,Compiling ( C++) :,$<,$@ )
$( V) $( CXX) -c $( CFLAGS) -std= c++17 -Wno-register -MMD -MF $( BUILD_DIR) /$* .d -o $@ $<
2019-11-03 14:36:27 -05:00
$(BUILD_DIR)/%.o : $( BUILD_DIR ) /%.c
2020-12-03 14:26:38 -05:00
$( call print,Compiling:,$<,$@ )
2020-12-08 19:28:12 -05:00
$( V) $( CC) -c $( CFLAGS) -MMD -MF $( BUILD_DIR) /$* .d -o $@ $<
2020-12-03 14:26:38 -05:00
# Assemble assembly code
2019-11-03 14:36:27 -05:00
$(BUILD_DIR)/%.o : %.s
2020-12-03 14:26:38 -05:00
$( call print,Assembling:,$<,$@ )
2021-08-05 18:11:55 -04:00
$( V) $( CROSS) gcc -c $( ASMFLAGS) $( foreach i,$( INCLUDE_DIRS) ,-Wa,-I$( i) ) -x assembler-with-cpp -MMD -MF $( BUILD_DIR) /$* .d -o $@ $<
2019-08-25 00:46:40 -04:00
2020-12-03 14:26:38 -05:00
# Assemble RSP assembly code
$(BUILD_DIR)/rsp/%.bin $(BUILD_DIR)/rsp/%_data.bin : rsp /%.s
$( call print,Assembling:,$<,$@ )
$( V) $( RSPASM) -sym $@ .sym $( RSPASMFLAGS) -strequ CODE_FILE $( BUILD_DIR) /rsp/$* .bin -strequ DATA_FILE $( BUILD_DIR) /rsp/$* _data.bin $<
# Run linker script through the C preprocessor
2021-08-13 15:14:01 -04:00
$(BUILD_DIR)/$(LD_SCRIPT) : $( LD_SCRIPT ) $( BUILD_DIR ) /goddard .txt
2020-12-03 14:26:38 -05:00
$( call print,Preprocessing linker script:,$<,$@ )
2023-01-26 10:03:07 -05:00
$( V) $( CPP) $( CPPFLAGS) -DBUILD_DIR= $( BUILD_DIR) -DULTRALIB= lib$( ULTRALIB) $( DEBUG_MAP_STACKTRACE_FLAG) -MMD -MP -MT $@ -MF $@ .d -o $@ $<
2019-08-25 00:46:40 -04:00
2021-03-28 20:54:54 -04:00
# Link libgoddard
$(BUILD_DIR)/libgoddard.a : $( GODDARD_O_FILES )
@$( PRINT) " $( GREEN) Linking libgoddard: $( BLUE) $@ $( NO_COL) \n "
$( V) $( AR) rcs -o $@ $( GODDARD_O_FILES)
2021-03-27 21:12:27 -04:00
2021-08-13 15:14:01 -04:00
# SS2: Goddard rules to get size
2025-07-02 12:37:50 +08:00
$(BUILD_DIR)/sm64_prelim.ld : sm 64.ld $( O_FILES ) $( YAY 0_OBJ_FILES ) $( SEG_FILES ) $( BUILD_DIR ) /libgoddard .a
2021-08-15 14:52:34 -04:00
$( call print,Preprocessing preliminary linker script:,$<,$@ )
2023-01-26 10:03:07 -05:00
$( V) $( CPP) $( CPPFLAGS) -DPRELIMINARY= 1 -DBUILD_DIR= $( BUILD_DIR) -DULTRALIB= lib$( ULTRALIB) -MMD -MP -MT $@ -MF $@ .d -o $@ $<
2021-08-13 15:14:01 -04:00
2021-08-15 14:52:34 -04:00
$(BUILD_DIR)/sm64_prelim.elf : $( BUILD_DIR ) /sm 64_prelim .ld
@$( PRINT) " $( GREEN) Linking Preliminary ELF file: $( BLUE) $@ $( NO_COL) \n "
2023-06-26 13:35:52 -04:00
$( V) $( LD) --gc-sections -L $( BUILD_DIR) -T $< -Map $( BUILD_DIR) /sm64_prelim.map --no-check-sections $( addprefix -R ,$( SEG_FILES) ) -o $@ $( O_FILES) -L$( LIBS_DIR) -l$( ULTRALIB) -Llib $( LINK_LIBRARIES) -u sprintf -u osMapTLB -Llib/gcclib/$( LIBGCCDIR) -lgcc
2021-08-13 15:14:01 -04:00
2021-08-15 14:52:34 -04:00
$(BUILD_DIR)/goddard.txt : $( BUILD_DIR ) /sm 64_prelim .elf
2021-08-13 15:14:01 -04:00
$( call print,Getting Goddard size...)
2026-01-17 01:50:46 -05:00
$( V) python3 tools/getGoddardSize.py $( BUILD_DIR) /sm64_prelim.map $( BUILD_DIR)
2021-08-13 15:14:01 -04:00
2021-09-18 23:54:35 -04:00
$(BUILD_DIR)/asm/debug/map.o : asm /debug /map .s $( BUILD_DIR ) /sm 64_prelim .elf
$( call print,Assembling:,$<,$@ )
2023-06-25 23:56:43 -04:00
$( V) python3 tools/mapPacker.py $( BUILD_DIR) /sm64_prelim.elf $( BUILD_DIR) /bin/addr.bin $( BUILD_DIR) /bin/name.bin
2021-09-18 23:54:35 -04:00
$( V) $( CROSS) gcc -c $( ASMFLAGS) $( foreach i,$( INCLUDE_DIRS) ,-Wa,-I$( i) ) -x assembler-with-cpp -MMD -MF $( BUILD_DIR) /$* .d -o $@ $<
2020-12-03 14:26:38 -05:00
# Link SM64 ELF file
2025-07-02 12:37:50 +08:00
$(ELF) : $( BUILD_DIR ) /sm 64_prelim .elf $( BUILD_DIR ) /asm /debug /map .o $( O_FILES ) $( YAY 0_OBJ_FILES ) $( SEG_FILES ) $( BUILD_DIR ) /$( LD_SCRIPT ) $( BUILD_DIR ) /libgoddard .a
2020-12-03 14:26:38 -05:00
@$( PRINT) " $( GREEN) Linking ELF file: $( BLUE) $@ $( NO_COL) \n "
2024-04-21 17:13:47 -04:00
$( V) $( LD) --gc-sections -L $( BUILD_DIR) -T $( BUILD_DIR) /$( LD_SCRIPT) -T goddard.txt -Map $( BUILD_DIR) /sm64.$( VERSION) .map --no-check-sections $( addprefix -R ,$( SEG_FILES) ) -o $@ $( O_FILES) -L$( LIBS_DIR) -l$( ULTRALIB) -Llib $( LINK_LIBRARIES) -u sprintf -u osMapTLB -Llib/gcclib/$( LIBGCCDIR) -lgcc
2019-08-25 00:46:40 -04:00
2020-12-03 14:26:38 -05:00
# Build ROM
2022-11-28 15:06:34 -05:00
i f e q ( n , $( findstring n ,$ ( firstword -$ ( MAKEFLAGS ) ) ) )
# run with -n / --dry-run
$(ROM) :
@$( PRINT) " $( BLUE) DRY RUNS ARE DISABLED $( NO_COL) \n "
e l s e
# not running with -n / --dry-run
2019-08-25 00:46:40 -04:00
$(ROM) : $( ELF )
2020-12-03 14:26:38 -05:00
$( call print,Building ROM:,$<,$@ )
2022-11-28 15:06:34 -05:00
e n d i f
2021-08-08 18:00:06 +01:00
i f e q ( $( CONSOLE ) , n 6 4 )
2021-08-16 17:41:27 +01:00
$( V) $( OBJCOPY) --pad-to= 0x101000 --gap-fill= 0xFF $< $@ -O binary
2021-08-08 18:00:06 +01:00
e l s e i f e q ( $( CONSOLE ) , b b )
$( V) $( OBJCOPY) --gap-fill= 0x00 $< $@ -O binary
2021-12-30 10:57:51 -06:00
$( V) dd if = $@ of = tmp bs = 16K conv = sync status = none
2021-08-08 18:00:06 +01:00
$( V) mv tmp $@
e n d i f
2021-01-25 00:44:33 -05:00
$( V) $( N64CKSUM) $@
2019-08-25 00:46:40 -04:00
$(BUILD_DIR)/$(TARGET).objdump : $( ELF )
$( OBJDUMP) -D $< > $@
2023-09-11 14:15:22 -07:00
.PHONY : all clean distclean default test load rebuildtools
2020-06-02 12:44:34 -04:00
# with no prerequisites, .SECONDARY causes no intermediate target to be removed
.SECONDARY :
2019-08-25 00:46:40 -04:00
# Remove built-in rules, to improve performance
MAKEFLAGS += --no-builtin-rules
- i n c l u d e $( DEP_FILES )
print-% : ; $( info $ * is a $ ( flavor $ *) variable set to [$ ( $ *) ]) @true