NewFunctions 8.71 KB

* New functions for F3DEX(.NoN), F3DLX(.NoN),
		    F3DLX.Rej, F3DLP.Rej, L3DEX ucode release 1.20.


+ gSPVertex (Gfx *pkt, Vtx *v, u32 n, u32 v0)
  gsSPVertex(          Vtx *v, u32 n, u32 v0)

	Made the vertex cache larger, so changed the range of
	parameters n and v0. (see below) g*SPVertex accepts less than
	33 vertice per one load. (n accepts 1-32.) So, you may use it
	twice or more to load more than 32 vertice(*).
	
	                    Vertice
                           cache size         Range of n      Range of v0
	F3DEX/F3DEX.NoN        32               1-32            0-31
	F3DLX/F3DLX.NoN        32               1-32            0-31
	F3DLX.Rej              64               1-32(*)         0-63
	F3DLP.Rej              80               1-32(*)         0-79
	L3DEX                  32               1-32            0-31
	

+ gSP2Triangles (pkt,  v00, v01, v02, flag0,  v10, v11, v12, flag1)
  gsSP2Triangles(      v00, v01, v02, flag0,  v10, v11, v12, flag1)

	gSP2Triangles are "double triangle face command."
	This command generates *two* triangles same as

	  gSP1Triangle(pkt++, v00, v01, v02, flag0);
	  gSP1Triangle(pkt++, v10, v11, v12, flag1);

	You can replace two g*SP1Triangle to one g*SP2Triangles,
	so this command can make DL size shorter.

	F3DLX.Rej and F3DLP.Rej are very fast because they are
	optimized for executing g*SP2Triangle. So you'd better use
	g*SPTriangle to get more performance.


+ gSP1Quadrangle (pkt,  v0, v1, v2, v3, flag)
  gsSP1Quadrangle(      v0, v1, v2, v3, flag)

	g*SP1Quadrangle generates a quadrangle (v0,v1,v2,v3).
	flag should be either 0,1,2 or 3 for flat shading.

	We don't support dynamic divide selection for quadrangle in
	this and later release. Because SP's overhead is larger than
	DP's increase of performance we had expected.

	In release 0.96 and later, g*SP1Quadrangle is emulated by
	g*SP2Triangles, so apps for release 0.95 or before can work
	with re-compiling.


+ gSPSetGeometryMode(Gfx *gdl, unsigned int mode)
  gsSPSetGeometryMode(unsigned int mode)

	G_CLIPPING would be available for mode identify.
	
	If G_CLIPPING has cleared, F3DLX does not clip any triangle
	(quadrangle) but faster.
	
	If G_CLIPPING has cleared....
	  gSPVertex   :  Does not make pre-calculated vertex data for clipping.
	  gSP*Triangle:  Does not work any clipping. (also gSP1Quadrangle)
	
	So, following DL is *not* correct because gsSP1Triangle cannot get
	pre-calculated vertex data of clipping from gsSPVertex.
	In this DL, gsSP1Triangle cannot work.

		gsSPClearGeometryMode(G_CLIPPING),	// Clipping OFF
		gsSPVertex(v, 3, 0),			// Load 3 vertices
		gsSPSetGeometryMode(G_CLIPPING),	// Clipping ON
		gsSP1Triangle(0,1,2,0),			// Draw TRI
	
	Also gSPCullDisplayList() cannot work with no pre-calculated vertex
	data made by no G_CLIPPING.
	
	G_CLIPPING is available in F3DLX only. It's ignored in other ucodes.
	
	G_CLIPPING is set when initialized RSP.


+ gSPCullDisplaylist(Gfx *gdl, unsigned int v0, unsigned int vn)
  gsSPCullDisplaylist(unsigned int v0, unsigned int vn)

	Change ranges of v0 and vn by increase vertices cache size.
	The ranges are same as v0 of gSPVertex parameter. But, must be
	v0 <= vn. (man pages are incorrect.)

	g*SPClipRatio of F3DEX(.NoN), F3DLX(.NoN) and L3DEX works same
	as Fast3D's. But F3DLX.Rej's and F3DLP.Rej's are not same at all.


+ gSPClipRatio(Gfx *gdl, r)
  gsSPClipRatio(r)

	Also, g*SPClipRatio of F3DEX(.NoN), F3DLX(.NoN) and L3DEX works
	same as Fast3D's. But F3DLX.Rej's and F3DLP.Rej's are not same
	at all. In F3DL*.Rej, g*SPClipRatio defines a size of the rejecting
	box. (default rejecting box size: FRUSTRATIO_2)


+ gSPModiftVertex(Gfx *gdl, 
		  unsigned int vtx, unsigned int where, unsigned int val)
  gsSPModifyVertex(unsigned int vtx, unsigned int where, unsigned int val)

	Change ranges of vtx by increase vertices cache size. The
	ranges are same as v0 of gSPVertex parameter. 


+ gSPBranchLessZ(Gfx *gdl, Gfx *branchdl, unsigned int vtx,
		 float zval, float near, float far, int flag)
  gsSPBranchLessZ(Gfx *branchdl, unsigned int vtx,
		  float zval, float near, float far, int flag)

	Branch display list to pointer specified `branchdl' if screen
	depth of `vtx' less than or equal `zval'. If greater, do nothing.
	It makes supporting model LOD very easier.
	
	Here is a sample model with 3 level LOD.

	Gfx model_near[] = {		// Model DL on  32<=depth<=200
		.....
		gsSPEndDisplayList(),
	};

	Gfx model_mid[] = {		// Model DL on 201<=depth<=800
		.....
		gsSPEndDisplayList(),
	};

	Gfx model_far[] = {		// Model DL on 801<=depth<=1600
		.....
		gsSPEndDisplayList(),
	};

	Gfx model[] = {
		gsSPVertex(testvtx, 1, 0),
		gsSPBranchLessZ(model_near, 0,  200, 32, 2000, G_BZ_PERSP),
		gsSPBranchLessZ(model_mid,  0,  800, 32, 2000, G_BZ_PERSP),
		gsSPBranchLessZ(model_far,  0, 1600, 32, 2000, G_BZ_PERSP),
		gsSPEndDisplayList(),	// Don't display if 1601<=depth.
	};

	This GBI needs some parameters about viewing frustum as following.
	
	`near'	Distance to the near clipping plane.
		Same value specified in guPerspective()/guOrtho().
	`far'	Distance to the far  clipping plane.
		Same value specified in guPerspective()/guOrtho().
	`flag'	Set `G_BZ_PERSP' for perspective  projection(guPerspective).
		Set `G_BZ_ORTHO' for orthographic projection(guOrtho).

	To use g*SPBranchLessZ(), the view port parameters
	`vp.vscale[2]' and `vp.vtrans[2]' should be set `G_MAXZ/2'.
	Normally, it is unnecessary to set other values for vp.vscale[2],
	and vp.vtrans[2]. But, when you want other values, you may use
	g*SPBranchLessZrg() instead of g*SPBranchLessZ().
	
	This GBI's are supported in release 1.02 or later, and available
	in F3DEX(.NoN), F3DLX(.NoN), F3DLX.Rej, F3DLP.Rej and L3DEX.


+ gSPBranchLessZrg(Gfx *gdl, Gfx *branchdl, unsigned int vtx,
		   float zval, float near, float far, int flag,
		   int zmin, int zmax)
  gsSPBranchLessZrg(Gfx *branchdl, unsigned int vtx,
		    float zval, float near, float far, int flag,
		    int zmin, int zmax)

	Normally, the range of screen depth value should be 0 to G_MAXZ
	with g*SPBranchLessZ. However, if you want to use another range
	`zmin' to `zmax', you should use g*SPBranchLessZrg instead of
	g*SPBranchLessZ. 
	g*SPBranchLessZrg needs two more parameters than g*SPBranchLessZ.
	
	`zmin'	depth value minimum. (= vp.vtrans[2]-vp.vscale[2])
	`zmax'	depth value maximum. (= vp.vtrans[2]+vp.vscale[2])
	
	Other paramters (gdl, branchdl, vtx, zval, near, far and flag)
	are same as g*SPBranchLessZ's.
	
	This GBI's are supported in release 1.02 or later, and available
	in F3DEX(.NoN), F3DLX(.NoN), F3DLX.Rej, F3DLP.Rej and L3DEX.


+ gSPLoadUcode(Gfx *gdl, u64 *uc_start, u64 *uc_dstart)
  gsSPLoadUcode(u64 *uc_start, u64 *uc_dstart)

	uc_start : Physical address of the top of the ucode text section.
	uc_dstart: Physical address of the top of the ucode data section.
	
	Load ucode into IMEM/DMEM and initailize RSP.
	Loadable ucodes are F3DEX(.NoN), F3DLX(.NoN), F3DLX_Rej, F3DLP_Rej
	and L3DEX. Fast3D and Turbo3D are not loadable.

	If you have F3DEX 1.22 (in the N64 Dev 2.0H) and S2DEX ucode for
	Sprite drawing, you can use gSPLoadUcode to load S2DEX for drawing
	sprite.

	You should be careful to `Load ucode'. Because to load ucode would 
	often take some processing time. It's overhead. So, you should 
	avoid useless ucode loading.

	The ucodes would be changed to get best performance in the situation,
	such as...

	o Loading F3DLX ucode to draw game field with clipping function.
			(Clipping is necessary to draw game field.)
	o Loading F3DLX.Rej (after draw game field) to draw game object as
	  a man, a car ... (F3DLX.Rej is faster than F3DLX.)

	And you can load line ucode `L3DEX' to draw line without CPU 
	processing.

	*** Caution ***
	This GBI command g*SPLoadUcode makes RSP initailized.
	So, you should set all parameters of RSP status again
	(Segment address, Viewport, Geometry-mode, Matrix, Link info.
	of display list ... and more). So, when you use g*SPLoadUcode in
	Display list (DL1) linked from another Display List (DL2) by 
	g*SPDisplayList, the DL1 cannot return back to DL2. It's very
	dangerous implemention I think, but we don't have enough code
	space to fix it.
	
	You should set `OS_TASK_LOADABLE' to member `flag' in `OSTask' to
	use this GBI g*SPLoadUcode like as this.
	
		OSTask *tp;
		tp->t.flag = OS_TASK_LOADABLE | OS_TASK_DP_WAIT;
	
	To make OS_TASK_LOADABLE available, you need some patches for
	N64 OS libraries. For more information, see `OS patches:'
	in file	`README'. The patched OS libultra*.a have upper
	compatiblility with original OS.
	

+ gSPLoadUcodeL(Gfx *gdl, ucode_name)
  gsSPLoadUcodeL(ucode_name)

	g*SPLoadUcodeL is same as g*SPLoadUcode expect an expression.
	See following, (a) and (b) works equally.

	(a) gsSPLoadUcode(OS_K0_TO_PHYSICAL(&gspF3DEX_fifoTextStart),
			  OS_K0_TO_PHYSICAL(&gspF3DEX_fifoDataStart))
	(b) gsSPLoadUcodeL(gspF3DEX_fifo)