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*"
|
filter "configurations:Release*"
|
||||||
defines { "NDEBUG" }
|
defines { "NDEBUG" }
|
||||||
optimize "On"
|
optimize "On"
|
||||||
filter "configurations:ReleaseStatic"
|
-- filter "configurations:ReleaseStatic"
|
||||||
staticruntime("On")
|
-- staticruntime("On")
|
||||||
|
|
||||||
filter { "platforms:*null" }
|
filter { "platforms:*null" }
|
||||||
defines { "RW_NULL" }
|
defines { "RW_NULL" }
|
||||||
@@ -119,6 +119,16 @@ workspace "librw"
|
|||||||
Libdir = "lib/%{cfg.platform}/%{cfg.buildcfg}"
|
Libdir = "lib/%{cfg.platform}/%{cfg.buildcfg}"
|
||||||
Bindir = "bin/%{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"
|
project "librw"
|
||||||
kind "StaticLib"
|
kind "StaticLib"
|
||||||
targetname "rw"
|
targetname "rw"
|
||||||
@@ -128,6 +138,10 @@ project "librw"
|
|||||||
files { "src/*/*.*" }
|
files { "src/*/*.*" }
|
||||||
filter { "platforms:*gl3" }
|
filter { "platforms:*gl3" }
|
||||||
files { "src/gl/glad/*.*" }
|
files { "src/gl/glad/*.*" }
|
||||||
|
filter { "platforms:*ps2" }
|
||||||
|
vucode()
|
||||||
|
files { "src/ps2/vu1/*.dsm" }
|
||||||
|
includedirs { "src/ps2/vu1" }
|
||||||
|
|
||||||
project "dumprwtree"
|
project "dumprwtree"
|
||||||
kind "ConsoleApp"
|
kind "ConsoleApp"
|
||||||
@@ -194,15 +208,6 @@ function skeltool(dir)
|
|||||||
findlibs()
|
findlibs()
|
||||||
end
|
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"
|
project "playground"
|
||||||
kind "WindowedApp"
|
kind "WindowedApp"
|
||||||
characterset ("MBCS")
|
characterset ("MBCS")
|
||||||
@@ -272,18 +277,18 @@ project "ska2anm"
|
|||||||
findlibs()
|
findlibs()
|
||||||
removeplatforms { "*gl3", "*d3d9", "*ps2" }
|
removeplatforms { "*gl3", "*d3d9", "*ps2" }
|
||||||
|
|
||||||
project "ps2test"
|
--project "ps2test"
|
||||||
kind "ConsoleApp"
|
-- kind "ConsoleApp"
|
||||||
targetdir (Bindir)
|
-- targetdir (Bindir)
|
||||||
vucode()
|
-- vucode()
|
||||||
removeplatforms { "*gl3", "*d3d9", "*null" }
|
-- removeplatforms { "*gl3", "*d3d9", "*null" }
|
||||||
targetextension '.elf'
|
-- targetextension '.elf'
|
||||||
includedirs { "." }
|
-- includedirs { "." }
|
||||||
files { "tools/ps2test/*.cpp",
|
-- files { "tools/ps2test/*.cpp",
|
||||||
"tools/ps2test/vu/*.dsm",
|
-- "tools/ps2test/vu/*.dsm",
|
||||||
"tools/ps2test/*.h" }
|
-- "tools/ps2test/*.h" }
|
||||||
libdirs { "$(PS2SDK)/ee/lib" }
|
-- libdirs { "$(PS2SDK)/ee/lib" }
|
||||||
links { "librw" }
|
-- links { "librw" }
|
||||||
|
|
||||||
--project "ps2rastertest"
|
--project "ps2rastertest"
|
||||||
-- kind "ConsoleApp"
|
-- kind "ConsoleApp"
|
||||||
|
|||||||
@@ -948,6 +948,9 @@ ObjPipeline::init(void)
|
|||||||
this->groupPipeline = nil;
|
this->groupPipeline = nil;
|
||||||
this->impl.instance = objInstance;
|
this->impl.instance = objInstance;
|
||||||
this->impl.uninstance = objUninstance;
|
this->impl.uninstance = objUninstance;
|
||||||
|
#ifdef RW_PS2
|
||||||
|
this->impl.render = defaultAtomicRender;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjPipeline*
|
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 {
|
namespace rw {
|
||||||
|
|
||||||
#ifdef RW_PS2
|
#ifdef RW_PS2
|
||||||
@@ -277,5 +282,44 @@ Texture *readNativeTexture(Stream *stream);
|
|||||||
void writeNativeTexture(Texture *tex, Stream *stream);
|
void writeNativeTexture(Texture *tex, Stream *stream);
|
||||||
uint32 getSizeNativeTexture(Texture *tex);
|
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 {
|
namespace rw {
|
||||||
|
|
||||||
|
#ifdef RW_PS2
|
||||||
|
typedef uint128_t uint128;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ps2 {
|
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);
|
Raster *rasterCreate(Raster *raster);
|
||||||
uint8 *rasterLock(Raster*, int32 level, int32 lockMode);
|
uint8 *rasterLock(Raster*, int32 level, int32 lockMode);
|
||||||
void rasterUnlock(Raster*, int32 level);
|
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