Force Link to always use Near-View or Far-View Display Lists

By CloudMax on 2014-07-05 19:15:19 Direct link
The addresses are for the Debug ROM.

So, from what I've gathered it is common practice when modifying links display lists to start by simply removing all the far-view (low-poly) display lists to gain space. And by doing so, you'd also have to change all the pointers that leads to the far-view display lists to their respective near-view display lists.
Well, I just spent a bit of time looking up where the game actually decides when to use the far-view and near-view display lists.
What it does is it check how far away link is from the camera using float values.
If the distance is 0x43200000 / 160.0 or higher, it will go over to the far-view display lists.
As reference, when in first person camera the distance is roughly -33 (negative distance since link is behind the camera)
Near-view display lists are also forced in cutscenes, and possibly other situations as well.
The branch used to force near-view in these situations is
0x00C194B4	BNEZ	T3, 0x803EA7E4
. You can set it to always branch here if you want to always force near-view display lists.
You can also change the branch address to 0x803EA7EC and add
ADDIU	T4, R0, 0x0001
below it to always force far-view display lists.
0x00C194C4	LUI	AT, 0x4320		#Set the far-view distance to 0x43200000
0x00C194C8	MTC1	AT, F6			#Move AT to F6
0x00C194CC	LWC1	F4, 0x00EC(S0)		#Load camera distance to F4
0x00C194D0	ADDIU	T4, R0, 0x0001		#Set T4 to 0x1. This is the modifier used to point to far-view display lists
0x00C194D4	C.LT.S	F4, F6			#True if F4 is less than F6 (If you are within near-view distance)
0x00C194D8	NOP				#
0x00C194DC	BC1FL	0x803EA7F0		#Branch Likely if false (If you're in far-view distance)
0x00C194E0	SW	T4, 0x008C(SP)		#Set the display-list modifier to T4 (0x1), far-view display lists will be used
0x00C194E4	BEQ	R0, R0, 0x803EA7F0 	#Branch to 0x803EA7F0 (The game branches to this command when near-view is forced)
0x00C194E8	SW	R0, 0x008C(SP)		#Set the display-list modidier to R0 (0x0), near-view display lists will be used
0x00C194EC	SW	T4, 0x008C(SP)		#Same as 0x00C194E0. Should always branch past this?


So, you can force either near-view or far-view display lists by setting 0x008C(SP) to 0x0 or 0x1. You can also change the distance used to determine display lists.
Note that this isn't a flag, it is a modifier which is shifted left twice (0x1 becomes 0x4) and added to the address when loading the display list pointer.