mirror of
https://github.com/aap/librw.git
synced 2026-08-10 09:37:04 +01:00
merge initial ps2 rendering support from other project
This commit is contained in:
+28
-23
@@ -63,8 +63,8 @@ workspace "librw"
|
||||
filter "configurations:Release*"
|
||||
defines { "NDEBUG" }
|
||||
optimize "On"
|
||||
filter "configurations:ReleaseStatic"
|
||||
staticruntime("On")
|
||||
-- filter "configurations:ReleaseStatic"
|
||||
-- staticruntime("On")
|
||||
|
||||
filter { "platforms:*null" }
|
||||
defines { "RW_NULL" }
|
||||
@@ -119,6 +119,16 @@ workspace "librw"
|
||||
Libdir = "lib/%{cfg.platform}/%{cfg.buildcfg}"
|
||||
Bindir = "bin/%{cfg.platform}/%{cfg.buildcfg}"
|
||||
|
||||
function vucode()
|
||||
filter "files:**.dsm"
|
||||
buildmessage 'dvp-as %{file.name}'
|
||||
buildcommands {
|
||||
'cpp -x assembler-with-cpp "%{file.abspath}" | ee-dvp-as -I "%{file.directory}" -o "%{cfg.objdir}/%{file.basename}.o"'
|
||||
}
|
||||
buildoutputs { '%{cfg.objdir}/%{file.basename}.o' }
|
||||
filter {}
|
||||
end
|
||||
|
||||
project "librw"
|
||||
kind "StaticLib"
|
||||
targetname "rw"
|
||||
@@ -128,6 +138,10 @@ project "librw"
|
||||
files { "src/*/*.*" }
|
||||
filter { "platforms:*gl3" }
|
||||
files { "src/gl/glad/*.*" }
|
||||
filter { "platforms:*ps2" }
|
||||
vucode()
|
||||
files { "src/ps2/vu1/*.dsm" }
|
||||
includedirs { "src/ps2/vu1" }
|
||||
|
||||
project "dumprwtree"
|
||||
kind "ConsoleApp"
|
||||
@@ -194,15 +208,6 @@ function skeltool(dir)
|
||||
findlibs()
|
||||
end
|
||||
|
||||
function vucode()
|
||||
filter "files:**.dsm"
|
||||
buildcommands {
|
||||
'cpp "%{file.relpath}" | dvp-as -o "%{cfg.objdir}/%{file.basename}.o"'
|
||||
}
|
||||
buildoutputs { '%{cfg.objdir}/%{file.basename}.o' }
|
||||
filter {}
|
||||
end
|
||||
|
||||
project "playground"
|
||||
kind "WindowedApp"
|
||||
characterset ("MBCS")
|
||||
@@ -272,18 +277,18 @@ project "ska2anm"
|
||||
findlibs()
|
||||
removeplatforms { "*gl3", "*d3d9", "*ps2" }
|
||||
|
||||
project "ps2test"
|
||||
kind "ConsoleApp"
|
||||
targetdir (Bindir)
|
||||
vucode()
|
||||
removeplatforms { "*gl3", "*d3d9", "*null" }
|
||||
targetextension '.elf'
|
||||
includedirs { "." }
|
||||
files { "tools/ps2test/*.cpp",
|
||||
"tools/ps2test/vu/*.dsm",
|
||||
"tools/ps2test/*.h" }
|
||||
libdirs { "$(PS2SDK)/ee/lib" }
|
||||
links { "librw" }
|
||||
--project "ps2test"
|
||||
-- kind "ConsoleApp"
|
||||
-- targetdir (Bindir)
|
||||
-- vucode()
|
||||
-- removeplatforms { "*gl3", "*d3d9", "*null" }
|
||||
-- targetextension '.elf'
|
||||
-- includedirs { "." }
|
||||
-- files { "tools/ps2test/*.cpp",
|
||||
-- "tools/ps2test/vu/*.dsm",
|
||||
-- "tools/ps2test/*.h" }
|
||||
-- libdirs { "$(PS2SDK)/ee/lib" }
|
||||
-- links { "librw" }
|
||||
|
||||
--project "ps2rastertest"
|
||||
-- kind "ConsoleApp"
|
||||
|
||||
@@ -948,6 +948,9 @@ ObjPipeline::init(void)
|
||||
this->groupPipeline = nil;
|
||||
this->impl.instance = objInstance;
|
||||
this->impl.uninstance = objUninstance;
|
||||
#ifdef RW_PS2
|
||||
this->impl.render = defaultAtomicRender;
|
||||
#endif
|
||||
}
|
||||
|
||||
ObjPipeline*
|
||||
|
||||
+1172
-11
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,124 @@
|
||||
#ifdef RW_PS2
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "../rwbase.h"
|
||||
|
||||
#include <sifdev.h>
|
||||
|
||||
struct FILE_PS2
|
||||
{
|
||||
int used;
|
||||
int fd;
|
||||
int pos;
|
||||
int size;
|
||||
};
|
||||
FILE_PS2 ps2files[64];
|
||||
|
||||
/* file functions */
|
||||
|
||||
void*
|
||||
ps2fopen(const char *path, const char *mode)
|
||||
{
|
||||
int flags = 0;
|
||||
int fd;
|
||||
int i;
|
||||
char *r, *w, *plus;
|
||||
|
||||
// printf("trying to open <%s> mode <%s>\n", path, mode);
|
||||
for(i = 0; i < nelem(ps2files); i++){
|
||||
if(!ps2files[i].used)
|
||||
goto found;
|
||||
}
|
||||
// no file pointer available
|
||||
return nil;
|
||||
found:
|
||||
|
||||
r = strchr(mode, 'r');
|
||||
w = strchr(mode, 'w');
|
||||
plus = strchr(mode, '+');
|
||||
|
||||
if(plus)
|
||||
flags = SCE_RDWR;
|
||||
else if(r)
|
||||
flags = SCE_RDONLY;
|
||||
else if(w)
|
||||
flags = SCE_WRONLY;
|
||||
|
||||
if(w)
|
||||
flags |= SCE_CREAT | SCE_TRUNC;
|
||||
|
||||
fd = sceOpen(path, flags);
|
||||
if(fd < 0)
|
||||
return nil;
|
||||
|
||||
ps2files[i].used = 1;
|
||||
ps2files[i].fd = fd;
|
||||
ps2files[i].pos = 0;
|
||||
if(w){
|
||||
ps2files[i].size = 0;
|
||||
}else{
|
||||
ps2files[i].size = sceLseek(fd, 0, SCE_SEEK_END);
|
||||
sceLseek(fd, 0, SCE_SEEK_SET);
|
||||
}
|
||||
return &ps2files[i];
|
||||
}
|
||||
|
||||
int
|
||||
ps2fclose(void *fp)
|
||||
{
|
||||
FILE_PS2 *f = (FILE_PS2*)fp;
|
||||
if(!f->used)
|
||||
return EOF;
|
||||
sceClose(f->fd);
|
||||
f->used = 0;
|
||||
f->fd = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ps2fseek(void *fp, long offset, int whence)
|
||||
{
|
||||
FILE_PS2 *f = (FILE_PS2*)fp;
|
||||
f->pos = sceLseek(f->fd, offset, whence);
|
||||
return f->pos;
|
||||
}
|
||||
|
||||
long
|
||||
ps2ftell(void *fp)
|
||||
{
|
||||
FILE_PS2 *f = (FILE_PS2*)fp;
|
||||
return f->pos;
|
||||
}
|
||||
|
||||
size_t
|
||||
ps2fread(void *ptr, size_t size, size_t nmemb, void *fp)
|
||||
{
|
||||
FILE_PS2 *f = (FILE_PS2*)fp;
|
||||
int n = sceRead(f->fd, ptr, size*nmemb);
|
||||
f->pos += n;
|
||||
return n/size;
|
||||
}
|
||||
|
||||
size_t
|
||||
ps2fwrite(const void *ptr, size_t size, size_t nmemb, void *fp)
|
||||
{
|
||||
FILE_PS2 *f = (FILE_PS2*)fp;
|
||||
int n = sceWrite(f->fd, ptr, size*nmemb);
|
||||
f->pos += n;
|
||||
if(f->pos > f->size)
|
||||
f->size = f->pos;
|
||||
return n/size;
|
||||
}
|
||||
|
||||
int
|
||||
ps2feof(void *fp)
|
||||
{
|
||||
FILE_PS2 *f = (FILE_PS2*)fp;
|
||||
return f->pos >= f->size;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,7 @@
|
||||
void *ps2fopen(const char *path, const char *mode);
|
||||
int ps2fclose(void *fp);
|
||||
int ps2fseek(void *fp, long offset, int whence);
|
||||
long ps2ftell(void *fp);
|
||||
size_t ps2fread(void *ptr, size_t size, size_t nmemb, void *fp);
|
||||
size_t ps2fwrite(const void *ptr, size_t size, size_t nmemb, void *fp);
|
||||
int ps2feof(void *fp);
|
||||
@@ -0,0 +1,345 @@
|
||||
#ifdef RW_PS2
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "../rwbase.h"
|
||||
#include "../rwerror.h"
|
||||
#include "../rwplg.h"
|
||||
#include "../rwrender.h"
|
||||
#include "../rwpipeline.h"
|
||||
#include "../rwobjects.h"
|
||||
#include "../rwengine.h"
|
||||
#include "../rwanim.h"
|
||||
#include "../rwplugins.h"
|
||||
#include "rwps2.h"
|
||||
#include "rwps2plg.h"
|
||||
|
||||
#include "rwps2impl.h"
|
||||
|
||||
#include <eestruct.h>
|
||||
|
||||
#define PLUGIN_ID 2
|
||||
|
||||
extern rw::ps2::VUdesc vu1_im3d_desc[7];
|
||||
extern rw::ps2::VUdesc vu1_im2d_desc[2];
|
||||
extern rw::uint32 vu1_im2d[];
|
||||
extern rw::uint32 vu1_im3d[];
|
||||
|
||||
namespace rw {
|
||||
namespace ps2 {
|
||||
|
||||
struct BatchInfo
|
||||
{
|
||||
uint32 numBatches;
|
||||
uint32 batchSize;
|
||||
int32 repeat;
|
||||
};
|
||||
|
||||
int
|
||||
prologue(BatchInfo *bi, PrimitiveType type, int32 numVerts)
|
||||
{
|
||||
// 2 words for GIF tags, 2 input and output buffers, 3 qw per vertex
|
||||
bi->batchSize = (vuMatrix - 2)/(2*3 + 2*3);
|
||||
int primsz = primSize[type];
|
||||
bi->repeat = primRepeat[type];
|
||||
int numPrims = 0;
|
||||
int numPrimsBatch = 0;
|
||||
switch(type){
|
||||
case PRIMTYPEPOINTLIST:
|
||||
case PRIMTYPELINELIST:
|
||||
case PRIMTYPETRILIST:
|
||||
numPrims = numVerts/primsz;
|
||||
numPrimsBatch = bi->batchSize/primsz;
|
||||
numPrimsBatch &= ~3;
|
||||
bi->batchSize = numPrimsBatch*primsz;
|
||||
break;
|
||||
case PRIMTYPEPOLYLINE:
|
||||
case PRIMTYPETRISTRIP:
|
||||
case PRIMTYPETRIFAN:
|
||||
numPrims = numVerts - bi->repeat;
|
||||
bi->batchSize &= ~3;
|
||||
numPrimsBatch = bi->batchSize - bi->repeat;
|
||||
break;
|
||||
}
|
||||
// nothing to draw
|
||||
if(bi->batchSize < primSize[type])
|
||||
return 1;
|
||||
|
||||
bi->numBatches = (numPrims + numPrimsBatch-1) / numPrimsBatch;
|
||||
|
||||
uploadRaster(rwStateCache.raster);
|
||||
setTexture(rwStateCache.raster, rwStateCache.addressU, rwStateCache.addressV, rwStateCache.filterMode);
|
||||
|
||||
flushGSRegs();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
prologue2d(BatchInfo *bi, PrimitiveType type, int32 numVerts)
|
||||
{
|
||||
uint128 tmp;
|
||||
|
||||
prologue(bi, type, numVerts);
|
||||
|
||||
uploadVUCode(vu1_im2d);
|
||||
|
||||
// DMAcnt for everything
|
||||
int dmasz = 8 // general VIF unpacks
|
||||
+ 3*(numVerts + (bi->numBatches-1)*bi->repeat) // vertices
|
||||
+ bi->numBatches*2; // batch prolog and epilog
|
||||
assert(dmasz <= 0xFFFF);
|
||||
MAKEQ(tmp, VIFflush, VIFflush, 0, DMAcnt + dmasz);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
|
||||
// some uploads and double buffer
|
||||
uint32 offset = bi->batchSize*3;
|
||||
MAKEQ(tmp, UNPACK(V4_32, 2, vuXyzwScale), STCYCL(4,4), VIFoffset + offset, VIFbase + 0);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
vifPacket[vifPacksz++] = vuConst.xyzwScale_2D;
|
||||
vifPacket[vifPacksz++] = vuConst.xyzwOffset_2D;
|
||||
|
||||
MAKEQ(tmp, UNPACK(V4_32, 2, vuGifTag), STCYCL(4,4), VIFnop, VIFnop);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
MAKE128(tmp, 0x412, SCE_GIF_SET_TAG(0, 1, 1,rw2gsPrim[type], SCE_GIF_PACKED, 3));
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
vifPacket[vifPacksz++] = (rwStateCache.raster == nil || doModulate2) ? colorNoScale : colorTexScale;
|
||||
|
||||
MAKEQ(tmp, UNPACK(V4_32, 1, vuVuSwitch), STCYCL(4,4), VIFnop, VIFnop);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
VUdesc *desc = rwStateCache.fogEnable ? &vu1_im2d_desc[1] : &vu1_im2d_desc[0];
|
||||
MAKEQ(tmp, 0, 0, 0, desc->process>>3);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
prologue3d(BatchInfo *bi, PrimitiveType type, int32 numVerts)
|
||||
{
|
||||
uint128 tmp;
|
||||
|
||||
prologue(bi, type, numVerts);
|
||||
|
||||
uploadVUCode(vu1_im3d);
|
||||
|
||||
// DMAcnt for everything
|
||||
int dmasz = 13 // general VIF unpacks
|
||||
+ 3*(numVerts + (bi->numBatches-1)*bi->repeat) // vertices
|
||||
+ bi->numBatches*2; // batch prolog and epilog
|
||||
assert(dmasz <= 0xFFFF);
|
||||
MAKEQ(tmp, VIFflush, VIFflush, 0, DMAcnt + dmasz);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
|
||||
// some uploads and double buffer
|
||||
uint32 offset = bi->batchSize*3;
|
||||
MAKEQ(tmp, UNPACK(V4_32, 7, vuMatrix), STCYCL(4,4), VIFoffset + offset, VIFbase + 0);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
vifPacket[vifPacksz++] = vuConst.mat0;
|
||||
vifPacket[vifPacksz++] = vuConst.mat1;
|
||||
vifPacket[vifPacksz++] = vuConst.mat2;
|
||||
vifPacket[vifPacksz++] = vuConst.mat3;
|
||||
vifPacket[vifPacksz++] = vuConst.xyzwScale_3D;
|
||||
vifPacket[vifPacksz++] = vuConst.xyzwOffset_3D;
|
||||
vifPacket[vifPacksz++] = vuConst.clipConsts;
|
||||
|
||||
MAKEQ(tmp, UNPACK(V4_32, 2, vuGifTag), STCYCL(4,4), VIFnop, VIFnop);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
MAKE128(tmp, 0x412, SCE_GIF_SET_TAG(0, 1, 1,rw2gsPrim[type], SCE_GIF_PACKED, 3));
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
vifPacket[vifPacksz++] = (rwStateCache.raster == nil || doModulate2) ? colorNoScale : colorTexScale;
|
||||
|
||||
MAKEQ(tmp, UNPACK(V4_32, 1, vuVuSwitch), STCYCL(4,4), VIFnop, VIFnop);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
VUdesc *desc;
|
||||
if(!doClipping)
|
||||
desc = &vu1_im3d_desc[0];
|
||||
else if(type != PRIMTYPETRIFAN && type <= PRIMTYPEPOINTLIST)
|
||||
desc = &vu1_im3d_desc[type];
|
||||
else
|
||||
printf("invalid primitive type\n");
|
||||
MAKEQ(tmp, 0, desc->buf2, desc->buf1, desc->process>>3);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
renderPrim_VU(PrimitiveType type, void *verts, int32 numVerts)
|
||||
{
|
||||
uint128 tmp;
|
||||
BatchInfo bi;
|
||||
|
||||
if(prologue2d(&bi, type, numVerts))
|
||||
return;
|
||||
|
||||
int i, j, vx;
|
||||
Im2DVertex *v;
|
||||
vx = 0;
|
||||
for(i = 0; i < bi.numBatches; i++){
|
||||
int32 vertCount = numVerts;
|
||||
if(vertCount > bi.batchSize)
|
||||
vertCount = bi.batchSize;
|
||||
|
||||
MAKEQ(tmp, UNPACK(V4_32, vertCount*3, 0x8000 + 0), STCYCL(4,4), VIFnop, VIFnop);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
for(j = 0; j < vertCount; j++){
|
||||
if(j == 0 && type == PRIMTYPETRIFAN)
|
||||
v = &((Im2DVertex*)verts)[0];
|
||||
else
|
||||
v = &((Im2DVertex*)verts)[vx];
|
||||
memcpy(&vifPacket[vifPacksz], v, 3*16);
|
||||
vifPacksz += 3;
|
||||
vx++;
|
||||
}
|
||||
uint64 call, flush;
|
||||
if(i == 0)
|
||||
call = UINT64(VIFmscalf + 0, VIFitop + vertCount);
|
||||
else
|
||||
call = UINT64(VIFmscnt, VIFitop + vertCount);
|
||||
if(i == bi.numBatches-1)
|
||||
flush = UINT64(VIFflush, VIFflush);
|
||||
else
|
||||
flush = UINT64(VIFnop, VIFnop);
|
||||
MAKE128(tmp, flush, call);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
|
||||
numVerts -= vertCount;
|
||||
numVerts += bi.repeat;
|
||||
vx -= bi.repeat;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
renderIndexedPrim_VU(PrimitiveType type, void *verts, int32 numVerts, void *indices, int32 numIndices)
|
||||
{
|
||||
uint128 tmp;
|
||||
BatchInfo bi;
|
||||
|
||||
if(prologue2d(&bi, type, numIndices))
|
||||
return;
|
||||
|
||||
int i, j, ix, vx;
|
||||
Im2DVertex *v;
|
||||
ix = 0;
|
||||
for(i = 0; i < bi.numBatches; i++){
|
||||
int32 vertCount = numIndices;
|
||||
if(vertCount > bi.batchSize)
|
||||
vertCount = bi.batchSize;
|
||||
|
||||
MAKEQ(tmp, UNPACK(V4_32, vertCount*3, 0x8000 + 0), STCYCL(4,4), VIFnop, VIFnop);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
for(j = 0; j < vertCount; j++){
|
||||
if(j == 0 && type == PRIMTYPETRIFAN)
|
||||
vx = ((uint16*)indices)[0];
|
||||
else
|
||||
vx = ((uint16*)indices)[ix];
|
||||
v = &((Im2DVertex*)verts)[vx];
|
||||
memcpy(&vifPacket[vifPacksz], v, 3*16);
|
||||
vifPacksz += 3;
|
||||
ix++;
|
||||
}
|
||||
uint64 call, flush;
|
||||
if(i == 0)
|
||||
call = UINT64(VIFmscalf + 0, VIFitop + vertCount);
|
||||
else
|
||||
call = UINT64(VIFmscnt, VIFitop + vertCount);
|
||||
if(i == bi.numBatches-1)
|
||||
flush = UINT64(VIFflush, VIFflush);
|
||||
else
|
||||
flush = UINT64(VIFnop, VIFnop);
|
||||
MAKE128(tmp, flush, call);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
|
||||
numIndices -= vertCount;
|
||||
numIndices += bi.repeat;
|
||||
ix -= bi.repeat;
|
||||
}
|
||||
}
|
||||
|
||||
/*********
|
||||
* VU Im3D
|
||||
*********/
|
||||
|
||||
static Im3DVertex *im3dVerts;
|
||||
|
||||
void
|
||||
vuIm3DTransform(void *vertices, int32 numVertices, Matrix *world, uint32 flags)
|
||||
{
|
||||
im3dVerts = (Im3DVertex*)vertices;
|
||||
setMatrix((RawMatrix*)&vuConst.mat0, world);
|
||||
}
|
||||
|
||||
void
|
||||
vuIm3DEnd(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
vuIm3DRenderIndexed(PrimitiveType type, void *indices, int32 numIndices)
|
||||
{
|
||||
uint128 tmp;
|
||||
BatchInfo bi;
|
||||
QWord q;
|
||||
|
||||
if(prologue3d(&bi, type, numIndices))
|
||||
return;
|
||||
|
||||
int i, j, ix, vx;
|
||||
Im3DVertex *v;
|
||||
ix = 0;
|
||||
int first = 1;
|
||||
for(i = 0; i < bi.numBatches; i++){
|
||||
int32 vertCount = numIndices;
|
||||
if(vertCount > bi.batchSize)
|
||||
vertCount = bi.batchSize;
|
||||
|
||||
MAKEQ(tmp, UNPACK(V4_32, vertCount*3, 0x8000 + 0), STCYCL(4,4), VIFnop, VIFnop);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
for(j = 0; j < vertCount; j++){
|
||||
if(j == 0 && type == PRIMTYPETRIFAN)
|
||||
vx = ((uint16*)indices)[0];
|
||||
else
|
||||
vx = ((uint16*)indices)[ix];
|
||||
v = &im3dVerts[vx];
|
||||
q.q_f[0] = v->position.x;
|
||||
q.q_f[1] = v->position.y;
|
||||
q.q_f[2] = v->position.z;
|
||||
q.q_f[3] = 0.0f; // ADC flag
|
||||
vifPacket[vifPacksz++] = q;
|
||||
q.q_f[0] = v->u;
|
||||
q.q_f[1] = v->v;
|
||||
q.q_f[2] = 0.0f;
|
||||
q.q_f[3] = 0.0f;
|
||||
vifPacket[vifPacksz++] = q;
|
||||
ix++;
|
||||
q.q_u32[0] = v->r;
|
||||
q.q_u32[1] = v->g;
|
||||
q.q_u32[2] = v->b;
|
||||
q.q_u32[3] = v->a;
|
||||
vifPacket[vifPacksz++] = q;
|
||||
}
|
||||
uint64 call, flush;
|
||||
if(i == 0)
|
||||
call = UINT64(VIFmscalf + 0, VIFitop + vertCount);
|
||||
else
|
||||
call = UINT64(VIFmscnt, VIFitop + vertCount);
|
||||
if(i == bi.numBatches-1)
|
||||
flush = UINT64(VIFflush, VIFflush);
|
||||
else
|
||||
flush = UINT64(VIFnop, VIFnop);
|
||||
MAKE128(tmp, flush, call);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
|
||||
numIndices -= vertCount;
|
||||
numIndices += bi.repeat;
|
||||
ix -= bi.repeat;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,248 @@
|
||||
#ifdef RW_PS2
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "../rwbase.h"
|
||||
#include "../rwerror.h"
|
||||
#include "../rwplg.h"
|
||||
#include "../rwrender.h"
|
||||
#include "../rwpipeline.h"
|
||||
#include "../rwobjects.h"
|
||||
#include "../rwengine.h"
|
||||
#include "../rwanim.h"
|
||||
#include "../rwplugins.h"
|
||||
#include "rwps2.h"
|
||||
#include "rwps2plg.h"
|
||||
|
||||
#include "rwps2impl.h"
|
||||
|
||||
#define PLUGIN_ID 2
|
||||
|
||||
#include <libgraph.h>
|
||||
|
||||
extern rw::ps2::VUdesc vu1_default_desc[3];
|
||||
extern rw::uint32 vu1_default[];
|
||||
|
||||
|
||||
|
||||
namespace rw {
|
||||
namespace ps2 {
|
||||
|
||||
void
|
||||
uploadLights(WorldLights *lightData, Matrix *worldMat)
|
||||
{
|
||||
int i;
|
||||
uint128 tmp;
|
||||
QWord q;
|
||||
RGBAf *col;
|
||||
V3d localDir;
|
||||
|
||||
int dmasz = 1;
|
||||
if(lightData->numAmbients)
|
||||
dmasz++;
|
||||
dmasz += lightData->numDirectionals*2;
|
||||
|
||||
Matrix lightmat;
|
||||
if(lightData->numDirectionals || lightData->numLocals)
|
||||
Matrix::invert(&lightmat, worldMat);
|
||||
|
||||
assert(dmasz <= 0x3F0-0x3D0);
|
||||
MAKEQ(tmp, UNPACK(V4_32, dmasz, vuLight), STCYCL(4,4), 0, DMAcnt + dmasz);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
|
||||
if(lightData->numAmbients){
|
||||
|
||||
q.q_f[0] = lightData->ambient.red*255.0f;
|
||||
q.q_f[1] = lightData->ambient.green*255.0f;
|
||||
q.q_f[2] = lightData->ambient.blue*255.0f;
|
||||
q.q_u32[3] = 1; // ambient
|
||||
vifPacket[vifPacksz++] = q;
|
||||
}
|
||||
for(i = 0; i < lightData->numDirectionals; i++){
|
||||
Light *l = lightData->directionals[i];
|
||||
col = &l->color;
|
||||
q.q_f[0] = col->red*255.0f;
|
||||
q.q_f[1] = col->green*255.0f;
|
||||
q.q_f[2] = col->blue*255.0f;
|
||||
q.q_u32[3] = 3; // direct
|
||||
vifPacket[vifPacksz++] = q;
|
||||
V3d *dir = &l->getFrame()->getLTM()->at;
|
||||
V3d::transformVectors(&localDir, dir, 1, &lightmat);
|
||||
q.q_f[0] = localDir.x;
|
||||
q.q_f[1] = localDir.y;
|
||||
q.q_f[2] = localDir.z;
|
||||
q.q_f[3] = 0.0f;
|
||||
vifPacket[vifPacksz++] = q;
|
||||
}
|
||||
|
||||
// TODO: local lights
|
||||
|
||||
MAKEQ(tmp, 0, 0, 0, 0);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp; // end
|
||||
}
|
||||
|
||||
void
|
||||
lightingCB(Atomic *atomic)
|
||||
{
|
||||
WorldLights lightData;
|
||||
Light *directionals[8];
|
||||
Light *locals[8];
|
||||
lightData.directionals = directionals;
|
||||
lightData.numDirectionals = 8;
|
||||
lightData.locals = locals;
|
||||
lightData.numLocals = 8;
|
||||
if(atomic->geometry->flags & rw::Geometry::LIGHT){
|
||||
engine->currentWorld->enumerateLights(atomic, &lightData);
|
||||
if((atomic->geometry->flags & rw::Geometry::NORMALS) == 0){
|
||||
// Get rid of lights that need normals when we don't have any
|
||||
lightData.numDirectionals = 0;
|
||||
lightData.numLocals = 0;
|
||||
}
|
||||
return uploadLights(&lightData, atomic->getFrame()->getLTM());
|
||||
}else{
|
||||
memset(&lightData, 0, sizeof(lightData));
|
||||
return uploadLights(&lightData, nil);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
setupAtomic(Atomic *atomic)
|
||||
{
|
||||
uint128 tmp;
|
||||
|
||||
setMatrix((RawMatrix*)&vuConst.mat0, atomic->getFrame()->getLTM());
|
||||
|
||||
lightingCB(atomic);
|
||||
|
||||
MeshHeader *header = atomic->geometry->meshHeader;
|
||||
PrimitiveType type = header->flags == rw::MeshHeader::TRISTRIP ?
|
||||
rw::PRIMTYPETRISTRIP : rw::PRIMTYPETRILIST;
|
||||
uploadVUCode(vu1_default);
|
||||
|
||||
// DMAcnt
|
||||
int dmasz = 12; // general VIF unpacks
|
||||
MAKEQ(tmp, VIFflush, VIFflush, 0, DMAcnt + dmasz);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
|
||||
// some uploads
|
||||
MAKEQ(tmp, UNPACK(V4_32, 7, vuMatrix), STCYCL(4,4), VIFnop, VIFnop);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
vifPacket[vifPacksz++] = vuConst.mat0;
|
||||
vifPacket[vifPacksz++] = vuConst.mat1;
|
||||
vifPacket[vifPacksz++] = vuConst.mat2;
|
||||
vifPacket[vifPacksz++] = vuConst.mat3;
|
||||
vifPacket[vifPacksz++] = vuConst.xyzwScale_3D;
|
||||
vifPacket[vifPacksz++] = vuConst.xyzwOffset_3D;
|
||||
vifPacket[vifPacksz++] = vuConst.clipConsts;
|
||||
|
||||
MAKEQ(tmp, UNPACK(V4_32, 1, vuGifTag), STCYCL(4,4), VIFnop, VIFnop);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
MAKE128(tmp, 0x412, SCE_GIF_SET_TAG(0, 1, 1,rw2gsPrim[type], SCE_GIF_PACKED, 3));
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
|
||||
MAKEQ(tmp, UNPACK(V4_32, 1, vuVuSwitch), STCYCL(4,4), VIFnop, VIFnop);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
VUdesc *desc;
|
||||
if(doClipping){
|
||||
if(type == PRIMTYPETRILIST)
|
||||
desc = &vu1_default_desc[1];
|
||||
else if(type == PRIMTYPETRISTRIP)
|
||||
desc = &vu1_default_desc[2];
|
||||
else
|
||||
printf("invalid primitive type\n");
|
||||
}else
|
||||
desc = &vu1_default_desc[0];
|
||||
MAKEQ(tmp, 0, desc->buf2, desc->buf1, desc->process>>3);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
setupMaterial(Material *mat)
|
||||
{
|
||||
uint128 tmp;
|
||||
QWord q;
|
||||
RGBAf matcol;
|
||||
Texture *tex = mat->texture;
|
||||
|
||||
// TODO: set texture alpha state
|
||||
if(tex)
|
||||
uploadRaster(tex->raster);
|
||||
|
||||
// TODO: no vertex alpha, sad
|
||||
rw::SetRenderState(VERTEXALPHA, mat->color.alpha != 0xFF);
|
||||
|
||||
QWord scale = (tex == nil || doModulate2) ? colorNoScale : colorTexScale;
|
||||
MAKEQ(tmp, UNPACK(V4_32, 2, vuColScale), STCYCL(4,4), 0, DMAcnt + 2);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
|
||||
// material color
|
||||
convColor(&matcol, &mat->color);
|
||||
if(tex){
|
||||
setTexture(tex->raster, tex->getAddressU(), tex->getAddressV(), tex->getFilter());
|
||||
q.q_f[0] = matcol.red*scale.q_f[0];
|
||||
q.q_f[1] = matcol.green*scale.q_f[1];
|
||||
q.q_f[2] = matcol.blue*scale.q_f[2];
|
||||
q.q_f[3] = matcol.alpha*scale.q_f[3];
|
||||
}else{
|
||||
setTexture(nil, 0, 0, 0);
|
||||
q.q_f[0] = matcol.red*scale.q_f[0];
|
||||
q.q_f[1] = matcol.green*scale.q_f[1];
|
||||
q.q_f[2] = matcol.blue*scale.q_f[2];
|
||||
q.q_f[3] = matcol.alpha*scale.q_f[3];
|
||||
}
|
||||
vifPacket[vifPacksz++] = q;
|
||||
|
||||
// surface props
|
||||
q.q_f[0] = mat->surfaceProps.ambient;
|
||||
q.q_f[1] = mat->surfaceProps.specular;
|
||||
q.q_f[2] = mat->surfaceProps.diffuse;
|
||||
q.q_f[3] = 0.0f;
|
||||
vifPacket[vifPacksz++] = q;
|
||||
|
||||
flushGSRegs();
|
||||
}
|
||||
|
||||
void
|
||||
defaultAtomicRender(rw::ObjPipeline *pipe, Atomic *atomic)
|
||||
{
|
||||
int i;
|
||||
uint128 tmp;
|
||||
ObjPipeline *op = (ObjPipeline*)pipe;
|
||||
|
||||
Geometry *geo = atomic->geometry;
|
||||
op->instance(atomic);
|
||||
assert(geo->instData != nil);
|
||||
assert(geo->instData->platform == PLATFORM_PS2);
|
||||
|
||||
InstanceDataHeader *instData = (InstanceDataHeader*)geo->instData;
|
||||
MeshHeader *header = geo->meshHeader;
|
||||
|
||||
setupAtomic(atomic);
|
||||
|
||||
for(i = 0; i < instData->numMeshes; i++){
|
||||
Material *mat = instData->instanceMeshes[i].material;
|
||||
MatPipeline *mp = op->groupPipeline;
|
||||
if(mp == nil)
|
||||
mp = (MatPipeline*)mat->pipeline;
|
||||
if(mp == nil)
|
||||
mp = defaultMatPipe;
|
||||
|
||||
// TODO: this should be a method of the pipeline
|
||||
setupMaterial(mat);
|
||||
|
||||
// call geometry
|
||||
MAKEQ(tmp, VIFoffset+mp->vifOffset, VIFbase + 0, (uint32)instData->instanceMeshes[i].data, DMAcall);
|
||||
vifPacket[vifPacksz++].q_u128 = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,63 @@
|
||||
#ifdef RW_PS2
|
||||
|
||||
#include <eetypes.h>
|
||||
|
||||
typedef char int8_t;
|
||||
typedef short int16_t;
|
||||
typedef int int32_t;
|
||||
typedef long long int64_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
typedef unsigned int uintptr_t;
|
||||
typedef u_long128 uint128_t;
|
||||
|
||||
typedef union QWord QWord;
|
||||
union QWord {
|
||||
u_long128 q_u128;
|
||||
u_long q_u64[2];
|
||||
u_int q_u32[4];
|
||||
float q_f[4];
|
||||
};
|
||||
|
||||
#define MAKE128(RES,MSB,LSB) \
|
||||
__asm__ ( "pcpyld %0, %1, %2" : "=r" (RES) : "r" ((uint64)MSB), "r" ((uint64)LSB))
|
||||
#define UINT64(HIGH,LOW) (((uint64)(uint32)HIGH)<<32 | ((uint64)(uint32)LOW))
|
||||
#define MAKEQ(RES,W3,W2,W1,W0) MAKE128(RES,UINT64(W3,W2),UINT64(W1,W0))
|
||||
|
||||
enum {
|
||||
IntFlg = 0x80000000,
|
||||
|
||||
DMAcnt = 0x10000000,
|
||||
DMAref = 0x30000000,
|
||||
DMAcall = 0x50000000,
|
||||
DMAret = 0x60000000,
|
||||
DMAend = 0x70000000,
|
||||
|
||||
VIFnop = 0,
|
||||
VIFoffset = 0x02000000,
|
||||
VIFbase = 0x03000000,
|
||||
VIFitop = 0x04000000,
|
||||
VIFstmod = 0x05000000,
|
||||
VIFmskpath3 = 0x06008000,
|
||||
VIFunmskpath3 = 0x06000000,
|
||||
VIFmark = 0x07000000,
|
||||
VIFflushe = 0x10000000,
|
||||
VIFflush = 0x11000000,
|
||||
VIFflusha = 0x13000000,
|
||||
VIFmscal = 0x14000000,
|
||||
VIFmscalf = 0x15000000,
|
||||
VIFmscnt = 0x17000000,
|
||||
VIFstmask = 0x20000000,
|
||||
VIFstrow = 0x30000000,
|
||||
VIFstcol = 0x31000000,
|
||||
VIFdirect = 0x50000000,
|
||||
|
||||
V4_32 = 0x6C
|
||||
};
|
||||
|
||||
#define UNPACK(type, nq, offset) ((type)<<24 | (nq)<<16 | (offset))
|
||||
#define STCYCL(WL,CL) (0x01000000 | (WL)<<8 | (CL))
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
typedef struct GsDispCtx GsDispCtx;
|
||||
struct GsDispCtx
|
||||
{
|
||||
// two circuits
|
||||
uint64_t pmode;
|
||||
uint64_t dispfb1;
|
||||
uint64_t dispfb2;
|
||||
uint64_t display1;
|
||||
uint64_t display2;
|
||||
uint64_t bgcolor;
|
||||
};
|
||||
|
||||
typedef struct GsDrawCtx GsDrawCtx;
|
||||
struct GsDrawCtx
|
||||
{
|
||||
//two contexts
|
||||
uint128_t gifTag;
|
||||
uint64_t frame1;
|
||||
uint64_t ad_frame1;
|
||||
uint64_t frame2;
|
||||
uint64_t ad_frame2;
|
||||
uint64_t zbuf1;
|
||||
uint64_t ad_zbuf1;
|
||||
uint64_t zbuf2;
|
||||
uint64_t ad_zbuf2;
|
||||
uint64_t xyoffset1;
|
||||
uint64_t ad_xyoffset1;
|
||||
uint64_t xyoffset2;
|
||||
uint64_t ad_xyoffset2;
|
||||
uint64_t scissor1;
|
||||
uint64_t ad_scissor1;
|
||||
uint64_t scissor2;
|
||||
uint64_t ad_scissor2;
|
||||
};
|
||||
|
||||
typedef struct GsCtx GsCtx;
|
||||
struct GsCtx
|
||||
{
|
||||
// display context; two buffers
|
||||
GsDispCtx disp[2];
|
||||
// draw context; two buffers
|
||||
GsDrawCtx draw[2];
|
||||
};
|
||||
|
||||
typedef struct GsCrtState GsCrtState;
|
||||
struct GsCrtState
|
||||
{
|
||||
int16_t inter, mode, ff;
|
||||
};
|
||||
|
||||
void GsSetDisp(GsDispCtx *disp);
|
||||
void GsSetDraw(GsDrawCtx *draw);
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
#ifdef RW_PS2
|
||||
#include "ps2types.h"
|
||||
#include "ps2file.h"
|
||||
#endif
|
||||
|
||||
namespace rw {
|
||||
|
||||
#ifdef RW_PS2
|
||||
@@ -277,5 +282,44 @@ Texture *readNativeTexture(Stream *stream);
|
||||
void writeNativeTexture(Texture *tex, Stream *stream);
|
||||
uint32 getSizeNativeTexture(Texture *tex);
|
||||
|
||||
|
||||
|
||||
#ifdef RW_PS2
|
||||
// Real hardware
|
||||
// very messy atm
|
||||
|
||||
void dmaFlip(int i);
|
||||
void dmaKick(void);
|
||||
|
||||
extern rw::uint32 gifPacksz, gifBufSize;
|
||||
extern rw::uint32 vifPacksz, vifBufSize;
|
||||
extern QWord *gifPacket, *vifPacket;
|
||||
|
||||
|
||||
extern int path2Textures;
|
||||
extern int synchTextures;
|
||||
extern int gateTextures;
|
||||
|
||||
extern int finishCycle;
|
||||
|
||||
extern int32 doClipping;
|
||||
extern int32 doModulate2;
|
||||
|
||||
extern QWord colorNoScale;
|
||||
extern QWord colorTexScale;
|
||||
|
||||
void beginFrame(int frame);
|
||||
void endFrame(float *t1, float *t2);
|
||||
|
||||
void uploadRaster(Raster *raster);
|
||||
void setTexture(Raster *raster, uint32 addressU, uint32 addressV, uint32 filterMode);
|
||||
void flushGSRegs(void);
|
||||
void uploadVUCode(uint32 *code);
|
||||
void setMatrix(RawMatrix *combined, Matrix *world);
|
||||
|
||||
void defaultAtomicRender(rw::ObjPipeline *pipe, Atomic *atomic);
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,104 @@
|
||||
// lower level stuff
|
||||
|
||||
// this should go elsewhere
|
||||
//#define PAL
|
||||
#define SCREEN_WIDTH 640
|
||||
#ifdef PAL
|
||||
#define SCREEN_HEIGHT 512
|
||||
#define VIDEOMODE SCE_GS_PAL
|
||||
#else
|
||||
#define SCREEN_HEIGHT 448
|
||||
#define VIDEOMODE SCE_GS_NTSC
|
||||
#endif
|
||||
|
||||
|
||||
// RW proper
|
||||
|
||||
namespace rw {
|
||||
|
||||
#ifdef RW_PS2
|
||||
typedef uint128_t uint128;
|
||||
#endif
|
||||
|
||||
namespace ps2 {
|
||||
|
||||
#ifdef RW_PS2
|
||||
|
||||
struct VUdesc
|
||||
{
|
||||
uint32 process, buf1, buf2, buf3;
|
||||
};
|
||||
|
||||
|
||||
extern int rw2gsPrim[];
|
||||
extern int primSize[];
|
||||
extern int primRepeat[];
|
||||
|
||||
struct RwStateCache {
|
||||
Raster *raster;
|
||||
uint32 addressU;
|
||||
uint32 addressV;
|
||||
uint32 filterMode;
|
||||
|
||||
bool32 vertexAlpha;
|
||||
uint32 alphaTestEnable;
|
||||
uint32 alphaFunc;
|
||||
bool32 textureAlpha;
|
||||
bool32 blendEnable;
|
||||
uint32 srcblend, destblend;
|
||||
uint32 zwrite;
|
||||
uint32 ztest;
|
||||
uint32 cullmode;
|
||||
uint32 fogEnable;
|
||||
float32 fogStart;
|
||||
float32 fogEnd;
|
||||
};
|
||||
extern RwStateCache rwStateCache;
|
||||
|
||||
enum {
|
||||
vuLight = 0x3D0,
|
||||
vuMatrix = 0x3F0,
|
||||
vuXyzwScale = 0x3F4,
|
||||
vuXyzwOffset = 0x3F5,
|
||||
vuClipConsts = 0x3F6,
|
||||
|
||||
vuGifTag = 0x3FA,
|
||||
vuColScale = 0x3FB,
|
||||
vuSurfProps = 0x3FC,
|
||||
vuVuSwitch = 0x3FF
|
||||
};
|
||||
|
||||
struct VuConst {
|
||||
QWord mat0, mat1, mat2, mat3;
|
||||
QWord xyzwScale_2D;
|
||||
QWord xyzwOffset_2D;
|
||||
QWord xyzwScale_3D;
|
||||
QWord xyzwOffset_3D;
|
||||
QWord clipConsts;
|
||||
|
||||
QWord gifTag;
|
||||
QWord surfProps;
|
||||
QWord vuSwitch;
|
||||
};
|
||||
extern VuConst vuConst;
|
||||
|
||||
|
||||
// The reset should be private
|
||||
|
||||
void renderPrim_VU(PrimitiveType type, void *verts, int32 numVerts);
|
||||
void renderIndexedPrim_VU(PrimitiveType type, void *verts, int32 numVerts, void *indices, int32 numIndices);
|
||||
void vuIm3DTransform(void *vertices, int32 numVertices, Matrix *world, uint32 flags);
|
||||
void vuIm3DRenderIndexed(PrimitiveType type, void *indices, int32 numIndices);
|
||||
void vuIm3DEnd(void);
|
||||
void clearCamera(Camera *cam, RGBA *col, uint32 mode);
|
||||
void beginUpdate(Camera *cam);
|
||||
void endUpdate(Camera *cam);
|
||||
void setRenderState(int32 state, void *pvalue);
|
||||
void *getRenderState(int32 state);
|
||||
int deviceSystem(DeviceReq req, void *arg, int32 n);
|
||||
|
||||
#endif
|
||||
|
||||
Raster *rasterCreate(Raster *raster);
|
||||
uint8 *rasterLock(Raster*, int32 level, int32 lockMode);
|
||||
void rasterUnlock(Raster*, int32 level);
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
nop xtop vi02 ; input pointer
|
||||
nop xitop vi04 ; vertex count
|
||||
LLClipLoop:
|
||||
nop iaddiu vi03,vi00,0 ; clipped vertex count
|
||||
nop iadd vi09,vi00,vi02 ; clipPtr, can do this in-place
|
||||
nop lq vf24,clipConsts(vi00) ; [fogNear, fogFar, near, far]
|
||||
LLClipPrimLoop:
|
||||
nop lq vf01,0+0*numInAttribs(vi02) ; - load pos[0]
|
||||
nop lq vf03,0+1*numInAttribs(vi02) ; - load pos[1]
|
||||
addw.x vf02,vf00,vf00 nop ; make bary1
|
||||
addw.y vf04,vf00,vf00 move.yz vf02,vf00 ; make bary2 - make bary1
|
||||
mulax acc,vf28,vf01 move.xz vf04,vf00 ; xform pos[0] - make bary2
|
||||
madday acc,vf29,vf01 nop
|
||||
maddaz acc,vf30,vf01 iaddiu vi02,vi02,2*numInAttribs ; - next input segment
|
||||
maddw vf01,vf31,vf00 isubiu vi04,vi04,2
|
||||
mulax acc,vf28,vf03 nop ; xform pos[1]
|
||||
madday acc,vf29,vf03 nop
|
||||
maddaz acc,vf30,vf03 nop
|
||||
maddw vf03,vf31,vf00 nop
|
||||
nop nop
|
||||
nop nop
|
||||
clipw.xyz vf01,vf01 nop
|
||||
clipw.xyz vf03,vf03 nop
|
||||
nop nop
|
||||
nop nop
|
||||
nop nop
|
||||
nop fcand vi01,0xFFF ; test if any vert is out of the frustum
|
||||
nop ibeq vi01,vi00,LLClipAllInside ; no, all inside
|
||||
|
||||
;; Call Clipper
|
||||
nop nop ; ClipLine tests clip flags in first instruction!
|
||||
nop bal vi15,ClipLine ; skips return if there is a segment
|
||||
nop nop
|
||||
nop b LLClipNext
|
||||
nop nop
|
||||
|
||||
LLClipNewSeg:
|
||||
;; insert new segment here
|
||||
addx.z vf01,vf00,vf00 lq vf05,1-2*numInAttribs(vi02) ; clear ADC - load st[0]
|
||||
addx.z vf03,vf00,vf00 lq vf06,1-1*numInAttribs(vi02) ; clear ADC - load st[1]
|
||||
nop lq vf07,2-2*numInAttribs(vi02) ; - load rgba[0]
|
||||
nop lq vf08,2-1*numInAttribs(vi02) ; - load rgba[1]
|
||||
mulax acc,vf05,vf02 nop ; interpolate st[0]
|
||||
maddy vf09,vf06,vf02 sq vf01,0+0*numInAttribs(vi09) ; - store clip[0]
|
||||
mulax acc,vf07,vf02 nop ; interpolate rgba[0]
|
||||
maddy vf10,vf08,vf02 sq vf03,0+1*numInAttribs(vi09) ; - store clip[1]
|
||||
mulax acc,vf05,vf04 nop ; interpolate st[1]
|
||||
maddy vf11,vf06,vf04 sq vf09,1+0*numInAttribs(vi09) ; - store st[0]
|
||||
mulax acc,vf07,vf04 iaddiu vi03,vi03,2 ; interpolate rgba[1] - inc nClipped
|
||||
maddy vf12,vf08,vf04 sq vf10,2+0*numInAttribs(vi09) ; - store rgba[0]
|
||||
nop iaddiu vi09,vi09,2*numInAttribs
|
||||
nop sq vf11,1-1*numInAttribs(vi09) ; - store st[1]
|
||||
nop b LLClipNext
|
||||
nop sq vf12,2-1*numInAttribs(vi09) ; - store rgba[1]
|
||||
LLClipAllInside:
|
||||
;; segment completely inside
|
||||
addx.z vf01,vf00,vf00 lq vf05,1-2*numInAttribs(vi02) ; clear ADC - load st[0]
|
||||
addx.z vf03,vf00,vf00 lq vf06,1-1*numInAttribs(vi02) ; clear ADC - load st[1]
|
||||
nop lq vf07,2-2*numInAttribs(vi02) ; - load rgba[0]
|
||||
nop lq vf08,2-1*numInAttribs(vi02) ; - load rgba[1]
|
||||
nop sq vf05,1+0*numInAttribs(vi09) ; - store st[0]
|
||||
nop sq vf06,1+1*numInAttribs(vi09) ; - store st[1]
|
||||
nop sq vf07,2+0*numInAttribs(vi09) ; - store rgba[0]
|
||||
nop sq vf08,2+1*numInAttribs(vi09) ; - store rgba[1]
|
||||
nop sq vf01,0+0*numInAttribs(vi09) ; - store clip[0]
|
||||
nop sq vf03,0+1*numInAttribs(vi09) ; - store clip[1]
|
||||
nop iaddiu vi03,vi03,2 ; - inc nClipped
|
||||
nop iaddiu vi09,vi09,2*numInAttribs
|
||||
LLClipNext:
|
||||
nop ibgtz vi04,LLClipPrimLoop ; more input
|
||||
nop nop
|
||||
nop ibeq vi03,vi00,End ; nothing to render
|
||||
nop nop
|
||||
|
||||
;; Process Clip buffer to output buffer and render
|
||||
nop bal vi15,ProcessClip
|
||||
nop xtop vi09
|
||||
nop b End
|
||||
nop nop
|
||||
@@ -0,0 +1,100 @@
|
||||
nop xtop vi02 ; input pointer
|
||||
nop xitop vi04 ; vertex count
|
||||
nop isubiu vi04,vi04,1 ; for linestrip
|
||||
LSClipLoop:
|
||||
nop iaddiu vi03,vi00,0 ; clipped vertex count
|
||||
nop iaddiu vi09,vi00,clipBuf ; clipPtr
|
||||
nop lq vf24,clipConsts(vi00) ; [fogNear, fogFar, near, far]
|
||||
nop iaddiu vi08,vi00,1 ; restartStrip flag
|
||||
LSClipPrimLoop:
|
||||
nop lq vf01,0+0*numInAttribs(vi02) ; - load pos[0]
|
||||
nop lq vf03,0+1*numInAttribs(vi02) ; - load pos[1]
|
||||
addw.x vf02,vf00,vf00 ilw.w vi15,0+1*numInAttribs(vi02) ; make bary1 - load pos[1].w, ADC flag
|
||||
addw.y vf04,vf00,vf00 isubiu vi04,vi04,1 ; make bary2
|
||||
mulax acc,vf28,vf01 nop ; xform pos[0]
|
||||
madday acc,vf29,vf01 ibltz vi04,LSClipRender ; - this could only really happen the first time
|
||||
maddaz acc,vf30,vf01 iaddiu vi02,vi02,numInAttribs ; - next input segment
|
||||
maddw vf01,vf31,vf00 ibne vi15,vi00,LSClipSkip ; - this segment is marked, skip it
|
||||
mulax acc,vf28,vf03 ior vi08,vi08,vi15 ; xform pos[1] - also set restart flag
|
||||
madday acc,vf29,vf03 nop
|
||||
maddaz acc,vf30,vf03 nop
|
||||
maddw vf03,vf31,vf00 nop
|
||||
nop nop
|
||||
nop nop
|
||||
clipw.xyz vf01,vf01 move.yz vf02,vf00 ; - make bary1
|
||||
clipw.xyz vf03,vf03 move.xz vf04,vf00 ; - mark bary2
|
||||
nop nop
|
||||
nop nop
|
||||
nop nop
|
||||
nop fcand vi01,0xFFF ; test if any vert is out of the frustum
|
||||
nop ibeq vi01,vi00,LSClipAllInside ; no, all inside
|
||||
|
||||
;; Call Clipper
|
||||
nop nop ; ClipLine tests clip flags in first instruction!
|
||||
nop bal vi15,ClipLine ; skips return if there is a segment
|
||||
nop nop
|
||||
nop b LSClipSkip
|
||||
nop iaddiu vi08,vi00,1 ; have to restart strip
|
||||
|
||||
LSClipNewSeg:
|
||||
;; insert new segment here
|
||||
nop loi 2048.0
|
||||
addi.z vf01,vf00,i lq vf05,1-1*numInAttribs(vi02) ; set ADC - load st[0
|
||||
addx.z vf03,vf00,vf00 lq vf06,1-0*numInAttribs(vi02) ; clear ADC - load st[1]
|
||||
nop lq vf07,2-1*numInAttribs(vi02) ; - load rgba[0]
|
||||
nop lq vf08,2-0*numInAttribs(vi02) ; - load rgba[1]
|
||||
mulax acc,vf05,vf02 iaddiu vi08,vi00,1 ; interpolate st[0] - have to restart strip
|
||||
maddy vf09,vf06,vf02 sq vf01,0+0*numInAttribs(vi09) ; - store clip[0]
|
||||
mulax acc,vf07,vf02 nop ; interpolate rgba[0]
|
||||
maddy vf10,vf08,vf02 sq vf03,0+1*numInAttribs(vi09) ; - store clip[1]
|
||||
mulax acc,vf05,vf04 nop ; interpolate st[1]
|
||||
maddy vf11,vf06,vf04 sq vf09,1+0*numInAttribs(vi09) ; - store st[0]
|
||||
mulax acc,vf07,vf04 iaddiu vi03,vi03,2 ; interpolate rgba[1] - inc nClipped
|
||||
maddy vf12,vf08,vf04 sq vf10,2+0*numInAttribs(vi09) ; - store rgba[0]
|
||||
nop iaddiu vi09,vi09,2*numInAttribs
|
||||
nop sq vf11,1-1*numInAttribs(vi09) ; - store st[1]
|
||||
nop b LSClipPrimEnd
|
||||
nop sq vf12,2-1*numInAttribs(vi09) ; - store rgba[1]
|
||||
|
||||
LSClipAllInside:
|
||||
nop ibeq vi08,vi00,LSClipContStrip
|
||||
nop loi 2048.0
|
||||
addi.z vf01,vf00,i lq vf05,1-1*numInAttribs(vi02) ; clear ADC - load st[0]
|
||||
nop lq vf07,2-1*numInAttribs(vi02) ; - load rgba[0]
|
||||
nop iaddiu vi03,vi03,1 ; - inc nClipped
|
||||
nop iaddiu vi09,vi09,numInAttribs
|
||||
nop sq vf05,1-1*numInAttribs(vi09) ; - store st[0]
|
||||
nop sq vf07,2-1*numInAttribs(vi09) ; - store rgba[0]
|
||||
nop sq vf01,0-1*numInAttribs(vi09) ; - store clip[0]
|
||||
LSClipContStrip:
|
||||
addx.z vf03,vf00,vf00 lq vf06,1-0*numInAttribs(vi02) ; clear ADC - load st[1]
|
||||
nop lq vf08,2-0*numInAttribs(vi02) ; - load rgba[1]
|
||||
nop iaddiu vi03,vi03,1 ; - inc nClipped
|
||||
nop iaddiu vi09,vi09,numInAttribs
|
||||
nop sq vf06,1-1*numInAttribs(vi09) ; - store st[1]
|
||||
nop sq vf08,2-1*numInAttribs(vi09) ; - store rgba[1]
|
||||
nop sq vf03,0-1*numInAttribs(vi09) ; - store clip[1]
|
||||
nop iaddiu vi08,vi00,0 ; we'll be in a strip after this
|
||||
|
||||
LSClipPrimEnd:
|
||||
;; TODO: don't use clipVertLimitTS
|
||||
nop isubiu vi15,vi03,clipVertLimitTS ; can we overflow next time?
|
||||
nop nop
|
||||
nop ibgtz vi15,LSClipRender ; yes, have to render
|
||||
LSClipSkip:
|
||||
nop nop
|
||||
nop ibgtz vi04,LSClipPrimLoop ; next segment
|
||||
nop nop
|
||||
LSClipRender:
|
||||
nop ibeq vi03,vi00,End ; nothing to render
|
||||
nop nop
|
||||
|
||||
;; Process Clip buffer to output buffer and render
|
||||
nop bal vi15,ProcessClip
|
||||
nop iaddiu vi09,vi00,clipBuf
|
||||
|
||||
nop iblez vi04,End ; no more verts to process
|
||||
nop nop
|
||||
nop b LSClipLoop ; next batch
|
||||
nop nop
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
nop xtop vi02 ; input pointer
|
||||
nop xitop vi04 ; vertex count
|
||||
nop lq vf10,0(vi02) ; load pos
|
||||
nop iadd vi03,vi00,vi00 ; nClipped
|
||||
nop iadd vi09,vi00,vi02 ; we're culling in-place
|
||||
mulaw acc,vf31,vf00 nop
|
||||
PCullLoop:
|
||||
maddax acc,vf28,vf10 lq vf02,1(vi02) ; xform pos - load st
|
||||
madday acc,vf29,vf10 lq vf03,2(vi02) ; - load rgba
|
||||
maddz vf01,vf30,vf10 nop
|
||||
nop iaddiu vi02,vi02,numInAttribs
|
||||
nop isubiu vi04,vi04,1
|
||||
nop lq vf10,0(vi02) ; load next pos
|
||||
clipw.xyz vf01,vf01 nop ; check if clipped
|
||||
addx.z vf01,vf00,vf00 nop ; clear ADC
|
||||
nop nop
|
||||
mulaw acc,vf31,vf00 nop
|
||||
nop fcand vi01,0x3F ; test if vert is out of the frustum
|
||||
nop ibne vi01,vi00,PCullSkip ; yup, skip it
|
||||
nop sq vf01,0(vi09) ; - store clip
|
||||
nop sq vf02,1(vi09) ; - store st
|
||||
nop sq vf03,2(vi09) ; - store rgba
|
||||
nop iaddiu vi03,vi03,1 ; - inc nClipped
|
||||
nop iaddiu vi09,vi09,numInAttribs
|
||||
PCullSkip:
|
||||
nop ibne vi04,vi00,PCullLoop ; more input
|
||||
nop nop
|
||||
nop ibeq vi03,vi00,End ; nothing to render
|
||||
nop nop
|
||||
|
||||
;; Process Clip buffer to output buffer and render
|
||||
nop bal vi15,ProcessClip
|
||||
nop xtop vi09
|
||||
nop b End
|
||||
nop nop
|
||||
@@ -0,0 +1,182 @@
|
||||
;;; Triangle List clipping
|
||||
;;; Process input buffer to Clipping buffer
|
||||
;;; flush Clipping buffer whenever it gets full
|
||||
; vi01
|
||||
; vi02 input buffer have to save this
|
||||
; vi03 nClipped
|
||||
; vi04 nVerts have to save this
|
||||
; vi05 polyInPtr
|
||||
; vi06 polyInEnd
|
||||
; vi07 polyOutPtr
|
||||
; vi08
|
||||
; vi09 clipPtr
|
||||
; vi10 polyBuf1
|
||||
; vi11 polyBuf2
|
||||
; vi12
|
||||
; vi15
|
||||
nop xtop vi02 ; input pointer
|
||||
nop xitop vi04 ; vertex count
|
||||
TLClipLoop:
|
||||
nop iaddiu vi03,vi00,0 ; clipped vertex count
|
||||
nop iaddiu vi09,vi00,clipBuf ; clipPtr
|
||||
nop iadd vi10,vi00,vi12 ; polyBuf1
|
||||
nop iaddiu vi11,vi10,2*10 ; polyBuf2, need some space for trailing junk
|
||||
nop lq vf24,clipConsts(vi00) ; [fogNear, fogFar, near, far]
|
||||
TLClipPrimLoop:
|
||||
;; We have two polygon buffers (at vi10 and vi11).
|
||||
;; For every clipping plane, clip polygon in one and generate new poly in the other
|
||||
nop iadd vi05,vi00,vi10 ; polyInPtr
|
||||
nop iaddiu vi06,vi05,6 ; polyInEnd
|
||||
nop iadd vi07,vi00,vi11 ; polyOutPtr
|
||||
|
||||
;; init polygon buffer
|
||||
nop lq vf01,0+0*numInAttribs(vi02) ; - load pos[0]
|
||||
nop ilw.w vi15,0+2*numInAttribs(vi02) ; - load pos[2].w, ADC flag
|
||||
nop lq vf02,0+1*numInAttribs(vi02) ; - load pos[1]
|
||||
nop lq vf03,0+2*numInAttribs(vi02) ; - load pos[2]
|
||||
mulax acc,vf28,vf01 nop ; xform pos[0]
|
||||
madday acc,vf29,vf01 nop
|
||||
maddaz acc,vf30,vf01 iaddiu vi02,vi02,3*numInAttribs ; - next input triangle
|
||||
maddw vf01,vf31,vf00 isubiu vi04,vi04,3
|
||||
mulax acc,vf28,vf02 nop ; xform pos[1]
|
||||
madday acc,vf29,vf02 ibltz vi04,TLClipRender
|
||||
maddaz acc,vf30,vf02 mr32 vf06,vf00 ; - make bary[2]
|
||||
maddw vf02,vf31,vf00 sq vf01,0(vi05) ; - store pos[0] in polybuf
|
||||
mulax acc,vf28,vf03 ibne vi15,vi00,TLClipSkip ; xform pos[2] - this tri is marked, skip it
|
||||
madday acc,vf29,vf03 nop
|
||||
maddaz acc,vf30,vf03 mr32 vf05,vf06 ; - make bary[1]
|
||||
maddw vf03,vf31,vf00 sq vf02,2(vi05) ; - store pos[1] in polybuf
|
||||
; do first clipping test (note we test the first one twice)
|
||||
; note only z-test is valid at this point because w can still be negative
|
||||
clipw.xyz vf01,vf01 nop
|
||||
clipw.xyz vf01,vf01 nop
|
||||
clipw.xyz vf02,vf02 mr32 vf04,vf05 ; - make bary[0]
|
||||
clipw.xyz vf03,vf03 sq vf03,4(vi05) ; - store pos[2] in polybuf
|
||||
nop sq vf06,5(vi05) ; - store bary[2]
|
||||
nop sq vf05,3(vi05) ; - store bary[1]
|
||||
nop sq vf04,1(vi05) ; - store bary[0]
|
||||
nop fcand vi01,0xFFFFFF ; test if any vert is out of the frustum
|
||||
nop ibeq vi01,vi00,TLClipAllInside ; no, all inside
|
||||
|
||||
;; Call Clipper
|
||||
nop nop
|
||||
nop bal vi15,ClipTriangle ; skips return if there is a poly
|
||||
nop nop
|
||||
nop b TLClipSkip
|
||||
nop nop
|
||||
|
||||
TLClipTriangulate:
|
||||
;; interpolate vertices and create new primitives from polygon buffer here
|
||||
;; this depends on the INPUTFORMAT
|
||||
/*
|
||||
v0 = interp(c0);
|
||||
v1 = interp(c1);
|
||||
clipPtr[1] = v1;
|
||||
i = 2;
|
||||
do {
|
||||
vi = interp(ci);
|
||||
i++;
|
||||
clipPtr[0] = v0;
|
||||
clipPtr[2] = vi;
|
||||
clipPtr += 3;
|
||||
if(polyPtr == polyEnd)
|
||||
break;
|
||||
clipPtr[1] = vi;
|
||||
}
|
||||
*/
|
||||
; vf01 - clip[0]
|
||||
; vf02 - bary[0]
|
||||
; vf03 - clip[i]
|
||||
; vf04 - bary[i]
|
||||
; input verts
|
||||
; vf10 - rgba[0]
|
||||
; vf11 - rgba[1]
|
||||
; vf12 - rgba[2]
|
||||
; vf13 - st[0]
|
||||
; vf14 - st[1]
|
||||
; vf15 - st[2]
|
||||
; vf16 - clip rgba[0]
|
||||
; vf17 - clip st[0]
|
||||
; vf18 - clip rgba[n]
|
||||
; vf19 - clip st[n]
|
||||
nop lq vf04,3(vi05) ; - load bary[1]
|
||||
nop ibeq vi05,vi06,TLClipSkip ; - no vertices at all
|
||||
addx.z vf01,vf00,vf00 lq vf10,1-3*numInAttribs(vi02) ; clear ADC - load st[0]
|
||||
addx.z vf03,vf00,vf00 lq vf11,1-2*numInAttribs(vi02) ; clear ADC - load st[1]
|
||||
nop lq vf12,1-1*numInAttribs(vi02) ; - load st[2]
|
||||
nop lq vf13,2-3*numInAttribs(vi02) ; - load rgba[0]
|
||||
mulax acc,vf10,vf04 lq vf14,2-2*numInAttribs(vi02) ; interpolate st[1] - load rgba[1]
|
||||
madday acc,vf11,vf04 lq vf15,2-1*numInAttribs(vi02) ; interpolate st[1] - load rgba[2]
|
||||
maddz vf18,vf12,vf04 lq vf02,1(vi05) ; interpolate st[1] - load bary[0]
|
||||
mulax acc,vf13,vf04 lq.xyw vf03,2(vi05) ; interpolate rgba[1] - load clip[1]
|
||||
madday acc,vf14,vf04 lq.xyw vf01,0(vi05) ; interpolate rgba[1] - load clip[0]
|
||||
maddz vf19,vf15,vf04 iaddiu vi05,vi05,4 ; interpolate rgba[1]
|
||||
mulax acc,vf10,vf02 nop ; interpolate st[0]
|
||||
madday acc,vf11,vf02 sq vf03,0+1*numInAttribs(vi09) ; interpolate st[0] - store clip[1]
|
||||
maddz vf16,vf12,vf02 sq vf18,1+1*numInAttribs(vi09) ; interpolate st[0] - store st[1]
|
||||
mulax acc,vf13,vf02 sq vf19,2+1*numInAttribs(vi09) ; interpolate rgba[0] - store rgba[1]
|
||||
madday acc,vf14,vf02 nop ; interpolate rgba[0]
|
||||
maddz vf17,vf15,vf02 nop ; interpolate rgba[0]
|
||||
TLClipTriLoop:
|
||||
;; write one triangle here
|
||||
nop lq vf04,1(vi05) ; - load bary[i]
|
||||
nop lq.xyw vf03,0(vi05) ; - load clip[i]
|
||||
nop sq vf01,0+0*numInAttribs(vi09) ; - store clip[0]
|
||||
nop sq vf16,1+0*numInAttribs(vi09) ; - store st[0]
|
||||
mulax acc,vf10,vf04 sq vf17,2+0*numInAttribs(vi09) ; interpolate st[i] - store rgba[0]
|
||||
madday acc,vf11,vf04 iaddiu vi05,vi05,2 ; interpolate st[i] - inc polyPtr
|
||||
maddz vf18,vf12,vf04 iaddiu vi03,vi03,3 ; interpolate st[i] - inc nClipped
|
||||
mulax acc,vf13,vf04 nop ; interpolate rgba[i]
|
||||
madday acc,vf14,vf04 nop ; interpolate rgba[i]
|
||||
maddz vf19,vf15,vf04 sq vf03,0+2*numInAttribs(vi09) ; interpolate rgba[i] - store clip[i]
|
||||
nop sq vf18,1+2*numInAttribs(vi09) ; - store st[i]
|
||||
nop iaddiu vi09,vi09,3*numInAttribs ; - inc clipPtr
|
||||
nop ibeq vi05,vi06,TLClipPrimEnd ; - reached the end
|
||||
nop sq vf19,2-1*numInAttribs(vi09) ; - store rgba[i]
|
||||
nop sq vf03,0+1*numInAttribs(vi09) ; - store clip[i]
|
||||
nop sq vf18,1+1*numInAttribs(vi09) ; - store st[i]
|
||||
nop b TLClipTriLoop
|
||||
nop sq vf19,2+1*numInAttribs(vi09) ; - store rgba[i]
|
||||
|
||||
TLClipAllInside:
|
||||
;; copy full triangle
|
||||
;; this depends on the INPUTFORMAT
|
||||
nop lq vf04,1-3*numInAttribs(vi02) ; - load st[0]
|
||||
nop lq vf05,1-2*numInAttribs(vi02) ; - load st[1]
|
||||
nop lq vf06,1-1*numInAttribs(vi02) ; - load st[2]
|
||||
nop lq vf07,2-3*numInAttribs(vi02) ; - load rgba[0]
|
||||
nop lq vf08,2-2*numInAttribs(vi02) ; - load rgba[1]
|
||||
nop lq vf09,2-1*numInAttribs(vi02) ; - load rgba[2]
|
||||
nop sq vf04,1+0*numInAttribs(vi09) ; - store st[0]
|
||||
nop sq vf05,1+1*numInAttribs(vi09) ; - store st[1]
|
||||
addx.z vf01,vf00,vf00 sq vf06,1+2*numInAttribs(vi09) ; clear ADC - store st[2]
|
||||
addx.z vf02,vf00,vf00 sq vf07,2+0*numInAttribs(vi09) ; clear ADC - store rgba[0]
|
||||
addx.z vf03,vf00,vf00 sq vf08,2+1*numInAttribs(vi09) ; clear ADC - store rgba[1]
|
||||
nop sq vf09,2+2*numInAttribs(vi09) ; - store rgba[2]
|
||||
nop sq vf01,0+0*numInAttribs(vi09) ; - store clip[0]
|
||||
nop sq vf02,0+1*numInAttribs(vi09) ; - store clip[1]
|
||||
nop sq vf03,0+2*numInAttribs(vi09) ; - store clip[2]
|
||||
nop iaddiu vi03,vi03,3 ; - inc nClipped
|
||||
nop iaddiu vi09,vi09,3*numInAttribs
|
||||
|
||||
TLClipPrimEnd:
|
||||
nop isubiu vi15,vi03,clipVertLimitTL ; can we overflow next time?
|
||||
nop nop
|
||||
nop ibgtz vi15,TLClipRender ; yes, have to render
|
||||
TLClipSkip:
|
||||
nop nop
|
||||
nop ibgtz vi04,TLClipPrimLoop ; next Triangle
|
||||
nop nop
|
||||
TLClipRender:
|
||||
nop ibeq vi03,vi00,End
|
||||
nop nop
|
||||
|
||||
;; Process Clip buffer to output buffer and render
|
||||
nop bal vi15,ProcessClip
|
||||
nop iaddiu vi09,vi00,clipBuf
|
||||
|
||||
nop iblez vi04,End ; no more verts to process
|
||||
nop nop
|
||||
nop b TLClipLoop ; next batch
|
||||
nop nop
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
;;; Triangle List clipping
|
||||
;;; Process input buffer to Clipping buffer
|
||||
;;; flush Clipping buffer whenever it gets full
|
||||
; vi01
|
||||
; vi02 input buffer have to save this
|
||||
; vi03 nClipped
|
||||
; vi04 nVerts have to save this
|
||||
; vi05 polyInPtr
|
||||
; vi06 polyInEnd
|
||||
; vi07 polyOutPtr
|
||||
; vi08
|
||||
; vi09 clipPtr
|
||||
; vi10 polyBuf1
|
||||
; vi11 polyBuf2
|
||||
; vi12
|
||||
; vi15
|
||||
nop xtop vi02 ; input pointer
|
||||
nop xitop vi04 ; vertex count
|
||||
nop isubiu vi04,vi04,2 ; for tristrip
|
||||
TSClipLoop:
|
||||
nop iaddiu vi03,vi00,0 ; clipped vertex count
|
||||
nop iaddiu vi09,vi00,clipBuf ; clipPtr
|
||||
nop iadd vi10,vi00,vi12 ; polyBuf1
|
||||
nop iaddiu vi11,vi10,2*10 ; polyBuf2, need some space for trailing junk
|
||||
nop lq vf24,clipConsts(vi00) ; [fogNear, fogFar, near, far]
|
||||
nop iaddiu vi08,vi00,1 ; restartStrip flag
|
||||
TSClipPrimLoop:
|
||||
;; We have two polygon buffers (at vi10 and vi11).
|
||||
;; For every clipping plane, clip polygon in one and generate new poly in the other
|
||||
nop iadd vi05,vi00,vi10 ; polyInPtr
|
||||
nop iaddiu vi06,vi05,6 ; polyInEnd
|
||||
nop iadd vi07,vi00,vi11 ; polyOutPtr
|
||||
|
||||
;; init polygon buffer
|
||||
nop lq vf10,0+0*numInAttribs(vi02) ; - load pos[0]
|
||||
nop ilw.w vi15,0+2*numInAttribs(vi02) ; - load pos[2].w, ADC flag
|
||||
nop lq vf11,0+1*numInAttribs(vi02) ; - load pos[1]
|
||||
nop lq vf12,0+2*numInAttribs(vi02) ; - load pos[2]
|
||||
mulax acc,vf28,vf10 isubiu vi04,vi04,1 ; xform pos[0]
|
||||
madday acc,vf29,vf10 iaddiu vi02,vi02,numInAttribs ; - next input triangle
|
||||
maddaz acc,vf30,vf10 ibltz vi04,TSClipRender ; - this could only really happen the first time
|
||||
maddw vf01,vf31,vf00 nop
|
||||
mulax acc,vf28,vf11 ibne vi15,vi00,TSClipSkip ; xform pos[1] - this tri is marked, skip it
|
||||
madday acc,vf29,vf11 ior vi08,vi08,vi15 ; - also set restart flag
|
||||
maddaz acc,vf30,vf11 mr32 vf06,vf00 ; - make bary[2]
|
||||
maddw vf02,vf31,vf00 sq vf01,0(vi05) ; - store pos[0] in polybuf
|
||||
mulax acc,vf28,vf12 nop ; xform pos[2]
|
||||
madday acc,vf29,vf12 nop
|
||||
maddaz acc,vf30,vf12 mr32 vf05,vf06 ; - make bary[1]
|
||||
maddw vf03,vf31,vf00 sq vf02,2(vi05) ; - store pos[1] in polybuf
|
||||
; do first clipping test (note we test the first one twice)
|
||||
; note only z-test is valid at this point because w can still be negative
|
||||
clipw.xyz vf01,vf01 nop
|
||||
clipw.xyz vf01,vf01 nop
|
||||
clipw.xyz vf02,vf02 mr32 vf04,vf05 ; - make bary[0]
|
||||
clipw.xyz vf03,vf03 sq vf03,4(vi05) ; - store pos[2] in polybuf
|
||||
sub.xyz vf13,vf11,vf10 sq vf06,5(vi05) ; get vectors for zero-area test - store bary[2]
|
||||
sub.xyz vf14,vf12,vf10 sq vf05,3(vi05) ; - store bary[1]
|
||||
nop sq vf04,1(vi05) ; - store bary[0]
|
||||
nop fcand vi01,0xFFFFFF ; test if any vert is out of the frustum
|
||||
nop ibeq vi01,vi00,TSClipAllInside ; no, all inside
|
||||
|
||||
;;; TEMP? cull degenerate tris that can become visible from clipping
|
||||
.if 1
|
||||
.if 1
|
||||
opmula.xyz acc,vf13,vf14 iaddiu vi15,vi00,0xE
|
||||
opmsub.xyz vf00,vf14,vf13 nop
|
||||
nop nop
|
||||
nop nop
|
||||
nop nop
|
||||
nop fmand vi01,vi15
|
||||
nop ibeq vi01,vi15,TSClipZeroArea
|
||||
.else ;; less efficient unless maybe it can be inserted above somewhere
|
||||
sub.xyz vf00,vf11,vf10 nop
|
||||
nop nop
|
||||
sub.xyz vf00,vf12,vf10 nop
|
||||
nop iaddiu vi15,vi00,0xE
|
||||
sub.xyz vf00,vf11,vf12 fmand vi01,vi15
|
||||
nop ibeq vi01,vi15,TSClipZeroArea
|
||||
nop fmand vi01,vi15
|
||||
nop ibeq vi01,vi15,TSClipZeroArea
|
||||
nop fmand vi01,vi15
|
||||
nop ibeq vi01,vi15,TSClipZeroArea
|
||||
.endif
|
||||
.endif
|
||||
|
||||
;; Call Clipper
|
||||
nop nop
|
||||
nop bal vi15,ClipTriangle ; skips return if there is a poly
|
||||
nop nop
|
||||
nop b TSClipSkip
|
||||
nop iaddiu vi08,vi00,1 ; have to restart strip
|
||||
|
||||
TSClipTriangulate:
|
||||
;; interpolate vertices and create new primitives from polygon buffer here
|
||||
;; this depends on the INPUTFORMAT
|
||||
nop ibeq vi05,vi06,TSClipSkip ; - no vertices at all
|
||||
nop iaddiu vi08,vi00,1 ; - have to restart strip
|
||||
nop loi 2048.0
|
||||
addi.z vf01,vf00,i lq vf10,1-1*numInAttribs(vi02) ; insert first two with ADC - load st[0]
|
||||
addi.z vf02,vf00,i lq vf11,1-0*numInAttribs(vi02) ; - load st[1]
|
||||
nop lq vf12,1+1*numInAttribs(vi02) ; - load st[2]
|
||||
nop lq vf13,2-1*numInAttribs(vi02) ; - load rgba[0]
|
||||
nop lq vf14,2-0*numInAttribs(vi02) ; - load rgba[1]
|
||||
nop lq vf15,2+1*numInAttribs(vi02) ; - load rgba[2]
|
||||
nop lq vf03,1(vi05) ; - bary1
|
||||
nop lq vf04,-1(vi06) ; - bary2
|
||||
nop lq.xyw vf01,0(vi05) ; - clip1
|
||||
nop lq.xyw vf02,-2(vi06) ; - clip2
|
||||
TSClipTriLoop:
|
||||
nop iaddiu vi08,vi00,1 ; - have to restart strip
|
||||
mulax acc,vf10,vf03 iaddiu vi05,vi05,2 ; interpolate st1
|
||||
madday acc,vf11,vf03 isubiu vi07,vi06,2
|
||||
maddz vf16,vf12,vf03 iaddiu vi03,vi03,1 ; inc nClipped
|
||||
mulax acc,vf13,vf03 sq vf01,0+0*numInAttribs(vi09) ; interpolate rgba1 - store clip1
|
||||
madday acc,vf14,vf03 lq.xyw vf01,0(vi05) ; - next clip1
|
||||
maddz vf17,vf15,vf03 lq vf03,1(vi05) ; - next bary1
|
||||
mulax acc,vf10,vf04 lq vf05,-3(vi06) ; interpolate st2 - next bary2
|
||||
madday acc,vf11,vf04 lq.xyw vf06,-4(vi06)
|
||||
maddz vf18,vf12,vf04 sq vf16,1+0*numInAttribs(vi09) ; - store rgba1
|
||||
mulax acc,vf13,vf04 sq vf17,2+0*numInAttribs(vi09) ; interpolate rgba2 - store st1
|
||||
madday acc,vf14,vf04 ibeq vi05,vi06,TSClipPrimEnd
|
||||
maddz vf19,vf15,vf04 iaddiu vi09,vi09,numInAttribs
|
||||
|
||||
addx vf04,vf05,vf00 iaddiu vi03,vi03,1 ; advance bary2
|
||||
addx.xyw vf02,vf06,vf00 sq vf02,0+0*numInAttribs(vi09) ; advance clip2 - store clip2
|
||||
nop sq vf18,1+0*numInAttribs(vi09) ; - store st2
|
||||
nop sq vf19,2+0*numInAttribs(vi09) ; - store rgba2
|
||||
addx.z vf01,vf00,vf00 ibeq vi05,vi06,TSClipPrimEnd ; insert all others without ADC
|
||||
addx.z vf02,vf00,vf00 iaddiu vi09,vi09,numInAttribs
|
||||
nop b TSClipTriLoop
|
||||
nop nop
|
||||
|
||||
TSClipZeroArea:
|
||||
nop b TSClipSkip
|
||||
nop iaddiu vi08,vi00,1 ; - have to restart strip
|
||||
nop nop ; make assembler happy
|
||||
|
||||
TSClipAllInside:
|
||||
;; copy full triangle
|
||||
;; this depends on the INPUTFORMAT
|
||||
nop ibeq vi08,vi00,TSClipContStrip
|
||||
nop loi 2048.0
|
||||
;; Have to restart the strip here
|
||||
nop lq vf04,1-1*numInAttribs(vi02) ; - load st[0]
|
||||
nop lq vf05,1-0*numInAttribs(vi02) ; - load st[1]
|
||||
addi.z vf01,vf00,i lq vf07,2-1*numInAttribs(vi02) ; set ADC - load rgba[0]
|
||||
addi.z vf02,vf00,i lq vf08,2-0*numInAttribs(vi02) ; set ADC - load rgba[1]
|
||||
nop sq vf04,1+0*numInAttribs(vi09) ; - store st[0]
|
||||
nop sq vf05,1+1*numInAttribs(vi09) ; - store st[1]
|
||||
nop sq vf07,2+0*numInAttribs(vi09) ; - store rgba[0]
|
||||
nop sq vf08,2+1*numInAttribs(vi09) ; - store rgba[1]
|
||||
nop sq vf01,0+0*numInAttribs(vi09) ; - store clip[0]
|
||||
nop sq vf02,0+1*numInAttribs(vi09) ; - store clip[1]
|
||||
nop iaddiu vi03,vi03,2 ; - inc nClipped
|
||||
nop iaddiu vi09,vi09,2*numInAttribs
|
||||
nop iaddiu vi08,vi00,0 ; we ll be in a strip after this
|
||||
TSClipContStrip:
|
||||
addx.z vf03,vf00,vf00 lq vf06,1+1*numInAttribs(vi02) ; clear ADC - load st[2]
|
||||
nop lq vf09,2+1*numInAttribs(vi02) ; - load rgab[2]
|
||||
nop iaddiu vi03,vi03,1 ; - inc nClipped
|
||||
nop iaddiu vi09,vi09,numInAttribs
|
||||
nop sq vf06,1-1*numInAttribs(vi09) ; - store st[2]
|
||||
nop sq vf09,2-1*numInAttribs(vi09) ; - store rgba[2]
|
||||
nop sq vf03,0-1*numInAttribs(vi09) ; - store clip[2]
|
||||
|
||||
TSClipPrimEnd:
|
||||
nop isubiu vi15,vi03,clipVertLimitTS ; can we overflow next time?
|
||||
nop nop
|
||||
nop ibgtz vi15,TSClipRender ; yes, have to render
|
||||
TSClipSkip:
|
||||
nop nop
|
||||
nop ibgtz vi04,TSClipPrimLoop ; next Triangle
|
||||
nop nop
|
||||
TSClipRender:
|
||||
nop ibeq vi03,vi00,End ; nothing to render
|
||||
nop nop
|
||||
|
||||
;; Process Clip buffer to output buffer and render
|
||||
nop bal vi15,ProcessClip
|
||||
nop iaddiu vi09,vi00,clipBuf
|
||||
|
||||
nop iblez vi04,End ; no more verts to process
|
||||
nop nop
|
||||
nop b TSClipLoop ; next batch
|
||||
nop nop
|
||||
|
||||
@@ -0,0 +1,230 @@
|
||||
;;;;;;;;;;;;
|
||||
;;;;;;; Perspective Line Segment Clipper
|
||||
;;;;;;;;;;;
|
||||
|
||||
;; TODO? start interpolating earlier and test the clipping flags later
|
||||
|
||||
;;;; Uses the following registers
|
||||
;;
|
||||
;; vi01 tmp
|
||||
;; vi15 tmp (return address)
|
||||
;;
|
||||
;; vf01 p1 pos input
|
||||
;; vf02 p1 bary input
|
||||
;; vf03 p2 pos input
|
||||
;; vf04 p2 bary input
|
||||
;; vf05 interp pos
|
||||
;; vf06 interp bary
|
||||
;; vf07.w d2
|
||||
;; vf08.w d1
|
||||
;; vf09.w d1-d2
|
||||
ClipLine:
|
||||
|
||||
.if 1
|
||||
;;; ====== w = near plane ======
|
||||
nop fcor vi01,negZo2 ; test if both out
|
||||
sub.w vf09,vf01,vf03 ibne vi01,vi00,CullLine ; d1-d2 - yes, skip this segment completely
|
||||
subz.w vf07,vf01,vf24 fcand vi01,negZn2 ; d1 - test if both in
|
||||
subz.w vf08,vf03,vf24 ibeq vi01,vi00,LClipNegZ_End ; d2 - yes, no need to clip against this plane
|
||||
;; So we need to interpolate
|
||||
nop nop
|
||||
nop div q,vf00w,vf09w
|
||||
mulaw acc,vf03,vf07 nop ; interp pos (acc = p2*d1)
|
||||
msubw vf05,vf01,vf08 nop ; interp pos (acc - p1*d2)
|
||||
mulaw acc,vf04,vf07 nop ; interp bary (acc = p2*d1)
|
||||
msubw vf06,vf02,vf08 nop ; interp bary (acc - p1*d2)
|
||||
nop nop
|
||||
nop nop
|
||||
mulq vf05,vf05,q nop ; interp pos
|
||||
mulq vf06,vf06,q nop ; interp bary
|
||||
nop fcand vi01,negZn1 ; test p2's cliping
|
||||
nop ibeq vi01,vi00,LClipNegZ_p1 ; it's in, so p1 is out
|
||||
;; p2 is out, so replace it
|
||||
nop nop
|
||||
clipw.xyz vf01,vf01 move vf03,vf05
|
||||
nop b LClipNegZ_Done
|
||||
clipw.xyz vf05,vf05 move vf04,vf06
|
||||
LClipNegZ_p1: ;; p1 is out, so replace it
|
||||
clipw.xyz vf05,vf05 move vf01,vf05
|
||||
clipw.xyz vf03,vf03 move vf02,vf06
|
||||
LClipNegZ_Done:
|
||||
nop nop ; wait for clipping flags
|
||||
nop nop
|
||||
nop nop
|
||||
LClipNegZ_End:
|
||||
.endif
|
||||
|
||||
.if 1
|
||||
;;; ====== w = far plane ======
|
||||
nop fcor vi01,posZo2 ; test if both out
|
||||
sub.w vf09,vf03,vf01 ibne vi01,vi00,CullLine ; d1-d2 - yes, skip this segment completely
|
||||
sub.w vf07,vf24,vf01 fcand vi01,posZn2 ; d1 - test if both in
|
||||
sub.w vf08,vf24,vf03 ibeq vi01,vi00,LClipPosZ_End ; d2 - yes, no need to clip against this plane
|
||||
;; So we need to interpolate
|
||||
nop nop
|
||||
nop div q,vf00w,vf09w
|
||||
mulaw acc,vf03,vf07 nop ; interp pos (acc = p2*d1)
|
||||
msubw vf05,vf01,vf08 nop ; interp pos (acc - p1*d2)
|
||||
mulaw acc,vf04,vf07 nop ; interp bary (acc = p2*d1)
|
||||
msubw vf06,vf02,vf08 nop ; interp bary (acc - p1*d2)
|
||||
nop nop
|
||||
nop nop
|
||||
mulq vf05,vf05,q nop ; interp pos
|
||||
mulq vf06,vf06,q nop ; interp bary
|
||||
nop fcand vi01,posZn1 ; test p2's cliping
|
||||
nop ibeq vi01,vi00,LClipPosZ_p1 ; it's in, so p1 is out
|
||||
;; p2 is out, so replace it
|
||||
nop nop
|
||||
clipw.xyz vf01,vf01 move vf03,vf05
|
||||
nop b LClipPosZ_Done
|
||||
clipw.xyz vf05,vf05 move vf04,vf06
|
||||
LClipPosZ_p1: ;; p1 is out, so replace it
|
||||
clipw.xyz vf05,vf05 move vf01,vf05
|
||||
clipw.xyz vf03,vf03 move vf02,vf06
|
||||
LClipPosZ_Done:
|
||||
nop nop ; wait for clipping flags
|
||||
nop nop
|
||||
nop nop
|
||||
LClipPosZ_End:
|
||||
.endif
|
||||
|
||||
.if 1
|
||||
;;; ====== w = -x ======
|
||||
addax.w acc,vf01,vf01 fcor vi01,negXo2 ; test if both out
|
||||
msubax.w acc,vf00,vf03 ibne vi01,vi00,CullLine ; yes, skip this segment completely
|
||||
msub.w vf09,vf00,vf03 fcand vi01,negXn2 ; d1-d2 test if both in
|
||||
addx.w vf07,vf01,vf01 ibeq vi01,vi00,LClipNegX_End ; d1 yes, no need to clip against this plane
|
||||
;; So we need to interpolate
|
||||
addx.w vf08,vf03,vf03 nop ; d2
|
||||
nop nop
|
||||
nop div q,vf00w,vf09w
|
||||
mulaw acc,vf03,vf07 nop ; interp pos (acc = p2*d1)
|
||||
msubw vf05,vf01,vf08 nop ; interp pos (acc - p1*d2)
|
||||
mulaw acc,vf04,vf07 nop ; interp bary (acc = p2*d1)
|
||||
msubw vf06,vf02,vf08 nop ; interp bary (acc - p1*d2)
|
||||
nop nop
|
||||
nop nop
|
||||
mulq vf05,vf05,q nop ; interp pos
|
||||
mulq vf06,vf06,q nop ; interp bary
|
||||
nop fcand vi01,negXn1 ; test p2's cliping
|
||||
nop ibeq vi01,vi00,LClipNegX_p1 ; it's in, so p1 is out
|
||||
;; p2 is out, so replace it
|
||||
nop nop
|
||||
clipw.xyz vf01,vf01 move vf03,vf05
|
||||
nop b LClipNegX_Done
|
||||
clipw.xyz vf05,vf05 move vf04,vf06
|
||||
LClipNegX_p1: ;; p1 is out, so replace it
|
||||
clipw.xyz vf05,vf05 move vf01,vf05
|
||||
clipw.xyz vf03,vf03 move vf02,vf06
|
||||
LClipNegX_Done:
|
||||
nop nop ; wait for clipping flags
|
||||
nop nop
|
||||
nop nop
|
||||
LClipNegX_End:
|
||||
.endif
|
||||
|
||||
.if 1
|
||||
;;; ====== w = x ======
|
||||
subax.w acc,vf01,vf01 fcor vi01,posXo2 ; test if both out
|
||||
maddax.w acc,vf00,vf03 ibne vi01,vi00,CullLine ; yes, skip this segment completely
|
||||
msub.w vf09,vf00,vf03 fcand vi01,posXn2 ; d1-d2 - test if both in
|
||||
subx.w vf07,vf01,vf01 ibeq vi01,vi00,LClipPosX_End ; d1 - yes, no need to clip against this plane
|
||||
;; So we need to interpolate
|
||||
subx.w vf08,vf03,vf03 nop ; d2
|
||||
nop nop
|
||||
nop div q,vf00w,vf09w
|
||||
mulaw acc,vf03,vf07 nop ; interp pos (acc = p2*d1)
|
||||
msubw vf05,vf01,vf08 nop ; interp pos (acc - p1*d2)
|
||||
mulaw acc,vf04,vf07 nop ; interp bary (acc = p2*d1)
|
||||
msubw vf06,vf02,vf08 nop ; interp bary (acc - p1*d2)
|
||||
nop nop
|
||||
nop nop
|
||||
mulq vf05,vf05,q nop ; interp pos
|
||||
mulq vf06,vf06,q nop ; interp bary
|
||||
nop fcand vi01,posXn1 ; test p2's cliping
|
||||
nop ibeq vi01,vi00,LClipPosX_p1 ; it's in, so p1 is out
|
||||
;; p2 is out, so replace it
|
||||
nop nop
|
||||
clipw.xyz vf01,vf01 move vf03,vf05
|
||||
nop b LClipPosX_Done
|
||||
clipw.xyz vf05,vf05 move vf04,vf06
|
||||
LClipPosX_p1: ;; p1 is out, so replace it
|
||||
clipw.xyz vf05,vf05 move vf01,vf05
|
||||
clipw.xyz vf03,vf03 move vf02,vf06
|
||||
LClipPosX_Done:
|
||||
nop nop ; wait for clipping flags
|
||||
nop nop
|
||||
nop nop
|
||||
LClipPosX_End:
|
||||
.endif
|
||||
|
||||
.if 1
|
||||
;;; ====== w = -y ======
|
||||
adday.w acc,vf01,vf01 fcor vi01,negYo2 ; test if both out
|
||||
msubay.w acc,vf00,vf03 ibne vi01,vi00,CullLine ; yes, skip this segment completely
|
||||
msub.w vf09,vf00,vf03 fcand vi01,negYn2 ; d1-d2 - test if both in
|
||||
addy.w vf07,vf01,vf01 ibeq vi01,vi00,LClipNegY_End ; d1 - yes, no need to clip against this plane
|
||||
;; So we need to interpolate
|
||||
addy.w vf08,vf03,vf03 nop ; d2
|
||||
nop nop
|
||||
nop div q,vf00w,vf09w
|
||||
mulaw acc,vf03,vf07 nop ; interp pos (acc = p2*d1)
|
||||
msubw vf05,vf01,vf08 nop ; interp pos (acc - p1*d2)
|
||||
mulaw acc,vf04,vf07 nop ; interp bary (acc = p2*d1)
|
||||
msubw vf06,vf02,vf08 nop ; interp bary (acc - p1*d2)
|
||||
nop nop
|
||||
nop nop
|
||||
mulq vf05,vf05,q nop ; interp pos
|
||||
mulq vf06,vf06,q nop ; interp bary
|
||||
nop fcand vi01,negYn1 ; test p2's cliping
|
||||
nop ibeq vi01,vi00,LClipNegY_p1 ; it's in, so p1 is out
|
||||
;; p2 is out, so replace it
|
||||
nop nop
|
||||
clipw.xyz vf01,vf01 move vf03,vf05
|
||||
nop b LClipNegY_Done
|
||||
clipw.xyz vf05,vf05 move vf04,vf06
|
||||
LClipNegY_p1: ;; p1 is out, so replace it
|
||||
clipw.xyz vf05,vf05 move vf01,vf05
|
||||
clipw.xyz vf03,vf03 move vf02,vf06
|
||||
LClipNegY_Done:
|
||||
nop nop ; wait for clipping flags
|
||||
nop nop
|
||||
nop nop
|
||||
LClipNegY_End:
|
||||
.endif
|
||||
|
||||
.if 1
|
||||
;;; ====== w = y ======
|
||||
subay.w acc,vf01,vf01 fcor vi01,posYo2 ; test if both out
|
||||
madday.w acc,vf00,vf03 ibne vi01,vi00,CullLine ; yes, skip this segment completely
|
||||
msub.w vf09,vf00,vf03 fcand vi01,posYn2 ; d1-d2 - test if both in
|
||||
suby.w vf07,vf01,vf01 ibeq vi01,vi00,LClipPosY_End ; d2 - yes, no need to clip against this plane
|
||||
;; So we need to interpolate
|
||||
suby.w vf08,vf03,vf03 nop ; d2
|
||||
nop nop
|
||||
nop div q,vf00w,vf09w
|
||||
mulaw acc,vf03,vf07 nop ; interp pos (acc = p2*d1)
|
||||
msubw vf05,vf01,vf08 nop ; interp pos (acc - p1*d2)
|
||||
mulaw acc,vf04,vf07 nop ; interp bary (acc = p2*d1)
|
||||
msubw vf06,vf02,vf08 nop ; interp bary (acc - p1*d2)
|
||||
nop nop
|
||||
nop nop
|
||||
mulq vf05,vf05,q nop ; interp pos
|
||||
mulq vf06,vf06,q nop ; interp bary
|
||||
nop fcand vi01,posYn1 ; test p2's cliping
|
||||
nop ibeq vi01,vi00,LClipPosY_p1 ; it's in, so p1 is out
|
||||
;; p2 is out, so replace it
|
||||
nop nop
|
||||
clipw.xyz vf01,vf01 move vf03,vf05
|
||||
nop b LClipPosY_End
|
||||
clipw.xyz vf05,vf05 move vf04,vf06
|
||||
LClipPosY_p1: ;; p1 is out, so replace it
|
||||
clipw.xyz vf05,vf05 move vf01,vf05
|
||||
clipw.xyz vf03,vf03 move vf02,vf06
|
||||
LClipPosY_End:
|
||||
.endif
|
||||
|
||||
nop iaddiu vi15,vi15,2
|
||||
CullLine:
|
||||
nop jr vi15
|
||||
nop nop
|
||||
@@ -0,0 +1,272 @@
|
||||
|
||||
;;;;;;;;;;;;
|
||||
;;;;;;; Perspective Triangle Clipper
|
||||
;;;;;;;;;;;
|
||||
|
||||
;;;; Uses the following registers
|
||||
;;
|
||||
;; vi01 tmp
|
||||
;; vi05 polyInPtr input
|
||||
;; vi06 polyInEnd input
|
||||
;; vi07 polyOutPtr input
|
||||
;; vi10 polyBuf1 input
|
||||
;; vi11 polyBuf2 input
|
||||
;; vi15 tmp (return address)
|
||||
;;
|
||||
;; vf01 p2 pos input
|
||||
;; vf02 interp pos
|
||||
;; vf03 p1 pos input
|
||||
;; vf04 p2 bary
|
||||
;; vf05 interp bary
|
||||
;; vf06 p1 bary input
|
||||
;; vf07.w d2
|
||||
;; vf08.w d1
|
||||
;; vf09.w d1-d2
|
||||
;; vf22 tmp
|
||||
;; vf23 tmp
|
||||
|
||||
ClipTriangle:
|
||||
nop isw.w vi08,codeSwitch(vi00) ; save return
|
||||
nop nop ;; TODO: assembler complains about hazard here. why?
|
||||
nop iadd vi08,vi00,vi15 ;
|
||||
.if 1
|
||||
;;; ====== w = near plane ======
|
||||
nop fcor vi01,negZo ; test if all out
|
||||
nop ibne vi01,vi00,CullTri ; yes, skip this triangle completely
|
||||
nop fcand vi01,negZn ; test if all in
|
||||
nop ibeq vi01,vi00,ClipNegZ_Skip ; yes, no need to clip against this plane
|
||||
ClipNegZ_Loop:
|
||||
sub.w vf09,vf03,vf01 lq vf04,1(vi05) ; d1-d2 - load bary2
|
||||
subz.w vf08,vf03,vf24 move vf22,vf03 ; d1 - save pos1
|
||||
subz.w vf07,vf01,vf24 move vf23,vf06 ; d2 - save pos2
|
||||
addx vf03,vf01,vf00 iaddiu vi05,vi05,2 ; advance pos1
|
||||
nop div q,vf00w,vf09w ; - 1/(d1-d2)
|
||||
mulaw acc,vf01,vf08 fsand vi01,2 ; interp pos (acc = p2*d1) get d1 sign
|
||||
mul.w vf00,vf07,vf08 lq vf01,0(vi05) ; d1*d2
|
||||
msubw vf02,vf22,vf07 nop ; interp pos (acc - p1*d2)
|
||||
mulaw acc,vf04,vf08 nop ; interp bary (acc = p2*d1)
|
||||
msubw vf05,vf06,vf07 ibne vi01,vi00,ClipNegZ_Clipped ; interp bary (acc - p1*d2)
|
||||
addx vf06,vf04,vf00 fsand vi15,2 ; advance bary1 - sign of d1*d2
|
||||
clipw.xyz vf22,vf22 sqi vf22,(vi07++) ; store p1
|
||||
nop sqi vf23,(vi07++)
|
||||
ClipNegZ_Clipped: ; p1 is clipped
|
||||
mulq vf02,vf02,q ibeq vi15,vi00,ClipNegZ_Next ; interp pos
|
||||
nop iadd vi01,vi00,vi07 ; always store interp bary here
|
||||
mulq vf05,vf05,q iaddiu vi07,vi07,2 ; interp bary - advance out ptr
|
||||
nop nop
|
||||
clipw.xyz vf02,vf02 sq vf02,-2(vi07) ; - store interp pos
|
||||
ClipNegZ_Next:
|
||||
nop ibne vi05,vi06,ClipNegZ_Loop
|
||||
nop sq vf05,1(vi01) ; - store interp bary (or junk if no interpolation)
|
||||
nop bal vi15,SwapClipBuffers
|
||||
nop nop
|
||||
ClipNegZ_Skip:
|
||||
.endif
|
||||
|
||||
.if 1
|
||||
;; Early out if all verts outside of any one plane
|
||||
nop fcor vi01,posZo
|
||||
nop ibne vi01,vi00,CullTri
|
||||
nop fcor vi01,negXo
|
||||
nop ibne vi01,vi00,CullTri
|
||||
nop fcor vi01,posXo
|
||||
nop ibne vi01,vi00,CullTri
|
||||
nop fcor vi01,negYo
|
||||
nop ibne vi01,vi00,CullTri
|
||||
nop fcor vi01,posYo
|
||||
nop ibne vi01,vi00,CullTri
|
||||
.endif
|
||||
|
||||
.if 1
|
||||
;;; ====== w = far plane ======
|
||||
nop lq vf01,0(vi05) ; load p2 pos
|
||||
nop ibeq vi05,vi06,CullTri
|
||||
nop fcand vi01,posZn ; test if all in
|
||||
nop ibeq vi01,vi00,ClipPosZ_Skip ; yes, no need to clip against this plane
|
||||
nop nop
|
||||
ClipPosZ_Loop:
|
||||
sub.w vf09,vf01,vf03 lq vf04,1(vi05) ; d1-d2 - load bary2
|
||||
sub.w vf08,vf24,vf03 move vf22,vf03 ; d1 - save pos1
|
||||
sub.w vf07,vf24,vf01 move vf23,vf06 ; d2 - save pos2
|
||||
addx vf03,vf01,vf00 iaddiu vi05,vi05,2 ; advance pos1
|
||||
nop div q,vf00w,vf09w ; - 1/(d1-d2)
|
||||
mulaw acc,vf01,vf08 fsand vi01,2 ; interp pos (acc = p2*d1) get d1 sign
|
||||
mul.w vf00,vf07,vf08 lq vf01,0(vi05) ; d1*d2
|
||||
msubw vf02,vf22,vf07 nop ; interp pos (acc - p1*d2)
|
||||
mulaw acc,vf04,vf08 nop ; interp bary (acc = p2*d1)
|
||||
msubw vf05,vf06,vf07 ibne vi01,vi00,ClipPosZ_Clipped ; interp bary (acc - p1*d2)
|
||||
addx vf06,vf04,vf00 fsand vi15,2 ; sign of d1*d2
|
||||
nop sqi vf22,(vi07++) ; store p1
|
||||
nop sqi vf23,(vi07++)
|
||||
ClipPosZ_Clipped: ; p1 is clipped
|
||||
mulq vf02,vf02,q ibeq vi15,vi00,ClipPosZ_Next ; interp pos
|
||||
nop iadd vi01,vi00,vi07 ; always store interp bary here
|
||||
mulq vf05,vf05,q iaddiu vi07,vi07,2 ; interp bary - advance out ptr
|
||||
nop nop
|
||||
nop sq vf02,-2(vi07) ; - store interp pos
|
||||
ClipPosZ_Next:
|
||||
nop ibne vi05,vi06,ClipPosZ_Loop
|
||||
nop sq vf05,1(vi01) ; - store interp bary (or junk if no interpolation)
|
||||
nop bal vi15,SwapClipBuffers
|
||||
nop nop
|
||||
ClipPosZ_Skip:
|
||||
.endif
|
||||
|
||||
.if 1
|
||||
;;; ====== w = -x plane ======
|
||||
nop lq vf01,0(vi05) ; load p2 pos
|
||||
nop ibeq vi05,vi06,CullTri
|
||||
nop fcand vi01,negXn ; test if all in
|
||||
addax.w acc,vf03,vf03 ibeq vi01,vi00,ClipNegX_Skip ; yes, no need to clip against this plane
|
||||
msubax.w acc,vf00,vf01 nop
|
||||
ClipNegX_Loop:
|
||||
msub.w vf09,vf00,vf01 lq vf04,1(vi05) ; d1-d2 - load bary2
|
||||
addx.w vf08,vf03,vf03 move vf22,vf03 ; d1 - save pos1
|
||||
addx.w vf07,vf01,vf01 move vf23,vf06 ; d2 - save pos2
|
||||
addx vf03,vf01,vf00 iaddiu vi05,vi05,2 ; advance pos1
|
||||
nop div q,vf00w,vf09w ; - 1/(d1-d2)
|
||||
mulaw acc,vf01,vf08 fsand vi01,2 ; interp pos (acc = p2*d1) get d1 sign
|
||||
mul.w vf00,vf07,vf08 lq vf01,0(vi05) ; d1*d2
|
||||
msubw vf02,vf22,vf07 nop ; interp pos (acc - p1*d2)
|
||||
mulaw acc,vf04,vf08 nop ; interp bary (acc = p2*d1)
|
||||
msubw vf05,vf06,vf07 ibne vi01,vi00,ClipNegX_Clipped ; interp bary (acc - p1*d2)
|
||||
addx vf06,vf04,vf00 fsand vi15,2 ; sign of d1*d2
|
||||
nop sqi vf22,(vi07++) ; store p1
|
||||
nop sqi vf23,(vi07++)
|
||||
ClipNegX_Clipped: ; p1 is clipped
|
||||
mulq vf02,vf02,q ibeq vi15,vi00,ClipNegX_Next ; interp pos
|
||||
nop iadd vi01,vi00,vi07 ; always store interp bary here
|
||||
mulq vf05,vf05,q iaddiu vi07,vi07,2 ; interp bary - advance out ptr
|
||||
nop nop
|
||||
nop sq vf02,-2(vi07) ; - store interp pos
|
||||
ClipNegX_Next:
|
||||
addax.w acc,vf03,vf03 ibne vi05,vi06,ClipNegX_Loop
|
||||
msubax.w acc,vf00,vf01 sq vf05,1(vi01) ; - store interp bary (or junk if no interpolation)
|
||||
nop bal vi15,SwapClipBuffers
|
||||
nop nop
|
||||
ClipNegX_Skip:
|
||||
.endif
|
||||
|
||||
.if 1
|
||||
;;; ====== w = +x plane ======
|
||||
nop lq vf01,0(vi05) ; load p2 pos
|
||||
nop ibeq vi05,vi06,CullTri
|
||||
nop fcand vi01,posXn ; test if all in
|
||||
subax.w acc,vf03,vf03 ibeq vi01,vi00,ClipPosX_Skip ; yes, no need to clip against this plane
|
||||
maddax.w acc,vf00,vf01 nop
|
||||
ClipPosX_Loop:
|
||||
msub.w vf09,vf00,vf01 lq vf04,1(vi05) ; d1-d2 - load bary2
|
||||
subx.w vf08,vf03,vf03 move vf22,vf03 ; d1 - save pos1
|
||||
subx.w vf07,vf01,vf01 move vf23,vf06 ; d2 - save pos2
|
||||
addx vf03,vf01,vf00 iaddiu vi05,vi05,2 ; advance pos1
|
||||
nop div q,vf00w,vf09w ; - 1/(d1-d2)
|
||||
mulaw acc,vf01,vf08 fsand vi01,2 ; interp pos (acc = p2*d1) get d1 sign
|
||||
mul.w vf00,vf07,vf08 lq vf01,0(vi05) ; d1*d2
|
||||
msubw vf02,vf22,vf07 nop ; interp pos (acc - p1*d2)
|
||||
mulaw acc,vf04,vf08 nop ; interp bary (acc = p2*d1)
|
||||
msubw vf05,vf06,vf07 ibne vi01,vi00,ClipPosX_Clipped ; interp bary (acc - p1*d2)
|
||||
addx vf06,vf04,vf00 fsand vi15,2 ; sign of d1*d2
|
||||
nop sqi vf22,(vi07++) ; store p1
|
||||
nop sqi vf23,(vi07++)
|
||||
ClipPosX_Clipped: ; p1 is clipped
|
||||
mulq vf02,vf02,q ibeq vi15,vi00,ClipPosX_Next ; interp pos
|
||||
nop iadd vi01,vi00,vi07 ; always store interp bary here
|
||||
mulq vf05,vf05,q iaddiu vi07,vi07,2 ; interp bary - advance out ptr
|
||||
nop nop
|
||||
nop sq vf02,-2(vi07) ; - store interp pos
|
||||
ClipPosX_Next:
|
||||
subax.w acc,vf03,vf03 ibne vi05,vi06,ClipPosX_Loop
|
||||
maddax.w acc,vf00,vf01 sq vf05,1(vi01) ; - store interp bary (or junk if no interpolation)
|
||||
nop bal vi15,SwapClipBuffers
|
||||
nop nop
|
||||
ClipPosX_Skip:
|
||||
.endif
|
||||
|
||||
.if 1
|
||||
;;; ====== w = -y plane ======
|
||||
nop lq vf01,0(vi05) ; load p2 pos
|
||||
nop ibeq vi05,vi06,CullTri
|
||||
nop fcand vi01,negYn ; test if all in
|
||||
adday.w acc,vf03,vf03 ibeq vi01,vi00,ClipNegY_Skip ; yes, no need to clip against this plane
|
||||
msubay.w acc,vf00,vf01 nop
|
||||
ClipNegY_Loop:
|
||||
msub.w vf09,vf00,vf01 lq vf04,1(vi05) ; d1-d2 - load bary2
|
||||
addy.w vf08,vf03,vf03 move vf22,vf03 ; d1 - save pos1
|
||||
addy.w vf07,vf01,vf01 move vf23,vf06 ; d2 - save pos2
|
||||
addx vf03,vf01,vf00 iaddiu vi05,vi05,2 ; advance pos1
|
||||
nop div q,vf00w,vf09w ; - 1/(d1-d2)
|
||||
mulaw acc,vf01,vf08 fsand vi01,2 ; interp pos (acc = p2*d1) get d1 sign
|
||||
mul.w vf00,vf07,vf08 lq vf01,0(vi05) ; d1*d2
|
||||
msubw vf02,vf22,vf07 nop ; interp pos (acc - p1*d2)
|
||||
mulaw acc,vf04,vf08 nop ; interp bary (acc = p2*d1)
|
||||
msubw vf05,vf06,vf07 ibne vi01,vi00,ClipNegY_Clipped ; interp bary (acc - p1*d2)
|
||||
addx vf06,vf04,vf00 fsand vi15,2 ; sign of d1*d2
|
||||
nop sqi vf22,(vi07++) ; store p1
|
||||
nop sqi vf23,(vi07++)
|
||||
ClipNegY_Clipped: ; p1 is clipped
|
||||
mulq vf02,vf02,q ibeq vi15,vi00,ClipNegY_Next ; interp pos
|
||||
nop iadd vi01,vi00,vi07 ; always store interp bary here
|
||||
mulq vf05,vf05,q iaddiu vi07,vi07,2 ; interp bary - advance out ptr
|
||||
nop nop
|
||||
nop sq vf02,-2(vi07) ; - store interp pos
|
||||
ClipNegY_Next:
|
||||
adday.w acc,vf03,vf03 ibne vi05,vi06,ClipNegY_Loop
|
||||
msubay.w acc,vf00,vf01 sq vf05,1(vi01) ; - store interp bary (or junk if no interpolation)
|
||||
nop bal vi15,SwapClipBuffers
|
||||
nop nop
|
||||
ClipNegY_Skip:
|
||||
.endif
|
||||
|
||||
.if 1
|
||||
;;; ====== w = +y plane ======
|
||||
nop lq vf01,0(vi05) ; load p2 pos
|
||||
nop ibeq vi05,vi06,CullTri
|
||||
nop fcand vi01,posYn ; test if all in
|
||||
subay.w acc,vf03,vf03 ibeq vi01,vi00,ClipPosY_Skip ; yes, no need to clip against this plane
|
||||
madday.w acc,vf00,vf01 nop
|
||||
ClipPosY_Loop:
|
||||
msub.w vf09,vf00,vf01 lq vf04,1(vi05) ; d1-d2 - load bary2
|
||||
suby.w vf08,vf03,vf03 move vf22,vf03 ; d1 - save pos1
|
||||
suby.w vf07,vf01,vf01 move vf23,vf06 ; d2 - save pos2
|
||||
addx vf03,vf01,vf00 iaddiu vi05,vi05,2 ; advance pos1
|
||||
nop div q,vf00w,vf09w ; - 1/(d1-d2)
|
||||
mulaw acc,vf01,vf08 fsand vi01,2 ; interp pos (acc = p2*d1) get d1 sign
|
||||
mul.w vf00,vf07,vf08 lq vf01,0(vi05) ; d1*d2
|
||||
msubw vf02,vf22,vf07 nop ; interp pos (acc - p1*d2)
|
||||
mulaw acc,vf04,vf08 nop ; interp bary (acc = p2*d1)
|
||||
msubw vf05,vf06,vf07 ibne vi01,vi00,ClipPosY_Clipped ; interp bary (acc - p1*d2)
|
||||
addx vf06,vf04,vf00 fsand vi15,2 ; sign of d1*d2
|
||||
nop sqi vf22,(vi07++) ; store p1
|
||||
nop sqi vf23,(vi07++)
|
||||
ClipPosY_Clipped: ; p1 is clipped
|
||||
mulq vf02,vf02,q ibeq vi15,vi00,ClipPosY_Next ; interp pos
|
||||
nop iadd vi01,vi00,vi07 ; always store interp bary here
|
||||
mulq vf05,vf05,q iaddiu vi07,vi07,2 ; interp bary - advance out ptr
|
||||
nop nop
|
||||
nop sq vf02,-2(vi07) ; - store interp pos
|
||||
ClipPosY_Next:
|
||||
subay.w acc,vf03,vf03 ibne vi05,vi06,ClipPosY_Loop
|
||||
madday.w acc,vf00,vf01 sq vf05,1(vi01) ; - store interp bary (or junk if no interpolation)
|
||||
nop bal vi15,SwapClipBuffers
|
||||
nop nop
|
||||
ClipPosY_Skip:
|
||||
.endif
|
||||
nop iaddiu vi08,vi08,2
|
||||
CullTri:
|
||||
nop jr vi08
|
||||
nop ilw.w vi08,codeSwitch(vi00)
|
||||
|
||||
;;;;;;;;;;;;
|
||||
;;;;;;; End of Perspective Triangle Clipper
|
||||
;;;;;;;;;;;
|
||||
|
||||
SwapClipBuffers:
|
||||
nop iadd vi05,vi00,vi11 ; polyInPtr
|
||||
nop iadd vi06,vi00,vi07 ; polyInEnd
|
||||
nop iadd vi07,vi00,vi10 ; polyOutPtr
|
||||
nop iadd vi11,vi00,vi10
|
||||
nop iadd vi10,vi00,vi05
|
||||
nop lq vf03,-2(vi06) ; load last vertex as p1
|
||||
nop jr vi15
|
||||
nop lq vf06,-1(vi06)
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
.equ vertexTop, 0x3d0
|
||||
.equ numInAttribs, 4
|
||||
.equ numOutAttribs, 3
|
||||
.equ numOutBuf, 2
|
||||
.equ vertCount, ((vertexTop-numOutBuf)/(numInAttribs*2+numOutAttribs*numOutBuf))
|
||||
.equ offset, (vertCount*numInAttribs)
|
||||
.equ outBuf1, (2*offset)
|
||||
;.equ outSize, ((vertexTop-outBuf1-numOutBuf)/numOutBuf)
|
||||
.equ outSize, (1 + vertCount*numOutAttribs)
|
||||
.equ outBuf2, (outBuf1+outSize)
|
||||
|
||||
.equ clipVertCount, ((vertexTop-outBuf1-numOutBuf)/(numInAttribs+numOutAttribs*numOutBuf))
|
||||
.equ clipOutSize, (1 + clipVertCount*numOutAttribs)
|
||||
.equ clipOutBuf2, (outBuf1+clipOutSize)
|
||||
.equ clipBuf, (clipOutBuf2+clipOutSize)
|
||||
|
||||
; up to 9 verts => 7 tris per poly in worst case, a lot for lists unfortunately
|
||||
.equ clipVertLimitTL, (clipVertCount-21)
|
||||
.equ clipVertLimitTS, (clipVertCount-15) ;;; TODO: this crashes when i set it to -9 as it should be
|
||||
|
||||
.include "defines.inc"
|
||||
|
||||
#define IN_VERTEX(n,r) 0 + (n)*numInAttribs(r)
|
||||
#define IN_UV(n,r) 1 + (n)*numInAttribs(r)
|
||||
#define IN_RGBA(n,r) 2 + (n)*numInAttribs(r)
|
||||
#define IN_NORMAL(n,r) 3 + (n)*numInAttribs(r)
|
||||
|
||||
#define OUT_STQ(n,r) 0 + (n)*numOutAttribs(r)
|
||||
#define OUT_RGBA(n,r) 1 + (n)*numOutAttribs(r)
|
||||
#define OUT_XYZ(n,r) 2 + (n)*numOutAttribs(r)
|
||||
|
||||
.balign 16,0
|
||||
|
||||
.global vu1_default
|
||||
vu1_default:
|
||||
|
||||
DMAret *
|
||||
MPG 0, *
|
||||
.vu
|
||||
start:
|
||||
nop ilw.y vi12,codeSwitch(vi00)
|
||||
nop ilw.z vi13,codeSwitch(vi00)
|
||||
nop lq vf28,matrix0(vi00)
|
||||
nop lq vf29,matrix1(vi00)
|
||||
nop lq vf30,matrix2(vi00)
|
||||
nop lq vf31,matrix3(vi00)
|
||||
nop lq vf27,xyzwScale(vi00)
|
||||
nop lq vf26,xyzwOffset(vi00)
|
||||
nop lq vf25,colorScale(vi00)
|
||||
nop lq vf24,clipConsts(vi00)
|
||||
restart:
|
||||
nop ilw.x vi09,codeSwitch(vi00) ; process switch
|
||||
|
||||
;; Calculate end of input buffer with vertex count rounded up to multiple of 4
|
||||
;; Note that the maximum vertex count is always a multiple of 4 so this is always legal
|
||||
nop xtop vi02 ; input pointer
|
||||
nop xitop vi01 ; vertex count
|
||||
nop iaddiu vi03,vi01,3
|
||||
nop iaddiu vi04,vi00,~3
|
||||
nop iand vi04,vi03,vi04 ; round up vertex count
|
||||
nop iadd vi03,vi02,vi04
|
||||
.rept numInAttribs-1
|
||||
nop iadd vi03,vi03,vi04
|
||||
.endr
|
||||
|
||||
;; Convert normals and colors to float. this is also where we d do skinning probably
|
||||
;; TODO: could simplify this if we have no lighting
|
||||
nop iaddiu vi02,vi02,4*numInAttribs
|
||||
nop loi 0.007874015748031496 ; normal scale
|
||||
nop lq vf01,IN_RGBA(0-4,vi02)
|
||||
sub vf09,vf00,vf00 lq vf02,IN_RGBA(1-4,vi02)
|
||||
nop lq vf03,IN_RGBA(2-4,vi02)
|
||||
nop lq vf04,IN_RGBA(3-4,vi02)
|
||||
PreprocLoop:
|
||||
itof0 vf01,vf01 lq vf05,IN_NORMAL(0-4,vi02)
|
||||
itof0 vf02,vf02 lq vf06,IN_NORMAL(1-4,vi02)
|
||||
itof0 vf03,vf03 lq vf07,IN_NORMAL(2-4,vi02)
|
||||
itof0 vf04,vf04 lq vf08,IN_NORMAL(3-4,vi02)
|
||||
itof0.xyz vf05,vf05 sq vf01,IN_RGBA(0-4,vi02)
|
||||
itof0.xyz vf06,vf06 sq vf02,IN_RGBA(1-4,vi02)
|
||||
itof0.xyz vf07,vf07 sq vf03,IN_RGBA(2-4,vi02)
|
||||
itof0.xyz vf08,vf08 sq vf04,IN_RGBA(3-4,vi02)
|
||||
muli.xyz vf05,vf05,i lq vf01,IN_RGBA(0,vi02)
|
||||
muli.xyz vf06,vf06,i lq vf02,IN_RGBA(1,vi02)
|
||||
muli.xyz vf07,vf07,i lq vf03,IN_RGBA(2,vi02)
|
||||
muli.xyz vf08,vf08,i lq vf04,IN_RGBA(3,vi02)
|
||||
nop sq vf05,IN_NORMAL(0-4,vi02)
|
||||
nop sq vf06,IN_NORMAL(1-4,vi02)
|
||||
nop sq vf07,IN_NORMAL(2-4,vi02)
|
||||
nop sq vf08,IN_NORMAL(3-4,vi02)
|
||||
.if 0
|
||||
;; clear ADC flag here if geometry doesn t write it
|
||||
nop sq.w vf09,IN_VERTEX(0-4,vi02)
|
||||
nop sq.w vf09,IN_VERTEX(1-4,vi02)
|
||||
nop sq.w vf09,IN_VERTEX(2-4,vi02)
|
||||
nop sq.w vf09,IN_VERTEX(3-4,vi02)
|
||||
.endif
|
||||
nop ibne vi02,vi03,PreprocLoop
|
||||
nop iaddiu vi02,vi02,4*numInAttribs
|
||||
|
||||
|
||||
#include "lighting.vu"
|
||||
|
||||
nop jr vi09
|
||||
nop nop
|
||||
|
||||
Process:
|
||||
#include "default_proc.vu"
|
||||
TLClip:
|
||||
#include "TLclip.vu"
|
||||
TSClip:
|
||||
#include "TSclip.vu"
|
||||
|
||||
End:
|
||||
nop[e] nop
|
||||
nop nop
|
||||
nop b restart
|
||||
nop nop
|
||||
|
||||
#include "cliptri.vu"
|
||||
#include "default_clipproc.vu"
|
||||
|
||||
.EndMPG
|
||||
.EndDmaData
|
||||
|
||||
|
||||
.global vu1_default_desc
|
||||
vu1_default_desc:
|
||||
.word Process, outBuf1, outBuf2, 0
|
||||
.word TLClip, outBuf1, clipOutBuf2, 0
|
||||
.word TSClip, outBuf1, clipOutBuf2, 0
|
||||
@@ -0,0 +1,46 @@
|
||||
|
||||
;; Process clipping buffer to output
|
||||
;; vertices are already in clip space
|
||||
;; vi09: input buffer
|
||||
;; vi03: vertex Count
|
||||
;; CANNOT use: vi02, vi04 (clipping), vi15 (return)
|
||||
;; TMP: vi06
|
||||
ProcessClip:
|
||||
nop lq vf01,gifTag(vi00) ; GIF tag
|
||||
nop iaddiu vi06,vi00,0x4000
|
||||
nop iadd vi06,vi06,vi06 ; EOP bit
|
||||
nop ior vi06,vi06,vi03 ; enter vertex count
|
||||
nop sq vf01,0(vi12) ; store GIF tag
|
||||
nop isw.x vi06,0(vi12)
|
||||
addw.z vf12,vf00,vf00 lq.xyw vf10,0(vi09) ; xyw
|
||||
addw.z vf10,vf00,vf00 lq vf11,2(vi09) ; rgba
|
||||
nop lq.xy vf12,1(vi09) ; st
|
||||
nop iaddiu vi05,vi12,1 ; output pointer
|
||||
ProcessClipLoop:
|
||||
miniy.w vf01,vf10,vf24 div q,vf00w,vf10w ; clamp to fog far - start perspective division
|
||||
nop nop
|
||||
mul.xyz vf22,vf10,vf27 lq.z vf13,0(vi09) ; pos.xyz*scale.xyz - load ADC flag
|
||||
addax acc,vf26,vf00 nop ; init acc
|
||||
maxx.w vf01,vf01,vf24 nop ; clamp to fog near
|
||||
ftoi0 vf02,vf11 isubiu vi03,vi03,1 ; convert rgba
|
||||
maddaz.w acc,vf00,vf13 iaddiu vi09,vi09,numInAttribs ; add ADC flag
|
||||
maddq.xyz vf01,vf22,q nop ; calc pos (can use q now)
|
||||
madd.w vf01,vf01,vf27 nop ; calc fog
|
||||
mulq.xyz vf03,vf12,q lq.xyw vf10,0(vi09) ; scale stq - next xyw
|
||||
addw.z vf12,vf00,vf00 lq vf11,2(vi09) ; - next rgba
|
||||
addw.z vf10,vf00,vf00 lq.xy vf12,1(vi09) ; - next st
|
||||
ftoi4 vf01,vf01 iaddiu vi05,vi05,numOutAttribs ; convert xyzf
|
||||
nop sq vf02,1-numOutAttribs(vi05) ; rgba
|
||||
nop sq vf03,0-numOutAttribs(vi05) ; stq
|
||||
nop ibne vi03,vi00,ProcessClipLoop
|
||||
nop sq vf01,2-numOutAttribs(vi05) ; xyzf
|
||||
|
||||
;; Render it
|
||||
nop xgkick vi12
|
||||
nop iadd vi05,vi00,vi12
|
||||
nop iadd vi12,vi00,vi13
|
||||
nop iadd vi13,vi00,vi05
|
||||
|
||||
nop jr vi15
|
||||
nop nop
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
mul.xyw vf23,vf31,vf27 xtop vi02 ; scale matrix - input pointer
|
||||
mul.xyw vf20,vf28,vf27 lq vf10,IN_VERTEX(0,vi02) ; scale matrix - load vert-1
|
||||
mul.xyw vf21,vf29,vf27 lq vf01,gifTag(vi00) ; scale matrix
|
||||
mul.xyw vf22,vf30,vf27 xitop vi01 ; scale matrix - vertex count
|
||||
mulaw acc,vf23,vf00 iaddiu vi05,vi00,0x4000 ; xform vert-1
|
||||
maddax acc,vf20,vf10 iadd vi05,vi05,vi05 ; xform vert-1 - EOP bit
|
||||
madday acc,vf21,vf10 ior vi05,vi05,vi01 ; xform vert-1 - enter vertex count
|
||||
maddz.xyw vf01,vf22,vf10 sq vf01,0(vi12) ; xform vert-1 - store GIF tag
|
||||
mulw.xy vf06,vf24,vf27 move.z vf01,vf27 ; scale fog clamp - init z-1
|
||||
add.w vf05,vf26,vf10 isw.x vi05,0(vi12) ; add adc-1 to w-offset - store vertex count
|
||||
nop lq vf10,IN_VERTEX(1,vi02) ; - load vert-2
|
||||
nop div q,vf27w,vf01w ; - divide vert-1
|
||||
miniy.w vf01,vf01,vf06 nop ; clamp fog-1
|
||||
nop lq.xy vf12,IN_UV(0,vi02) ; - load uv-1
|
||||
mulaw acc,vf23,vf00 lq vf11,IN_RGBA(0,vi02) ; xform vert-2 - load rgba-1
|
||||
maddax acc,vf20,vf10 mr32.z vf12,vf00 ; xform vert-2
|
||||
maxx.w vf04,vf01,vf06 move.xyz vf05,vf26 ; clamp fog-1
|
||||
madday acc,vf21,vf10 iaddiu vi04,vi12,1 ; xform vert-2 - output pointer
|
||||
ProcessLoop:
|
||||
mulq.xyz vf04,vf01,q move.z vf01,vf27
|
||||
maddz.xyw vf01,vf22,vf10 nop
|
||||
ftoi0 vf02,vf11 lq vf11,IN_RGBA(1,vi02)
|
||||
mulq.xyz vf03,vf12,q lq.xy vf12,IN_UV(1,vi02)
|
||||
add vf04,vf04,vf05 iaddiu vi02,vi02,numInAttribs
|
||||
add.w vf05,vf26,vf10 div q,vf27w,vf01w
|
||||
miniy.w vf01,vf01,vf06 lq vf10,IN_VERTEX(1,vi02)
|
||||
mulaw acc,vf23,vf00 sqi vf03,(vi04++)
|
||||
ftoi4 vf07,vf04 sqi vf02,(vi04++)
|
||||
nop nop
|
||||
maxx.w vf04,vf01,vf06 mr32.z vf12,vf00
|
||||
maddax acc,vf20,vf10 ibne vi02,vi03,ProcessLoop
|
||||
madday acc,vf21,vf10 sqi vf07,(vi04++)
|
||||
|
||||
nop xgkick vi12 ; draw kick
|
||||
nop iadd vi15,vi00,vi12 ; swap output buffers
|
||||
nop iadd vi12,vi00,vi13
|
||||
nop b End
|
||||
nop iadd vi13,vi00,vi15
|
||||
@@ -0,0 +1,65 @@
|
||||
.equ light, 0x3d0
|
||||
.equ matrix0, 0x3f0
|
||||
.equ matrix1, 0x3f1
|
||||
.equ matrix2, 0x3f2
|
||||
.equ matrix3, 0x3f3
|
||||
.equ xyzwScale, 0x3f4
|
||||
.equ xyzwOffset, 0x3f5
|
||||
.equ clipConsts, 0x3f6
|
||||
.equ gifTag, 0x3fa
|
||||
.equ colorScale, 0x3fb
|
||||
.equ surfaceProps, 0x3fc
|
||||
.equ codeSwitch, 0x3ff
|
||||
|
||||
;; FCAND masks -- if register is 0, the whole poly is out
|
||||
.equ posXn, (0x041041)
|
||||
.equ negXn, (0x082082)
|
||||
.equ posYn, (0x104104)
|
||||
.equ negYn, (0x208208)
|
||||
.equ posZn, (0x410410)
|
||||
.equ negZn, (0x820820)
|
||||
.equ posXn3, (posXn&0x3FFFF)
|
||||
.equ negXn3, (negXn&0x3FFFF)
|
||||
.equ posYn3, (posYn&0x3FFFF)
|
||||
.equ negYn3, (negYn&0x3FFFF)
|
||||
.equ posZn3, (posZn&0x3FFFF)
|
||||
.equ negZn3, (negZn&0x3FFFF)
|
||||
.equ posXn2, (posXn&0xFFF)
|
||||
.equ negXn2, (negXn&0xFFF)
|
||||
.equ posYn2, (posYn&0xFFF)
|
||||
.equ negYn2, (negYn&0xFFF)
|
||||
.equ posZn2, (posZn&0xFFF)
|
||||
.equ negZn2, (negZn&0xFFF)
|
||||
.equ posXn1, (posXn&0x3F)
|
||||
.equ negXn1, (negXn&0x3F)
|
||||
.equ posYn1, (posYn&0x3F)
|
||||
.equ negYn1, (negYn&0x3F)
|
||||
.equ posZn1, (posZn&0x3F)
|
||||
.equ negZn1, (negZn&0x3F)
|
||||
|
||||
|
||||
;; FCOR masks -- if register is 1, the whole poly is in
|
||||
.equ posXo, (0xFBEFBE)
|
||||
.equ negXo, (0xF7DF7D)
|
||||
.equ posYo, (0xEFBEFB)
|
||||
.equ negYo, (0xDF7DF7)
|
||||
.equ posZo, (0xBEFBEF)
|
||||
.equ negZo, (0x7DF7DF)
|
||||
.equ posXo3, (posXo|0xFC0000)
|
||||
.equ negXo3, (negXo|0xFC0000)
|
||||
.equ posYo3, (posYo|0xFC0000)
|
||||
.equ negYo3, (negYo|0xFC0000)
|
||||
.equ posZo3, (posZo|0xFC0000)
|
||||
.equ negZo3, (negZo|0xFC0000)
|
||||
.equ posXo2, (posXo|0xFFF000)
|
||||
.equ negXo2, (negXo|0xFFF000)
|
||||
.equ posYo2, (posYo|0xFFF000)
|
||||
.equ negYo2, (negYo|0xFFF000)
|
||||
.equ posZo2, (posZo|0xFFF000)
|
||||
.equ negZo2, (negZo|0xFFF000)
|
||||
.equ posXo1, (posXo|0xFFFFC0)
|
||||
.equ negXo1, (negXo|0xFFFFC0)
|
||||
.equ posYo1, (posYo|0xFFFFC0)
|
||||
.equ negYo1, (negYo|0xFFFFC0)
|
||||
.equ posZo1, (posZo|0xFFFFC0)
|
||||
.equ negZo1, (negZo|0xFFFFC0)
|
||||
@@ -0,0 +1,123 @@
|
||||
.equ vertexTop, 0x3f0
|
||||
.equ numInAttribs, 3
|
||||
.equ numOutAttribs, 3
|
||||
.equ numOutBuf, 2
|
||||
.equ vertCount, ((vertexTop-numOutBuf)/(numInAttribs*2+numOutAttribs*numOutBuf))
|
||||
.equ offset, (vertCount*numInAttribs)
|
||||
.equ outBuf1, (2*offset)
|
||||
;.equ outSize, ((vertexTop-outBuf1-numOutBuf)/numOutBuf)
|
||||
.equ outSize, (1 + vertCount*numOutAttribs)
|
||||
.equ outBuf2, (outBuf1+outSize)
|
||||
|
||||
.include "defines.inc"
|
||||
|
||||
#define IN_VERTEX(n,r) 0 + (n)*numInAttribs(r)
|
||||
#define IN_UV(n,r) 1 + (n)*numInAttribs(r)
|
||||
#define IN_RGBA(n,r) 2 + (n)*numInAttribs(r)
|
||||
|
||||
#define OUT_STQ(n,r) 0 + (n)*numOutAttribs(r)
|
||||
#define OUT_RGBA(n,r) 1 + (n)*numOutAttribs(r)
|
||||
#define OUT_XYZ(n,r) 2 + (n)*numOutAttribs(r)
|
||||
|
||||
.balign 16,0
|
||||
|
||||
.global vu1_im2d
|
||||
vu1_im2d:
|
||||
|
||||
DMAret *
|
||||
MPG 0, *
|
||||
.vu
|
||||
start:
|
||||
nop iaddiu vi12,vi00,outBuf1
|
||||
nop iaddiu vi13,vi00,outBuf2
|
||||
nop lq vf04,xyzwOffset(vi00)
|
||||
nop lq vf05,colorScale(vi00)
|
||||
nop lq vf06,colorScale(vi00)
|
||||
restart:
|
||||
nop ilw.x vi09,codeSwitch(vi00) ; process switch
|
||||
nop xtop vi02 ; input pointer
|
||||
nop jr vi09
|
||||
nop xtop vi01 ; vertex count
|
||||
|
||||
|
||||
NoFog:
|
||||
nop xtop vi02 ; input pointer
|
||||
mulz.w vf01,vf00,vf00 lq vf13,IN_RGBA(0,vi02) ; clear ADC flag - load rgba
|
||||
nop lq.xyz vf11,IN_VERTEX(0,vi02) ; - load xyz
|
||||
nop lq.xyz vf02,IN_UV(0,vi02) ; - load uvq
|
||||
nop lq vf03,gifTag(vi00) ; - GIF tag
|
||||
itof0 vf13,vf13 xitop vi01 ; rgba to float - vertex count
|
||||
add.xy vf11,vf11,vf04 iaddiu vi05,vi00,0x4000 ; add xy offset
|
||||
mulz.xy vf02,vf02,vf02 iadd vi05,vi05,vi05 ; - EOP bit
|
||||
nop ior vi05,vi05,vi01 ; - enter vertex count
|
||||
nop sq vf03,0(vi12) ; - store GIF tag
|
||||
nop isw.x vi05,0(vi12)
|
||||
nop iaddiu vi03,vi12,1 ; - output pointer
|
||||
nop iadd vi05,vi03,vi01
|
||||
.rept numOutAttribs-1
|
||||
nop iadd vi05,vi05,vi01
|
||||
.endr
|
||||
NoFogLoop:
|
||||
mul vf03,vf13,vf05 lq.xyz vf12,IN_UV(1,vi02)
|
||||
nop lq vf13,IN_RGBA(1,vi02)
|
||||
ftoi4.xyz vf01,vf11 lq.xyz vf11,IN_VERTEX(1,vi02)
|
||||
nop iaddiu vi02,vi02,numInAttribs
|
||||
ftoi0 vf03,vf03 iaddiu vi03,vi03,numOutAttribs
|
||||
itof0 vf13,vf13 sq vf02,OUT_STQ(-1,vi03)
|
||||
add.xy vf11,vf11,vf04 sq vf01,OUT_XYZ(-1,vi03)
|
||||
mulz.xy vf02,vf12,vf12 ibne vi03,vi05,NoFogLoop
|
||||
addx.z vf02,vf12,vf00 sq vf03,OUT_RGBA(-1,vi03)
|
||||
nop b End
|
||||
nop nop
|
||||
|
||||
|
||||
Fog:
|
||||
nop loi 255.0
|
||||
nop xtop vi02 ; input pointer
|
||||
nop lq vf21,IN_VERTEX(0,vi02) ; - load xyzw
|
||||
nop lq vf13,IN_RGBA(0,vi02) ; - load rgba
|
||||
nop lq.xyz vf02,IN_UV(0,vi02) ; - load uvq
|
||||
addax acc,vf04,vf00 lq vf03,gifTag(vi00) ; - GIF tag
|
||||
madd vf21,vf05,vf21 xitop vi01 ; - vertex count
|
||||
itof0 vf13,vf13 iaddiu vi05,vi00,0x4000 ;
|
||||
nop iadd vi05,vi05,vi05 ; - EOP bit
|
||||
nop ior vi05,vi05,vi01 ; - enter vertex count
|
||||
minii.w vf11,vf21,i sq vf03,0(vi12) ; - store GIF tag
|
||||
addx.xyz vf01,vf21,vf00 isw.x vi05,0(vi12)
|
||||
nop iaddiu vi03,vi12,1 ; - output pointer
|
||||
nop iadd vi05,vi03,vi01
|
||||
.rept numInAttribs-1
|
||||
nop iadd vi05,vi05,vi01
|
||||
.endr
|
||||
FogLoop:
|
||||
mul vf03,vf13,vf06 nop
|
||||
addax acc,vf04,vf00 lq vf21,IN_VERTEX(1,vi02)
|
||||
maxw.w vf01,vf11,vf00 nop
|
||||
mulz.xy vf02,vf02,vf02 lq vf13,IN_RGBA(1,vi02)
|
||||
ftoi0 vf03,vf03 lq.xyz vf12,IN_UV(1,vi02)
|
||||
madd vf21,vf05,vf21 iaddiu vi02,vi02,numInAttribs
|
||||
ftoi4 vf01,vf01 iaddiu vi03,vi03,numOutAttribs
|
||||
itof0 vf13,vf13 sq vf02,OUT_STQ(-1,vi03)
|
||||
addx vf02,vf12,vf00 sq vf03,OUT_RGBA(-1,vi03)
|
||||
minii.w vf11,vf21,i ibne vi03,vi05,FogLoop
|
||||
addx.xyz vf01,vf21,vf00 sq vf01,OUT_XYZ(-1,vi03)
|
||||
nop b End
|
||||
nop nop
|
||||
|
||||
|
||||
End:
|
||||
nop xgkick vi12
|
||||
nop iadd vi15,vi00,vi12
|
||||
nop[e] iadd vi12,vi00,vi13
|
||||
nop iadd vi13,vi00,vi15
|
||||
nop b restart
|
||||
nop nop
|
||||
|
||||
.EndMPG
|
||||
.EndDmaData
|
||||
|
||||
|
||||
.global vu1_im2d_desc
|
||||
vu1_im2d_desc:
|
||||
.word NoFog, 0, 0, 0
|
||||
.word Fog, 0, 0, 0
|
||||
@@ -0,0 +1,125 @@
|
||||
.equ vertexTop, 0x3f0
|
||||
.equ numInAttribs, 3
|
||||
.equ numOutAttribs, 3
|
||||
.equ numOutBuf, 2
|
||||
.equ vertCount, ((vertexTop-numOutBuf)/(numInAttribs*2+numOutAttribs*numOutBuf))
|
||||
.equ offset, (vertCount*numInAttribs)
|
||||
.equ outBuf1, (2*offset)
|
||||
;.equ outSize, ((vertexTop-outBuf1-numOutBuf)/numOutBuf)
|
||||
.equ outSize, (1 + vertCount*numOutAttribs)
|
||||
.equ outBuf2, (outBuf1+outSize)
|
||||
|
||||
.equ clipVertCount, ((vertexTop-outBuf1-numOutBuf)/(numInAttribs+numOutAttribs*numOutBuf))
|
||||
.equ clipOutSize, (1 + clipVertCount*numOutAttribs)
|
||||
.equ clipOutBuf2, (outBuf1+clipOutSize)
|
||||
.equ clipBuf, (clipOutBuf2+clipOutSize)
|
||||
|
||||
; up to 9 verts => 7 tris per poly in worst case
|
||||
.equ clipVertLimitTL, (clipVertCount-21)
|
||||
.equ clipVertLimitTS, (clipVertCount-15) ;;; TODO: this crashes when i set it to -9 as it should be
|
||||
|
||||
.include "defines.inc"
|
||||
|
||||
#define IN_VERTEX(n,r) 0 + (n)*numInAttribs(r)
|
||||
#define IN_UV(n,r) 1 + (n)*numInAttribs(r)
|
||||
#define IN_RGBA(n,r) 2 + (n)*numInAttribs(r)
|
||||
|
||||
#define OUT_STQ(n,r) 0 + (n)*numOutAttribs(r)
|
||||
#define OUT_RGBA(n,r) 1 + (n)*numOutAttribs(r)
|
||||
#define OUT_XYZ(n,r) 2 + (n)*numOutAttribs(r)
|
||||
|
||||
.balign 16,0
|
||||
|
||||
.global vu1_im3d
|
||||
vu1_im3d:
|
||||
|
||||
DMAret *
|
||||
MPG 0, *
|
||||
.vu
|
||||
start:
|
||||
nop ilw.y vi12,codeSwitch(vi00)
|
||||
nop ilw.z vi13,codeSwitch(vi00)
|
||||
nop lq vf28,matrix0(vi00)
|
||||
nop lq vf29,matrix1(vi00)
|
||||
nop lq vf30,matrix2(vi00)
|
||||
nop lq vf31,matrix3(vi00)
|
||||
nop lq vf27,xyzwScale(vi00)
|
||||
nop lq vf26,xyzwOffset(vi00)
|
||||
nop lq vf25,colorScale(vi00)
|
||||
nop lq vf24,clipConsts(vi00)
|
||||
restart:
|
||||
nop ilw.x vi09,codeSwitch(vi00) ; process switch
|
||||
|
||||
;; Calculate end of input buffer with vertex count rounded up to multiple of 4
|
||||
;; Note that the maximum vertex count is always a multiple of 4 so this is always legal
|
||||
nop xtop vi02 ; input pointer
|
||||
nop xitop vi01 ; vertex count
|
||||
nop iaddiu vi03,vi01,3
|
||||
nop iaddiu vi04,vi00,~3
|
||||
nop iand vi04,vi03,vi04 ; round up vertex count
|
||||
nop iadd vi03,vi02,vi04
|
||||
.rept numInAttribs-1
|
||||
nop iadd vi03,vi03,vi04
|
||||
.endr
|
||||
|
||||
;; Convert colors to float
|
||||
nop iaddiu vi02,vi02,4*numInAttribs
|
||||
nop lq vf01,IN_RGBA(0-4,vi02)
|
||||
nop lq vf02,IN_RGBA(1-4,vi02)
|
||||
nop lq vf03,IN_RGBA(2-4,vi02)
|
||||
nop lq vf04,IN_RGBA(3-4,vi02)
|
||||
itof0 vf01,vf01 nop
|
||||
itof0 vf02,vf02 nop
|
||||
itof0 vf03,vf03 nop
|
||||
itof0 vf04,vf04 nop
|
||||
PreprocLoop:
|
||||
mul vf05,vf01,vf25 lq vf01,IN_RGBA(0,vi02)
|
||||
mul vf06,vf02,vf25 lq vf02,IN_RGBA(1,vi02)
|
||||
mul vf07,vf03,vf25 lq vf03,IN_RGBA(2,vi02)
|
||||
mul vf08,vf04,vf25 lq vf04,IN_RGBA(3,vi02)
|
||||
itof0 vf01,vf01 sq vf05,IN_RGBA(0-4,vi02)
|
||||
itof0 vf02,vf02 sq vf06,IN_RGBA(1-4,vi02)
|
||||
itof0 vf03,vf03 sq vf07,IN_RGBA(2-4,vi02)
|
||||
itof0 vf04,vf04 sq vf08,IN_RGBA(3-4,vi02)
|
||||
nop ibne vi02,vi03,PreprocLoop
|
||||
nop iaddiu vi02,vi02,4*numInAttribs
|
||||
|
||||
nop jr vi09
|
||||
nop nop
|
||||
|
||||
Process:
|
||||
#include "default_proc.vu"
|
||||
TLClip:
|
||||
.include "TLclip.vu"
|
||||
TSClip:
|
||||
.include "TSclip.vu"
|
||||
LLClip:
|
||||
.include "LLclip.vu"
|
||||
LSClip:
|
||||
.include "LSclip.vu"
|
||||
PointCull:
|
||||
.include "PointCull.vu"
|
||||
|
||||
End:
|
||||
nop[e] nop
|
||||
nop nop
|
||||
nop b restart
|
||||
nop nop
|
||||
|
||||
.include "cliptri.vu"
|
||||
.include "clipline.vu"
|
||||
#include "default_clipproc.vu"
|
||||
|
||||
.EndMPG
|
||||
.EndDmaData
|
||||
|
||||
;; indexed by PrimitiveType
|
||||
.global vu1_im3d_desc
|
||||
vu1_im3d_desc:
|
||||
.word Process, outBuf1, outBuf2, 0 ; PRIMTYPENONE
|
||||
.word LLClip, outBuf1, outBuf2, 0 ; PRIMTYPELINELIST
|
||||
.word LSClip, outBuf1, clipOutBuf2, 0 ; PRIMTYPEPOLYLINE
|
||||
.word TLClip, outBuf1, clipOutBuf2, 0 ; PRIMTYPETRILIST
|
||||
.word TSClip, outBuf1, clipOutBuf2, 0 ; PRIMTYPETRISTRIP
|
||||
.word 0, 0, 0, 0 ; PRIMTYPETRIFAN TODO
|
||||
.word PointCull, outBuf1, outBuf2, 0 ; PRIMTYPEPOINTLIST
|
||||
@@ -0,0 +1,106 @@
|
||||
;;; Register usage:
|
||||
;; vf20 light color
|
||||
;; vf21 light direction
|
||||
;; vf23 surfaceProps
|
||||
|
||||
Lighting:
|
||||
nop iaddiu vi08,vi00,light
|
||||
nop lq vf23,surfaceProps(vi00)
|
||||
LightLoop:
|
||||
nop ilw.w vi15,0(vi08) ; load light type
|
||||
nop lqi.xyz vf20,(vi08++) ; light color
|
||||
nop ibeq vi15,vi00,PostLighting
|
||||
nop xtop vi02 ; input pointer
|
||||
nop iaddiu vi15,vi15,LightSwitch
|
||||
nop jr vi15
|
||||
LightSwitch:
|
||||
;; Light type dispatch table
|
||||
nop nop
|
||||
nop b AmbientLight
|
||||
nop nop
|
||||
nop b DirectLight
|
||||
nop lqi.xyz vf21,(vi08++) ; light direction
|
||||
|
||||
;; Apply Ambient light
|
||||
AmbientLight:
|
||||
mulx.xyz vf20,vf20,vf23 iaddiu vi02,vi02,4*numInAttribs
|
||||
nop lq vf01,IN_RGBA(0-4,vi02)
|
||||
nop lq vf02,IN_RGBA(1-4,vi02)
|
||||
nop lq vf03,IN_RGBA(2-4,vi02)
|
||||
nop lq vf04,IN_RGBA(3-4,vi02)
|
||||
AmbientLoop:
|
||||
add vf05,vf01,vf20 lq vf01,IN_RGBA(0,vi02)
|
||||
add vf06,vf02,vf20 lq vf02,IN_RGBA(1,vi02)
|
||||
add vf07,vf03,vf20 lq vf03,IN_RGBA(2,vi02)
|
||||
add vf08,vf04,vf20 lq vf04,IN_RGBA(3,vi02)
|
||||
nop sq vf05,IN_RGBA(0-4,vi02)
|
||||
nop sq vf06,IN_RGBA(1-4,vi02)
|
||||
nop sq vf07,IN_RGBA(2-4,vi02)
|
||||
nop sq vf08,IN_RGBA(3-4,vi02)
|
||||
nop ibne vi02,vi03,AmbientLoop
|
||||
nop iaddiu vi02,vi02,4*numInAttribs
|
||||
nop b LightLoop
|
||||
nop nop
|
||||
|
||||
;; Apply Directional light
|
||||
DirectLight:
|
||||
sub.xyz vf21,vf00,vf21 lq vf01,IN_NORMAL(0,vi02) ; flip light directio
|
||||
mulz.xyz vf20,vf20,vf23 lq vf02,IN_NORMAL(1,vi02) ; multiply color by surfProps
|
||||
nop lq vf03,IN_NORMAL(2,vi02)
|
||||
nop lq vf04,IN_NORMAL(3,vi02)
|
||||
mul.xyz vf01,vf01,vf21 nop
|
||||
mul.xyz vf02,vf02,vf21 nop
|
||||
mul.xyz vf03,vf03,vf21 nop
|
||||
mul.xyz vf04,vf04,vf21 nop
|
||||
addy.x vf11,vf01,vf01 nop
|
||||
addx.y vf11,vf02,vf02 nop
|
||||
addx.z vf11,vf03,vf03 nop
|
||||
addy.z vf04,vf04,vf04 mr32 vf09,vf04
|
||||
DirectLoop:
|
||||
addz.x vf10,vf11,vf01 lq vf01,IN_NORMAL(0+4,vi02)
|
||||
addz.y vf10,vf11,vf02 lq vf02,IN_NORMAL(1+4,vi02)
|
||||
addy.z vf10,vf11,vf03 lq vf03,IN_NORMAL(2+4,vi02)
|
||||
addz.w vf10,vf09,vf04 lq vf04,IN_NORMAL(3+4,vi02)
|
||||
mul.xyz vf01,vf01,vf21 lq vf05,IN_RGBA(0,vi02)
|
||||
mul.xyz vf02,vf02,vf21 lq vf06,IN_RGBA(1,vi02)
|
||||
mul.xyz vf03,vf03,vf21 lq vf07,IN_RGBA(2,vi02)
|
||||
maxx vf10,vf10,vf00 lq vf08,IN_RGBA(3,vi02)
|
||||
mul.xyz vf04,vf04,vf21 nop
|
||||
addy.x vf11,vf01,vf01 nop
|
||||
addax acc,vf05,vf00 nop
|
||||
maddx.xyz vf05,vf20,vf10 nop
|
||||
addax acc,vf06,vf00 mr32 vf09,vf04
|
||||
maddy.xyz vf06,vf20,vf10 nop
|
||||
addax acc,vf07,vf00 iaddiu vi02,vi02,4*numInAttribs
|
||||
maddz.xyz vf07,vf20,vf10 sq vf05,IN_RGBA(0-4,vi02)
|
||||
addax acc,vf08,vf00 nop
|
||||
maddw.xyz vf08,vf20,vf10 sq vf06,IN_RGBA(1-4,vi02)
|
||||
addx.y vf11,vf02,vf02 nop
|
||||
addx.z vf11,vf03,vf03 sq vf07,IN_RGBA(2-4,vi02)
|
||||
addy.z vf04,vf04,vf04 ibne vi02,vi03,DirectLoop
|
||||
nop sq vf08,IN_RGBA(3-4,vi02)
|
||||
nop b LightLoop
|
||||
nop nop
|
||||
|
||||
;;; Clamp lighting and multiply by material color
|
||||
PostLighting:
|
||||
nop loi 255.0
|
||||
nop lq vf01,IN_RGBA(0,vi02)
|
||||
nop lq vf02,IN_RGBA(1,vi02)
|
||||
nop lq vf03,IN_RGBA(2,vi02)
|
||||
nop lq vf04,IN_RGBA(3,vi02)
|
||||
minii vf05,vf01,i iaddiu vi02,vi02,4*numInAttribs
|
||||
minii vf06,vf02,i nop
|
||||
minii vf07,vf03,i nop
|
||||
minii vf08,vf04,i nop
|
||||
PostLightLoop:
|
||||
mul vf05,vf05,vf25 lq vf01,IN_RGBA(0,vi02)
|
||||
mul vf06,vf06,vf25 lq vf02,IN_RGBA(1,vi02)
|
||||
mul vf07,vf07,vf25 lq vf03,IN_RGBA(2,vi02)
|
||||
mul vf08,vf08,vf25 lq vf04,IN_RGBA(3,vi02)
|
||||
minii vf05,vf01,i sq vf05,IN_RGBA(0-4,vi02)
|
||||
minii vf06,vf02,i sq vf06,IN_RGBA(1-4,vi02)
|
||||
minii vf07,vf03,i sq vf07,IN_RGBA(2-4,vi02)
|
||||
minii vf08,vf04,i sq vf08,IN_RGBA(3-4,vi02)
|
||||
nop ibne vi02,vi03,PostLightLoop
|
||||
nop iaddiu vi02,vi02,4*numInAttribs
|
||||
Reference in New Issue
Block a user