1 #include <assert.h>
2 #include <stdint.h>
3 #include <math.h>
4 #include "N64.h"
5 #include "RSP.h"
6 #include "RDP.h"
7 #include "gSP.h"
8 #include "gDP.h"
9 #include "F3D.h"
10 #include "OpenGL.h"
11 #include "3DMath.h"
12 
13 #include "../../Graphics/RDP/gDP_state.h"
14 #include "../../Graphics/RSP/gSP_state.h"
15 #include "../../Graphics/HLE/Microcode/ZSort.h"
16 
17 ZSORTRDP GLN64zSortRdp = {{0, 0}, {0, 0}, 0, 0};
18 
ZSort_RDPCMD(uint32_t a,uint32_t _w1)19 void ZSort_RDPCMD( uint32_t a, uint32_t _w1)
20 {
21    uint32_t addr = RSP_SegmentToPhysical(_w1) >> 2;
22    if (addr)
23    {
24       __RSP.bLLE = true;
25       while(true)
26       {
27          uint32_t w1;
28          uint32_t w0 = ((uint32_t*)gfx_info.RDRAM)[addr++];
29          __RSP.cmd = _SHIFTR( w0, 24, 8 );
30          if (__RSP.cmd == 0xDF)
31             break;
32          w1 = ((uint32_t*)gfx_info.RDRAM)[addr++];
33          if (__RSP.cmd == 0xE4 || __RSP.cmd == 0xE5)
34          {
35             addr++;
36             __RDP.w2 = ((uint32_t*)gfx_info.RDRAM)[addr++];
37             addr++;
38             __RDP.w3 = ((uint32_t*)gfx_info.RDRAM)[addr++];
39          }
40          GBI.cmd[__RSP.cmd]( w0, w1 );
41       };
42       __RSP.bLLE = false;
43    }
44 }
45 
46 /* RSP command VRCPL */
47 
ZSort_DrawObject(uint8_t * _addr,uint32_t _type)48 static void ZSort_DrawObject (uint8_t * _addr, uint32_t _type)
49 {
50    uint32_t i;
51    uint32_t textured = 0, vnum = 0, vsize = 0;
52 
53    switch (_type)
54    {
55       case ZH_NULL:
56          textured = vnum = vsize = 0;
57          break;
58       case ZH_SHTRI:
59          textured = 0;
60          vnum = 3;
61          vsize = 8;
62          break;
63       case ZH_TXTRI:
64          textured = 1;
65          vnum = 3;
66          vsize = 16;
67          break;
68       case ZH_SHQUAD:
69          textured = 0;
70          vnum = 4;
71          vsize = 8;
72          break;
73       case ZH_TXQUAD:
74          textured = 1;
75          vnum = 4;
76          vsize = 16;
77          break;
78    }
79 
80    for (i = 0; i < vnum; ++i)
81    {
82       struct SPVertex *vtx = (struct SPVertex*)&OGL.triangles.vertices[i];
83       vtx->x = _FIXED2FLOAT(((int16_t*)_addr)[0 ^ 1], 2);
84       vtx->y = _FIXED2FLOAT(((int16_t*)_addr)[1 ^ 1], 2);
85       vtx->z = 0.0f;
86       vtx->r = _addr[4^3] * 0.0039215689f;
87       vtx->g = _addr[5^3] * 0.0039215689f;
88       vtx->b = _addr[6^3] * 0.0039215689f;
89       vtx->a = _addr[7^3] * 0.0039215689f;
90       vtx->flag    = 0;
91       vtx->HWLight = 0;
92       vtx->clip    = 0;
93       vtx->w       = 1.0f;
94       if (textured != 0)
95       {
96          vtx->s = _FIXED2FLOAT(((int16_t*)_addr)[4^1], 5 );
97          vtx->t = _FIXED2FLOAT(((int16_t*)_addr)[5^1], 5 );
98          vtx->w = ZSort_Calc_invw(((int*)_addr)[3]) / 31.0f;
99       }
100 
101       _addr += vsize;
102    }
103 
104    //render.drawLLETriangle(vnum);
105 }
106 
ZSort_LoadObject(uint32_t _zHeader,uint32_t * _pRdpCmds)107 static uint32_t ZSort_LoadObject (uint32_t _zHeader, uint32_t * _pRdpCmds)
108 {
109    uint32_t w1;
110    const uint32_t type = _zHeader & 7;
111    uint8_t * addr = gfx_info.RDRAM + (_zHeader&0xFFFFFFF8);
112 
113    switch (type)
114    {
115       case ZH_SHTRI:
116       case ZH_SHQUAD:
117          {
118             w1 = ((uint32_t*)addr)[1];
119             if (w1 != _pRdpCmds[0]) {
120                _pRdpCmds[0] = w1;
121                ZSort_RDPCMD (0, w1);
122             }
123             ZSort_DrawObject(addr + 8, type);
124          }
125          break;
126       case ZH_NULL:
127       case ZH_TXTRI:
128       case ZH_TXQUAD:
129          {
130             w1 = ((uint32_t*)addr)[1];
131             if (w1 != _pRdpCmds[0]) {
132                _pRdpCmds[0] = w1;
133                ZSort_RDPCMD (0, w1);
134             }
135             w1 = ((uint32_t*)addr)[2];
136             if (w1 != _pRdpCmds[1]) {
137                ZSort_RDPCMD (0, w1);
138                _pRdpCmds[1] = w1;
139             }
140             w1 = ((uint32_t*)addr)[3];
141             if (w1 != _pRdpCmds[2]) {
142                ZSort_RDPCMD (0,  w1);
143                _pRdpCmds[2] = w1;
144             }
145             if (type != 0) {
146                ZSort_DrawObject(addr + 16, type);
147             }
148          }
149          break;
150    }
151    return RSP_SegmentToPhysical(((uint32_t*)addr)[0]);
152 }
153 
ZSort_Obj(uint32_t _w0,uint32_t _w1)154 void ZSort_Obj( uint32_t _w0, uint32_t _w1 )
155 {
156    uint32_t rdpcmds[3] = {0, 0, 0};
157    uint32_t cmd1 = _w1;
158    uint32_t zHeader = RSP_SegmentToPhysical(_w0);
159    while (zHeader)
160       zHeader = ZSort_LoadObject(zHeader, rdpcmds);
161    zHeader = RSP_SegmentToPhysical(cmd1);
162    while (zHeader)
163       zHeader = ZSort_LoadObject(zHeader, rdpcmds);
164 }
165 
ZSort_Interpolate(uint32_t a,uint32_t b)166 void ZSort_Interpolate( uint32_t a , uint32_t b)
167 {
168 #ifdef DEBUG
169 	LOG(LOG_VERBOSE, "ZSort_Interpolate Ignored\n");
170 #endif
171 }
172 
ZSort_XFMLight(uint32_t _w0,uint32_t _w1)173 void ZSort_XFMLight( uint32_t _w0, uint32_t _w1 )
174 {
175    uint32_t i, addr;
176    int mid = _SHIFTR(_w0, 0, 8);
177    gln64gSPNumLights(1 + _SHIFTR(_w1, 12, 8));
178    addr = -1024 + _SHIFTR(_w1, 0, 12);
179 
180    assert(mid == GZM_MMTX);
181 
182    gSP.lights[gSP.numLights].r = (float)(((uint8_t*)gfx_info.DMEM)[(addr+0)^3]) * 0.0039215689f;
183    gSP.lights[gSP.numLights].g = (float)(((uint8_t*)gfx_info.DMEM)[(addr+1)^3]) * 0.0039215689f;
184    gSP.lights[gSP.numLights].b = (float)(((uint8_t*)gfx_info.DMEM)[(addr+2)^3]) * 0.0039215689f;
185    addr += 8;
186    for (i = 0; i < gSP.numLights; ++i)
187    {
188       gSP.lights[i].r = (float)(((uint8_t*)gfx_info.DMEM)[(addr+0)^3]) * 0.0039215689f;
189       gSP.lights[i].g = (float)(((uint8_t*)gfx_info.DMEM)[(addr+1)^3]) * 0.0039215689f;
190       gSP.lights[i].b = (float)(((uint8_t*)gfx_info.DMEM)[(addr+2)^3]) * 0.0039215689f;
191       gSP.lights[i].x = (float)(((int8_t*)gfx_info.DMEM)[(addr+8)^3]);
192       gSP.lights[i].y = (float)(((int8_t*)gfx_info.DMEM)[(addr+9)^3]);
193       gSP.lights[i].z = (float)(((int8_t*)gfx_info.DMEM)[(addr+10)^3]);
194       addr += 24;
195    }
196    for (i = 0; i < 2; i++)
197    {
198       gSP.lookat[i].x = (float)(((int8_t*)gfx_info.DMEM)[(addr+8)^3]);
199       gSP.lookat[i].y = (float)(((int8_t*)gfx_info.DMEM)[(addr+9)^3]);
200       gSP.lookat[i].z = (float)(((int8_t*)gfx_info.DMEM)[(addr+10)^3]);
201       gSP.lookatEnable = (i == 0) || (i == 1 && gSP.lookat[i].x != 0 && gSP.lookat[i].y != 0);
202       addr += 24;
203    }
204 }
205 
ZSort_LightingL(uint32_t a,uint32_t b)206 void ZSort_LightingL( uint32_t a, uint32_t b )
207 {
208 #ifdef DEBUG
209 	LOG(LOG_VERBOSE, "ZSort_LightingL Ignored\n");
210 #endif
211 }
212 
213 
ZSort_Lighting(uint32_t _w0,uint32_t _w1)214 void ZSort_Lighting( uint32_t _w0, uint32_t _w1 )
215 {
216    uint32_t i;
217    uint32_t csrs = -1024 + _SHIFTR(_w0, 12, 12);
218    uint32_t nsrs = -1024 + _SHIFTR(_w0, 0, 12);
219    uint32_t num = 1 + _SHIFTR(_w1, 24, 8);
220    uint32_t cdest = -1024 + _SHIFTR(_w1, 12, 12);
221    uint32_t tdest = -1024 + _SHIFTR(_w1, 0, 12);
222    int use_material = (csrs != 0x0ff0);
223    tdest >>= 1;
224 
225    for (i = 0; i < num; i++)
226    {
227       float x, y;
228       float fLightDir[3];
229       struct SPVertex *vtx = (struct SPVertex*)&OGL.triangles.vertices[i];
230 
231       vtx->nx = ((int8_t*)gfx_info.DMEM)[(nsrs++)^3];
232       vtx->ny = ((int8_t*)gfx_info.DMEM)[(nsrs++)^3];
233       vtx->nz = ((int8_t*)gfx_info.DMEM)[(nsrs++)^3];
234       TransformVectorNormalize( &vtx->nx, gSP.matrix.modelView[gSP.matrix.modelViewi] );
235       gln64gSPLightVertex(vtx);
236       fLightDir[0] = vtx->nx;
237       fLightDir[1] = vtx->ny;
238       fLightDir[2] = vtx->nz;
239       TransformVectorNormalize(fLightDir, gSP.matrix.projection);
240       if (gSP.lookatEnable) {
241          x = DotProduct(&gSP.lookat[0].x, fLightDir);
242          y = DotProduct(&gSP.lookat[1].x, fLightDir);
243       } else {
244          x = fLightDir[0];
245          y = fLightDir[1];
246       }
247       vtx->s = (x + 1.0f) * 512.0f;
248       vtx->t = (y + 1.0f) * 512.0f;
249 
250       vtx->a = 1.0f;
251       if (use_material)
252       {
253          vtx->r *= gfx_info.DMEM[(csrs++)^3] * 0.0039215689f;
254          vtx->g *= gfx_info.DMEM[(csrs++)^3] * 0.0039215689f;
255          vtx->b *= gfx_info.DMEM[(csrs++)^3] * 0.0039215689f;
256          vtx->a = gfx_info.DMEM[(csrs++)^3] * 0.0039215689f;
257       }
258       gfx_info.DMEM[(cdest++)^3] = (uint8_t)(vtx->r * 255.0f);
259       gfx_info.DMEM[(cdest++)^3] = (uint8_t)(vtx->g * 255.0f);
260       gfx_info.DMEM[(cdest++)^3] = (uint8_t)(vtx->b * 255.0f);
261       gfx_info.DMEM[(cdest++)^3] = (uint8_t)(vtx->a * 255.0f);
262       ((int16_t*)gfx_info.DMEM)[(tdest++)^1] = (int16_t)(vtx->s * 32.0f);
263       ((int16_t*)gfx_info.DMEM)[(tdest++)^1] = (int16_t)(vtx->t * 32.0f);
264    }
265 }
266 
ZSort_MTXRNSP(uint32_t a,uint32_t b)267 void ZSort_MTXRNSP(uint32_t a, uint32_t b)
268 {
269 #ifdef DEBUG
270 	LOG(LOG_VERBOSE, "ZSort_MTXRNSP Ignored\n");
271 #endif
272 }
273 
ZSort_MTXCAT(uint32_t _w0,uint32_t _w1)274 void ZSort_MTXCAT(uint32_t _w0, uint32_t _w1)
275 {
276    float m[4][4];
277    M44 *s = NULL;
278    M44 *t = NULL;
279    uint32_t S = _SHIFTR(_w0, 0, 4);
280    uint32_t T = _SHIFTR(_w1, 16, 4);
281    uint32_t D = _SHIFTR(_w1, 0, 4);
282    switch (S)
283    {
284       case GZM_MMTX:
285          s = (M44*)gSP.matrix.modelView[gSP.matrix.modelViewi];
286          break;
287       case GZM_PMTX:
288          s = (M44*)gSP.matrix.projection;
289          break;
290       case GZM_MPMTX:
291          s = (M44*)gSP.matrix.combined;
292          break;
293    }
294 
295    switch (T)
296    {
297       case GZM_MMTX:
298          t = (M44*)gSP.matrix.modelView[gSP.matrix.modelViewi];
299          break;
300       case GZM_PMTX:
301          t = (M44*)gSP.matrix.projection;
302          break;
303       case GZM_MPMTX:
304          t = (M44*)gSP.matrix.combined;
305          break;
306    }
307    assert(s != NULL && t != NULL);
308    MultMatrix(*s, *t, m);
309 
310    switch (D) {
311       case GZM_MMTX:
312          memcpy (gSP.matrix.modelView[gSP.matrix.modelViewi], m, 64);;
313          break;
314       case GZM_PMTX:
315          memcpy (gSP.matrix.projection, m, 64);;
316          break;
317       case GZM_MPMTX:
318          memcpy (gSP.matrix.combined, m, 64);;
319          break;
320    }
321 }
322 
323 struct zSortVDest{
324 	int16_t sy;
325 	int16_t sx;
326 	int32_t invw;
327 	int16_t yi;
328 	int16_t xi;
329 	int16_t wi;
330 	uint8_t fog;
331 	uint8_t cc;
332 };
333 
ZSort_MultMPMTX(uint32_t _w0,uint32_t _w1)334 void ZSort_MultMPMTX( uint32_t _w0, uint32_t _w1 )
335 {
336    unsigned i;
337    struct zSortVDest v;
338    int num = 1 + _SHIFTR(_w1, 24, 8);
339    int src = -1024 + _SHIFTR(_w1, 12, 12);
340    int dst = -1024 + _SHIFTR(_w1, 0, 12);
341    int16_t * saddr = (int16_t*)(gfx_info.DMEM+src);
342    struct zSortVDest * daddr = (struct zSortVDest*)(gfx_info.DMEM+dst);
343    int idx = 0;
344 
345    memset(&v, 0, sizeof(struct zSortVDest));
346    for (i = 0; i < num; ++i)
347    {
348       int16_t sx = saddr[(idx++)^1];
349       int16_t sy = saddr[(idx++)^1];
350       int16_t sz = saddr[(idx++)^1];
351       float x = sx*gSP.matrix.combined[0][0] + sy*gSP.matrix.combined[1][0] + sz*gSP.matrix.combined[2][0] + gSP.matrix.combined[3][0];
352       float y = sx*gSP.matrix.combined[0][1] + sy*gSP.matrix.combined[1][1] + sz*gSP.matrix.combined[2][1] + gSP.matrix.combined[3][1];
353       float z = sx*gSP.matrix.combined[0][2] + sy*gSP.matrix.combined[1][2] + sz*gSP.matrix.combined[2][2] + gSP.matrix.combined[3][2];
354       float w = sx*gSP.matrix.combined[0][3] + sy*gSP.matrix.combined[1][3] + sz*gSP.matrix.combined[2][3] + gSP.matrix.combined[3][3];
355       v.sx    = (int16_t)(GLN64zSortRdp.view_trans[0] + x / w * GLN64zSortRdp.view_scale[0]);
356       v.sy    = (int16_t)(GLN64zSortRdp.view_trans[1] + y / w * GLN64zSortRdp.view_scale[1]);
357 
358       v.xi    = (int16_t)x;
359       v.yi    = (int16_t)y;
360       v.wi    = (int16_t)w;
361       v.invw  = ZSort_Calc_invw((int)(w * 31.0));
362 
363       if (w < 0.0f)
364          v.fog = 0;
365       else {
366          int fog = (int)(z / w * gSP.fog.multiplier + gSP.fog.offset);
367          if (fog > 255)
368             fog = 255;
369          v.fog = (fog >= 0) ? (uint8_t)fog : 0;
370       }
371 
372       v.cc = 0;
373       if (x < -w) v.cc |= 0x10;
374       if (x > w) v.cc |= 0x01;
375       if (y < -w) v.cc |= 0x20;
376       if (y > w) v.cc |= 0x02;
377       if (w < 0.1f) v.cc |= 0x04;
378 
379       daddr[i] = v;
380    }
381 }
382 
ZSort_LinkSubDL(uint32_t a,uint32_t b)383 void ZSort_LinkSubDL( uint32_t a , uint32_t b)
384 {
385 #ifdef DEBUG
386 	LOG(LOG_VERBOSE, "ZSort_LinkSubDL Ignored\n");
387 #endif
388 }
389 
ZSort_SetSubDL(uint32_t a,uint32_t b)390 void ZSort_SetSubDL( uint32_t a, uint32_t b)
391 {
392 #ifdef DEBUG
393 	LOG(LOG_VERBOSE, "ZSort_SetSubDL Ignored\n");
394 #endif
395 }
396 
ZSort_WaitSignal(uint32_t a,uint32_t b)397 void ZSort_WaitSignal( uint32_t a, uint32_t b)
398 {
399 #ifdef DEBUG
400 	LOG(LOG_VERBOSE, "ZSort_WaitSignal Ignored\n");
401 #endif
402 }
403 
ZSort_SendSignal(uint32_t a,uint32_t b)404 void ZSort_SendSignal( uint32_t a, uint32_t b)
405 {
406 #ifdef DEBUG
407 	LOG(LOG_VERBOSE, "ZSort_SendSignal Ignored\n");
408 #endif
409 }
410 
ZSort_SetTexture(void)411 static void ZSort_SetTexture(void)
412 {
413 	gSP.texture.scales = 1.0f;
414 	gSP.texture.scalet = 1.0f;
415 	gSP.texture.level = 0;
416 	gSP.texture.on = 1;
417 	gSP.texture.tile = 0;
418 
419 	gln64gSPSetGeometryMode(0x0200);
420 }
421 
ZSort_MoveMem(uint32_t _w0,uint32_t _w1)422 void ZSort_MoveMem( uint32_t _w0, uint32_t _w1 )
423 {
424    int idx = _w0 & 0x0E;
425    int ofs = _SHIFTR(_w0, 6, 9)<<3;
426    int len = 1 + (_SHIFTR(_w0, 15, 9)<<3);
427    int flag = _w0 & 0x01;
428    uint32_t addr = RSP_SegmentToPhysical(_w1);
429    switch (idx)
430    {
431       case GZF_LOAD:
432          if (flag == 0)
433          {
434             int dmem_addr = (idx<<3) + ofs;
435             memcpy(gfx_info.DMEM + dmem_addr, gfx_info.RDRAM + addr, len);
436          }
437          else
438          {
439             int dmem_addr = (idx<<3) + ofs;
440             memcpy(gfx_info.RDRAM + addr, gfx_info.DMEM + dmem_addr, len);
441          }
442          break;
443 
444       case GZM_MMTX:  // model matrix
445          RSP_LoadMatrix(gSP.matrix.modelView[gSP.matrix.modelViewi], addr);
446          gSP.changed |= CHANGED_MATRIX;
447          break;
448 
449       case GZM_PMTX:  // projection matrix
450          RSP_LoadMatrix(gSP.matrix.projection, addr);
451          gSP.changed |= CHANGED_MATRIX;
452          break;
453 
454       case GZM_MPMTX:  // combined matrix
455          RSP_LoadMatrix(gSP.matrix.combined, addr);
456          gSP.changed &= ~CHANGED_MATRIX;
457          break;
458 
459       case GZM_OTHERMODE:
460 #ifdef DEBUG
461          LOG(LOG_VERBOSE, "MoveMem Othermode Ignored\n");
462 #endif
463          break;
464 
465       case GZM_VIEWPORT:
466          {
467             uint32_t a = addr >> 1;
468             const float scale_x = _FIXED2FLOAT( *(int16_t*)&gfx_info.RDRAM[(a+0)^1], 2 );
469             const float scale_y = _FIXED2FLOAT( *(int16_t*)&gfx_info.RDRAM[(a+1)^1], 2 );
470             const float scale_z = _FIXED2FLOAT( *(int16_t*)&gfx_info.RDRAM[(a+2)^1], 10 );
471             const float trans_x = _FIXED2FLOAT( *(int16_t*)&gfx_info.RDRAM[(a+4)^1], 2 );
472             const float trans_y = _FIXED2FLOAT( *(int16_t*)&gfx_info.RDRAM[(a+5)^1], 2 );
473             const float trans_z = _FIXED2FLOAT( *(int16_t*)&gfx_info.RDRAM[(a+6)^1], 10 );
474 
475             gSP.fog.multiplier = ((int16_t*)gfx_info.RDRAM)[(a+3)^1];
476             gSP.fog.offset = ((int16_t*)gfx_info.RDRAM)[(a+7)^1];
477 
478             gSP.viewport.vscale[0] = scale_x;
479             gSP.viewport.vscale[1] = scale_y;
480             gSP.viewport.vscale[2] = scale_z;
481             gSP.viewport.vtrans[0] = trans_x;
482             gSP.viewport.vtrans[1] = trans_y;
483             gSP.viewport.vtrans[2] = trans_z;
484 
485             gSP.viewport.x		= gSP.viewport.vtrans[0] - gSP.viewport.vscale[0];
486             gSP.viewport.y		= gSP.viewport.vtrans[1] - gSP.viewport.vscale[1];
487             gSP.viewport.width	= gSP.viewport.vscale[0] * 2;
488             gSP.viewport.height	= gSP.viewport.vscale[1] * 2;
489             gSP.viewport.nearz	= gSP.viewport.vtrans[2] - gSP.viewport.vscale[2];
490             gSP.viewport.farz	= (gSP.viewport.vtrans[2] + gSP.viewport.vscale[2]) ;
491 
492             GLN64zSortRdp.view_scale[0] = scale_x*4.0f;
493             GLN64zSortRdp.view_scale[1] = scale_y*4.0f;
494             GLN64zSortRdp.view_trans[0] = trans_x*4.0f;
495             GLN64zSortRdp.view_trans[1] = trans_y*4.0f;
496 
497             gSP.changed |= CHANGED_VIEWPORT;
498 
499             ZSort_SetTexture();
500          }
501          break;
502 
503       default:
504          //LOG(LOG_ERROR, "ZSort_MoveMem UNKNOWN %d\n", idx);
505          break;
506    }
507 
508 }
509 
SZort_SetScissor(uint32_t _w0,uint32_t _w1)510 void SZort_SetScissor(uint32_t _w0, uint32_t _w1)
511 {
512 	RDP_SetScissor(_w0, _w1);
513 
514 	if ((gDP.scissor.lrx - gDP.scissor.ulx) > (GLN64zSortRdp.view_scale[0] - GLN64zSortRdp.view_trans[0]))
515 	{
516 		float w = (gDP.scissor.lrx - gDP.scissor.ulx) / 2.0f;
517 		float h = (gDP.scissor.lry - gDP.scissor.uly) / 2.0f;
518 
519 		gSP.viewport.vscale[0] = w;
520 		gSP.viewport.vscale[1] = h;
521 		gSP.viewport.vtrans[0] = w;
522 		gSP.viewport.vtrans[1] = h;
523 
524 		gSP.viewport.x = gSP.viewport.vtrans[0] - gSP.viewport.vscale[0];
525 		gSP.viewport.y = gSP.viewport.vtrans[1] - gSP.viewport.vscale[1];
526 		gSP.viewport.width = gSP.viewport.vscale[0] * 2;
527 		gSP.viewport.height = gSP.viewport.vscale[1] * 2;
528 
529 		GLN64zSortRdp.view_scale[0] = w * 4.0f;
530 		GLN64zSortRdp.view_scale[1] = h * 4.0f;
531 		GLN64zSortRdp.view_trans[0] = w * 4.0f;
532 		GLN64zSortRdp.view_trans[1] = h * 4.0f;
533 
534 		gSP.changed |= CHANGED_VIEWPORT;
535 
536 		ZSort_SetTexture();
537 	}
538 }
539 
540 #define	G_ZS_ZOBJ			0x80
541 #define	G_ZS_RDPCMD			0x81
542 #define	G_ZS_SETOTHERMODE_H	0xE3
543 #define	G_ZS_SETOTHERMODE_L	0xE2
544 #define	G_ZS_ENDDL			0xDF
545 #define	G_ZS_DL				0xDE
546 #define	G_ZS_MOVEMEM		0xDC
547 #define	G_ZS_MOVEWORD		0xDB
548 #define	G_ZS_SENDSIGNAL		0xDA
549 #define	G_ZS_WAITSIGNAL		0xD9
550 #define	G_ZS_SETSUBDL		0xD8
551 #define	G_ZS_LINKSUBDL		0xD7
552 #define	G_ZS_MULT_MPMTX		0xD6
553 #define	G_ZS_MTXCAT			0xD5
554 #define	G_ZS_MTXTRNSP		0xD4
555 #define	G_ZS_LIGHTING_L		0xD3
556 #define	G_ZS_LIGHTING		0xD2
557 #define	G_ZS_XFMLIGHT		0xD1
558 #define	G_ZS_INTERPOLATE	0xD0
559 
560 uint32_t G_ZOBJ, G_ZRDPCMD, G_ZSENDSIGNAL, G_ZWAITSIGNAL, G_ZSETSUBDL, G_ZLINKSUBDL, G_ZMULT_MPMTX, G_ZMTXCAT, G_ZMTXTRNSP;
561 uint32_t G_ZLIGHTING_L, G_ZLIGHTING, G_ZXFMLIGHT, G_ZINTERPOLATE, G_ZSETSCISSOR;
562 
ZSort_Init(void)563 void ZSort_Init(void)
564 {
565 	gSPSetupFunctions();
566 	// Set GeometryMode flags
567 	GBI_InitFlags( F3D );
568 
569 	GBI.PCStackSize = 10;
570 
571 	//          GBI Command             Command Value			Command Function
572 	GBI_SetGBI( G_SPNOOP,				F3D_SPNOOP,				F3D_SPNoOp );
573 	GBI_SetGBI( G_RESERVED0,			F3D_RESERVED0,			F3D_Reserved0 );
574 	GBI_SetGBI( G_RESERVED1,			F3D_RESERVED1,			F3D_Reserved1 );
575 	GBI_SetGBI( G_DL,					G_ZS_DL,				F3D_DList );
576 	GBI_SetGBI( G_RESERVED2,			F3D_RESERVED2,			F3D_Reserved2 );
577 	GBI_SetGBI( G_RESERVED3,			F3D_RESERVED3,			F3D_Reserved3 );
578 
579 	GBI_SetGBI( G_CULLDL,				F3D_CULLDL,				F3D_CullDL );
580 	GBI_SetGBI( G_MOVEWORD,				G_ZS_MOVEWORD,			F3D_MoveWord );
581 	GBI_SetGBI( G_TEXTURE,				F3D_TEXTURE,			F3D_Texture );
582 	GBI_SetGBI( G_ZSETSCISSOR,			G_SETSCISSOR,			SZort_SetScissor );
583 	GBI_SetGBI( G_SETOTHERMODE_H,		G_ZS_SETOTHERMODE_H,	F3D_SetOtherMode_H );
584 	GBI_SetGBI( G_SETOTHERMODE_L,		G_ZS_SETOTHERMODE_L,	F3D_SetOtherMode_L );
585 	GBI_SetGBI( G_ENDDL,				G_ZS_ENDDL,				F3D_EndDL );
586 	GBI_SetGBI( G_SETGEOMETRYMODE,		F3D_SETGEOMETRYMODE,	F3D_SetGeometryMode );
587 	GBI_SetGBI( G_CLEARGEOMETRYMODE,	F3D_CLEARGEOMETRYMODE,	F3D_ClearGeometryMode );
588 	GBI_SetGBI( G_RDPHALF_1,			F3D_RDPHALF_1,			F3D_RDPHalf_1 );
589 	GBI_SetGBI( G_RDPHALF_2,			F3D_RDPHALF_2,			F3D_RDPHalf_2 );
590 	GBI_SetGBI( G_RDPHALF_CONT,			F3D_RDPHALF_CONT,		F3D_RDPHalf_Cont );
591 
592 	GBI_SetGBI( G_ZOBJ,					G_ZS_ZOBJ,				ZSort_Obj );
593 	GBI_SetGBI( G_ZRDPCMD,				G_ZS_RDPCMD,			ZSort_RDPCMD );
594 	GBI_SetGBI( G_MOVEMEM,				G_ZS_MOVEMEM,			ZSort_MoveMem );
595 	GBI_SetGBI( G_ZSENDSIGNAL,			G_ZS_SENDSIGNAL,		ZSort_SendSignal );
596 	GBI_SetGBI( G_ZWAITSIGNAL,			G_ZS_WAITSIGNAL,		ZSort_WaitSignal );
597 	GBI_SetGBI( G_ZSETSUBDL,			G_ZS_SETSUBDL,			ZSort_SetSubDL );
598 	GBI_SetGBI( G_ZLINKSUBDL,			G_ZS_LINKSUBDL,			ZSort_LinkSubDL );
599 	GBI_SetGBI( G_ZMULT_MPMTX,			G_ZS_MULT_MPMTX,		ZSort_MultMPMTX );
600 	GBI_SetGBI( G_ZMTXCAT,				G_ZS_MTXCAT,			ZSort_MTXCAT );
601 	GBI_SetGBI( G_ZMTXTRNSP,			G_ZS_MTXTRNSP,			ZSort_MTXRNSP );
602 	GBI_SetGBI( G_ZLIGHTING_L,			G_ZS_LIGHTING_L,		ZSort_LightingL );
603 	GBI_SetGBI( G_ZLIGHTING,			G_ZS_LIGHTING,			ZSort_Lighting );
604 	GBI_SetGBI( G_ZXFMLIGHT,			G_ZS_XFMLIGHT,			ZSort_XFMLight );
605 	GBI_SetGBI( G_ZINTERPOLATE,			G_ZS_INTERPOLATE,		ZSort_Interpolate );
606 }
607