starting work on ps2 driver

This commit is contained in:
aap 2017-08-12 10:25:25 +02:00
parent e5c2a66bd5
commit aec8c202c6
24 changed files with 1843 additions and 61 deletions

View File

@ -12,8 +12,8 @@ workspace "librw"
"win-amd64-null", "win-amd64-gl3", "win-amd64-d3d9" }
filter { "system:linux" }
platforms { "linux-x86-null", "linux-x86-gl3",
"linux-amd64-null", "linux-amd64-gl3" }
-- TODO: ps2
"linux-amd64-null", "linux-amd64-gl3",
"ps2" }
filter {}
filter "configurations:Debug"
@ -31,8 +31,12 @@ workspace "librw"
defines { "RW_GL3" }
filter { "platforms:*d3d9" }
defines { "RW_D3D9" }
filter { "platforms:*ps2" }
filter { "platforms:ps2" }
defines { "RW_PS2" }
toolset "gcc"
gccprefix 'ee-'
buildoptions { "-nostdlib", "-fno-common" }
includedirs { "$(PS2SDK)/ee/include", "$(PS2SDK)/common/include" }
filter { "platforms:*amd64*" }
architecture "x86_64"
@ -110,9 +114,35 @@ function skeltool(dir)
findlibs()
end
function vucode()
filter "files:**.dsm"
buildcommands {
'cpp "%{file.relpath}" | dvp-as -o "%{cfg.objdir}/%{file.basename}.o"'
}
buildoutputs { '%{cfg.objdir}/%{file.basename}.o' }
filter {}
end
project "clumpview"
kind "WindowedApp"
characterset ("MBCS")
skeltool("clumpview")
flags { "WinMain" }
removeplatforms { "*null" }
project "ps2test"
kind "ConsoleApp"
targetdir (Bindir)
vucode()
removeplatforms { "*gl3", "*d3d9", "*null" }
targetextension '.elf'
includedirs { "." }
files { "tools/ps2test/*.cpp",
"tools/ps2test/vu/*.dsm",
"tools/ps2test/*.h" }
linkoptions '$(PS2SDK)/ee/startup/crt0.o'
linkoptions { '-mno-crt0', "-T$(PS2SDK)/ee/startup/linkfile" }
libdirs { "$(PS2SDK)/ee/lib" }
links { "librw" }
-- "c -lc" is a hack because we need -lc twice for some reason
links { "c -lc", "kernel", "mf" }

17
src/base.cpp Normal file → Executable file
View File

@ -261,6 +261,7 @@ Matrix::translate(V3d *translation, CombineOp op)
Matrix tmp;
Matrix trans = identMat;
trans.pos = *translation;
trans.flags &= ~IDENTITY;
switch(op){
case COMBINEREPLACE:
*this = trans;
@ -483,22 +484,6 @@ Matrix::identityError(void)
return dot(r,r) + dot(u,u) + dot(a,a) + dot(pos,pos);
}
#if 0
bool32
Matrix::isIdentity(void)
{
return matrixIsIdentity((float32*)this);
}
void
Matrix::transpose(Matrix *m1, Matrix *m2)
{
matrixTranspose((float32*)m1, (float32*)m2);
}
#endif
#define PSEP_C '/'
#define PSEP_S "/"
#ifndef _WIN32

56
src/camera.cpp Normal file → Executable file
View File

@ -184,7 +184,21 @@ cameraSync(ObjectWithFrame *obj)
* and to clip space are handled by separate matrices there.
* On these platforms the two matrices are built in the platform's
* beginUpdate function.
* On the PS2 the 1/2 translation/shear is removed again on the VU1.
* On the PS2 the z- and w-rows are the same and the
* 1/2 translation/shear is removed again on the VU1 by
* subtracting the w-row/2 from the x- and y-rows.
*
* perspective:
* 1/2w 0 ox/2w -ox/2w
* 0 -1/2h -oy/2h oy/2h
* 0 0 1 0
* 0 0 1 0
*
* parallel:
* 1/2w 0 ox/2w -ox/2w
* 0 -1/2h -oy/2h oy/2h
* 0 0 1 0
* 0 0 0 1
*
* RW builds this matrix directly without using explicit
* inversion and matrix multiplication.
@ -193,8 +207,8 @@ cameraSync(ObjectWithFrame *obj)
Camera *cam = (Camera*)obj;
Matrix inv, proj;
Matrix::invertOrthonormal(&inv, cam->getFrame()->getLTM());
float32 xscl = 2.0f/cam->viewWindow.x;
float32 yscl = 2.0f/cam->viewWindow.y;
float32 xscl = 1.0f/(2.0f*cam->viewWindow.x);
float32 yscl = 1.0f/(2.0f*cam->viewWindow.y);
proj.flags = 0;
proj.right.x = xscl;
@ -351,6 +365,8 @@ Camera::setNearPlane(float32 near)
{
this->nearPlane = near;
calczShiftScale(this);
if(this->getFrame())
this->getFrame()->updateObjects();
}
void
@ -358,6 +374,32 @@ Camera::setFarPlane(float32 far)
{
this->farPlane = far;
calczShiftScale(this);
if(this->getFrame())
this->getFrame()->updateObjects();
}
void
Camera::setViewWindow(const V2d *window)
{
this->viewWindow = *window;
if(this->getFrame())
this->getFrame()->updateObjects();
}
void
Camera::setViewOffset(const V2d *offset)
{
this->viewOffset = *offset;
if(this->getFrame())
this->getFrame()->updateObjects();
}
void
Camera::setProjection(int32 proj)
{
this->projection = proj;
if(this->getFrame())
this->getFrame()->updateObjects();
}
int32
@ -433,10 +475,12 @@ Camera::streamGetSize(void)
void
Camera::setFOV(float32 fov, float32 ratio)
{
V2d v;
float32 a = tan(fov*3.14159f/360.0f);
this->viewWindow.x = a;
this->viewWindow.y = a/ratio;
this->viewOffset.set(0.0f, 0.0f);
v.set(a, a/ratio);
this->setViewWindow(&v);
v.set(0.0f, 0.0f);
this->setViewOffset(&v);
}
}

0
src/d3d/d3ddriver.cpp → src/d3d/d3ddevice.cpp Normal file → Executable file
View File

8
src/engine.cpp Normal file → Executable file
View File

@ -74,7 +74,9 @@ Engine::open(void)
// Initialize device
// Device and possibly OS specific!
#ifdef RW_GL3
#ifdef RW_PS2
engine->device = ps2::renderdevice;
#elif RW_GL3
engine->device = gl3::renderdevice;
#elif RW_D3D9
engine->device = d3d::renderdevice;
@ -196,7 +198,7 @@ rasterToImage(Raster*)
}
int
devicesystem(DeviceReq req, void *arg0)
deviceSystem(DeviceReq req, void *arg0)
{
return 1;
}
@ -210,7 +212,7 @@ Device renderdevice = {
null::setRenderState,
null::getRenderState,
null::im2DRenderIndexedPrimitive,
null::devicesystem
null::deviceSystem
};
}

0
src/gl/gl3driver.cpp → src/gl/gl3device.cpp Normal file → Executable file
View File

2
src/matfx.cpp Normal file → Executable file
View File

@ -145,7 +145,7 @@ MatFX::get(Material *m)
return *PLUGINOFFSET(MatFX*, m, matFXGlobals.materialOffset);
}
uint32
int32
MatFX::getEffectIndex(uint32 type)
{
for(int i = 0; i < 2; i++)

1
src/pipeline.cpp Normal file → Executable file
View File

@ -7,7 +7,6 @@
#include "rwplg.h"
#include "rwpipeline.h"
#include "rwobjects.h"
#include "ps2/rwps2.h"
#define COLOR_ARGB(a,r,g,b) \
((uint32)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff)))

1
src/ps2/pds.cpp Normal file → Executable file
View File

@ -7,6 +7,7 @@
#include "../rwplg.h"
#include "../rwpipeline.h"
#include "../rwobjects.h"
#include "../rwengine.h"
#include "../rwanim.h"
#include "../rwplugins.h"
#include "rwps2.h"

47
src/ps2/ps2.cpp Normal file → Executable file
View File

@ -92,7 +92,6 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
uint32 buf[2];
stream->read(buf, 8);
instance->dataSize = buf[0];
instance->arePointersFixed = buf[1];
// TODO: force alignment
instance->data = new uint8[instance->dataSize];
#ifdef RW_PS2
@ -100,6 +99,10 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
assert(a % 0x10 == 0);
#endif
stream->read(instance->data, instance->dataSize);
#ifdef RW_PS2
if(!buf[1])
fixDmaOffsets(instance);
#endif
instance->material = geometry->meshHeader->mesh[i].material;
// sizedebug(instance);
}
@ -118,13 +121,15 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
for(uint32 i = 0; i < header->numMeshes; i++){
InstanceData *instance = &header->instanceMeshes[i];
if(instance->arePointersFixed == 2)
unfixDmaOffsets(instance);
uint32 buf[2];
buf[0] = instance->dataSize;
buf[1] = instance->arePointersFixed;
buf[1] = unfixDmaOffsets(instance);
stream->write(buf, 8);
stream->write(instance->data, instance->dataSize);
#ifdef RW_PS2
if(!buf[1])
fixDmaOffsets(instance);
#endif
}
return stream;
}
@ -157,13 +162,11 @@ registerNativeDataPlugin(void)
getSizeNativeData);
}
// Patch DMA ref ADDR fields to point to the actual data.
#ifdef RW_PS2
void
fixDmaOffsets(InstanceData *inst)
{
if(inst->arePointersFixed)
return;
uint32 base = (uint32)inst->data;
uint32 *tag = (uint32*)inst->data;
for(;;){
@ -184,7 +187,6 @@ fixDmaOffsets(InstanceData *inst)
// DMAret
case 0x60000000:
// we're done
inst->arePointersFixed = 2;
return;
default:
@ -195,15 +197,17 @@ fixDmaOffsets(InstanceData *inst)
}
#endif
void
// Patch DMA ref ADDR fields to qword offsets and return whether
// no ref tags were found.
// Only under RW_PS2 are the addresses actually patched but we need
// the return value for streaming out.
bool32
unfixDmaOffsets(InstanceData *inst)
{
(void)inst;
bool32 norefs = 1;
#ifdef RW_PS2
if(inst->arePointersFixed != 2)
return;
uint32 base = (uint32)inst->data;
#endif
uint32 *tag = (uint32*)inst->data;
for(;;){
switch(tag[0]&0x70000000){
@ -215,23 +219,23 @@ unfixDmaOffsets(InstanceData *inst)
// DMAref
case 0x30000000:
norefs = 0;
// unfix address and jump to next
#ifdef RW_PS2
tag[1] = (tag[1] - base)>>4;
#endif
tag += 4;
break;
// DMAret
case 0x60000000:
// we're done
inst->arePointersFixed = 0;
return;
return norefs;
default:
fprintf(stderr, "error: unknown DMAtag %X\n", tag[0]);
return;
return norefs;
}
}
#endif
}
// Pipeline
@ -586,7 +590,6 @@ MatPipeline::instance(Geometry *g, InstanceData *inst, Mesh *m)
InstMeshInfo im = getInstMeshInfo(this, g, m);
inst->dataSize = (im.size+im.size2)<<4;
inst->arePointersFixed = im.numBrokenAttribs == 0;
// TODO: force alignment
inst->data = new uint8[inst->dataSize];
@ -685,6 +688,8 @@ MatPipeline::instance(Geometry *g, InstanceData *inst, Mesh *m)
if(this->instanceCB)
this->instanceCB(this, g, m, datap);
if(im.numBrokenAttribs)
fixDmaOffsets(inst);
}
uint8*
@ -766,6 +771,7 @@ objInstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
geo->flags |= Geometry::NATIVE;
}
/*
static void
printVertCounts(InstanceData *inst, int flag)
{
@ -794,6 +800,7 @@ printVertCounts(InstanceData *inst, int flag)
}
}
}
*/
static void
objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
@ -1241,6 +1248,7 @@ registerADCPlugin(void)
}
// misc stuff
/*
void
printDMA(InstanceData *inst)
@ -1300,6 +1308,7 @@ sizedebug(InstanceData *inst)
}
}
}
*/
}
}

41
src/ps2/ps2device.cpp Executable file
View File

@ -0,0 +1,41 @@
#ifdef RW_PS2
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include "../rwbase.h"
#include "../rwerror.h"
#include "../rwplg.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
namespace rw {
namespace ps2 {
Device renderdevice = {
16777215.0f, 0.0f,
null::beginUpdate,
null::endUpdate,
null::clearCamera,
null::showRaster,
null::setRenderState,
null::getRenderState,
null::im2DRenderIndexedPrimitive,
null::deviceSystem
};
}
}
#endif

20
src/ps2/rwps2.h Normal file → Executable file
View File

@ -1,15 +1,19 @@
namespace rw {
#ifdef RW_PS2
struct EngineStartParams
{
};
#endif
namespace ps2 {
void initializePlatform(void);
extern Device renderdevice;
struct InstanceData
{
// 0 - addresses in ref tags need fixing
// 1 - no ref tags, so no fixing
// set by the program:
// 2 - ref tags are fixed, need to unfix before stream write
uint32 arePointersFixed;
uint32 dataSize;
uint8 *data;
Material *material;
@ -57,10 +61,8 @@ void registerNativeDataPlugin(void);
void printDMA(InstanceData *inst);
void sizedebug(InstanceData *inst);
// only RW_PS2
void fixDmaOffsets(InstanceData *inst);
void unfixDmaOffsets(InstanceData *inst);
//
void fixDmaOffsets(InstanceData *inst); // only RW_PS2
int32 unfixDmaOffsets(InstanceData *inst);
struct PipeAttribute
{

3
src/rwengine.h Normal file → Executable file
View File

@ -140,6 +140,7 @@ namespace null {
void beginUpdate(Camera*);
void endUpdate(Camera*);
void clearCamera(Camera*, RGBA *col, uint32 mode);
void showRaster(Raster*);
void setRenderState(int32 state, uint32 value);
uint32 getRenderState(int32 state);
@ -154,7 +155,7 @@ namespace null {
void im2DRenderIndexedPrimitive(PrimitiveType,
void*, int32, void*, int32);
int deviceSystem(DeviceReq req);
int deviceSystem(DeviceReq req, void*);
extern Device renderdevice;
}

3
src/rwobjects.h Normal file → Executable file
View File

@ -624,6 +624,9 @@ struct Camera
void showRaster(void);
void setNearPlane(float32);
void setFarPlane(float32);
void setViewWindow(const V2d *window);
void setViewOffset(const V2d *offset);
void setProjection(int32 proj);
int32 frustumTestSphere(Sphere *s);
static Camera *streamRead(Stream *stream);
bool streamWrite(Stream *stream);

2
src/rwplugins.h Normal file → Executable file
View File

@ -130,7 +130,7 @@ struct MatFX
static void setEffects(Material *m, uint32 flags);
static uint32 getEffects(Material *m);
static MatFX *get(Material *m);
uint32 getEffectIndex(uint32 type);
int32 getEffectIndex(uint32 type);
void setBumpTexture(Texture *t);
void setBumpCoefficient(float32 coef);
void setEnvTexture(Texture *t);

7
src/world.cpp Normal file → Executable file
View File

@ -35,14 +35,19 @@ World::addLight(Light *light)
light->world = this;
if(light->getType() < Light::POINT){
this->directionalLights.append(&light->inWorld);
}else
}else{
this->lights.append(&light->inWorld);
if(light->getFrame())
light->getFrame()->updateObjects();
}
}
void
World::addCamera(Camera *cam)
{
cam->world = this;
if(cam->getFrame())
cam->getFrame()->updateObjects();
}
}

437
tools/ps2test/gs.h Executable file
View File

@ -0,0 +1,437 @@
#define GS_NONINTERLACED 0
#define GS_INTERLACED 1
#define GS_NTSC 2
#define GS_PAL 3
#define GS_VESA1A 0x1a
#define GS_VESA1B 0x1b
#define GS_VESA1C 0x1c
#define GS_VESA1D 0x1d
#define GS_VESA2A 0x2a
#define GS_VESA2B 0x2b
#define GS_VESA2C 0x2c
#define GS_VESA2D 0x2d
#define GS_VESA2E 0x2e
#define GS_VESA3B 0x3b
#define GS_VESA3C 0x3c
#define GS_VESA3D 0x3d
#define GS_VESA3E 0x3e
#define GS_VESA4A 0x4a
#define GS_VESA4B 0x4b
#define GS_DTV480P 0x50
#define GS_FIELD 0
#define GS_FRAME 1
#define GS_PSMCT32 0
#define GS_PSMCT24 1
#define GS_PSMCT16 2
#define GS_PSMCT16S 10
#define GS_PS_GPU24 18
#define GS_PSMZ32 0
#define GS_PSMZ24 1
#define GS_PSMZ16 2
#define GS_PSMZ16S 10
#define GS_ZTST_NEVER 0
#define GS_ZTST_ALWAYS 1
#define GS_ZTST_GREATER 2
#define GS_ZTST_GEQUAL 3
#define GS_PRIM_POINT 0
#define GS_PRIM_LINE 1
#define GS_PRIM_LINE_STRIP 2
#define GS_PRIM_TRI 3
#define GS_PRIM_TRI_STRIP 4
#define GS_PRIM_TRI_FAN 5
#define GS_PRIM_SPRITE 6
#define GS_PRIM_NO_SPEC 7
#define GS_IIP_FLAT 0
#define GS_IIP_GOURAUD 1
/* GS general purpose registers */
#define GS_PRIM 0x00
#define GS_RGBAQ 0x01
#define GS_ST 0x02
#define GS_UV 0x03
#define GS_XYZF2 0x04
#define GS_XYZ2 0x05
#define GS_TEX0_1 0x06
#define GS_TEX0_2 0x07
#define GS_CLAMP_1 0x08
#define GS_CLAMP_2 0x09
#define GS_FOG 0x0a
#define GS_XYZF3 0x0c
#define GS_XYZ3 0x0d
#define GS_TEX1_1 0x14
#define GS_TEX1_2 0x15
#define GS_TEX2_1 0x16
#define GS_TEX2_2 0x17
#define GS_XYOFFSET_1 0x18
#define GS_XYOFFSET_2 0x19
#define GS_PRMODECONT 0x1a
#define GS_PRMODE 0x1b
#define GS_TEXCLUT 0x1c
#define GS_SCANMSK 0x22
#define GS_MIPTBP1_1 0x34
#define GS_MIPTBP1_2 0x35
#define GS_MIPTBP2_1 0x36
#define GS_MIPTBP2_2 0x37
#define GS_TEXA 0x3b
#define GS_FOGCOL 0x3d
#define GS_TEXFLUSH 0x3f
#define GS_SCISSOR_1 0x40
#define GS_SCISSOR_2 0x41
#define GS_ALPHA_1 0x42
#define GS_ALPHA_2 0x43
#define GS_DIMX 0x44
#define GS_DTHE 0x45
#define GS_COLCLAMP 0x46
#define GS_TEST_1 0x47
#define GS_TEST_2 0x48
#define GS_PABE 0x49
#define GS_FBA_1 0x4a
#define GS_FBA_2 0x4b
#define GS_FRAME_1 0x4c
#define GS_FRAME_2 0x4d
#define GS_ZBUF_1 0x4e
#define GS_ZBUF_2 0x4f
#define GS_BITBLTBUF 0x50
#define GS_TRXPOS 0x51
#define GS_TRXREG 0x52
#define GS_TRXDIR 0x53
#define GS_HWREG 0x54
#define GS_SIGNAL 0x60
#define GS_FINISH 0x61
#define GS_LABEL 0x62
typedef union
{
struct {
uint64 EN1 : 1;
uint64 EN2 : 1;
uint64 CRTMD : 3;
uint64 MMOD : 1;
uint64 AMOD : 1;
uint64 SLBG : 1;
uint64 ALP : 8;
} f;
uint64 d;
} GsPmode;
#define GS_MAKE_PMODE(EN1,EN2,MMOD,AMOD,SLBG,ALP) \
(BIT64(EN1,0) | BIT64(EN2,1) | BIT64(1,2) | \
BIT64(MMOD,5) | BIT64(AMOD,6) | BIT64(SLBG,7) | BIT64(ALP,8))
typedef union
{
struct {
uint64 INT : 1;
uint64 FFMD : 1;
uint64 DPMS : 2;
} f;
uint64 d;
} GsSmode2;
#define GS_MAKE_SMODE2(INT,FFMD,DPMS) \
(BIT64(INT,0) | BIT64(FFMD,1) | BIT64(DPMS,2))
typedef union
{
struct {
uint64 FBP : 9;
uint64 FBW : 6;
uint64 PSM : 5;
uint64 : 12;
uint64 DBX : 11;
uint64 DBY : 11;
} f;
uint64 d;
} GsDispfb;
#define GS_MAKE_DISPFB(FBP,FBW,PSM,DBX,DBY) \
(BIT64(FBP,0) | BIT64(FBW,9) | BIT64(PSM,15) | \
BIT64(DBX,32) | BIT64(DBY,43))
typedef union
{
struct {
uint64 DX : 12;
uint64 DY : 11;
uint64 MAGH : 4;
uint64 MAGV : 2;
uint64 : 3;
uint64 DW : 12;
uint64 DH : 11;
} f;
uint64 d;
} GsDisplay;
#define GS_MAKE_DISPLAY(DX,DY,MAGH,MAGV,DW,DH) \
(BIT64(DX,0) | BIT64(DY,12) | BIT64(MAGH,23) | \
BIT64(MAGV,27) | BIT64(DW,32) | BIT64(DH,44))
typedef union
{
struct {
uint64 EXBP : 14;
uint64 EXBW : 6;
uint64 FBIN : 2;
uint64 WFFMD : 1;
uint64 EMODA : 2;
uint64 EMODC : 2;
uint64 : 5;
uint64 WDX : 11;
uint64 WDY : 11;
} f;
uint64 d;
} GsExtbuf;
#define GS_MAKE_EXTBUF(EXBP,EXBW,FBIN,WFFMD,EMODA,EMODC,WDX,WDY) \
(BIT64(EXBP,0) | BIT64(EXBW,14) | BIT64(FBIN,20) | \
BIT64(WFFMD,22) | BIT64(EMODA,23) | BIT64(EMODC,25) | \
BIT64(WDX,32) | BIT64(WDY,43))
typedef union
{
struct {
uint64 SX : 12;
uint64 SY : 11;
uint64 SMPH : 4;
uint64 SMPV : 2;
uint64 : 3;
uint64 WW : 12;
uint64 WH : 11;
} f;
uint64 d;
} GsExtdata;
#define GS_MAKE_EXTDATA(SX,SY,SMPH,SMPV,WW,WH) \
(BIT64(SX,0) | BIT64(SY,12) | BIT64(SMPH,23) | \
BIT64(SMPV,27) | BIT64(WW,32) | BIT64(WH,44))
typedef union
{
struct {
uint64 WRITE : 1;
} f;
uint64 d;
} GsExtwrite;
typedef union
{
struct {
uint64 R : 8;
uint64 G : 8;
uint64 B : 8;
} f;
uint64 d;
} GsBgcolor;
#define GS_MAKE_BGCOLOR(R,G,B) \
(BIT64(R,0) | BIT64(G,8) | BIT64(B,16))
typedef union
{
struct {
uint64 SIGNAL : 1;
uint64 FINISH : 1;
uint64 HSINT : 1;
uint64 VSINT : 1;
uint64 EDWINT : 1;
uint64 : 3;
uint64 FLUSH : 1;
uint64 RESET : 1;
uint64 : 2;
uint64 NFIELD : 1;
uint64 FIELD : 1;
uint64 FIFO : 2;
uint64 REV : 8;
uint64 ID : 8;
} f;
uint64 d;
} GsCsr;
#define GS_CSR_SIGNAL_O 0
#define GS_CSR_FINISH_O 1
#define GS_CSR_HSINT_O 2
#define GS_CSR_VSINT_O 3
#define GS_CSR_EDWINT_O 4
#define GS_CSR_FLUSH_O 8
#define GS_CSR_RESET_O 9
#define GS_CSR_NFIELD_O 12
#define GS_CSR_FIELD_O 13
#define GS_CSR_FIFO_O 14
#define GS_CSR_REV_O 16
#define GS_CSR_ID_O 24
typedef union
{
struct {
uint64 : 8;
uint64 SIGMSK : 1;
uint64 FINISHMSK : 1;
uint64 HSMSKMSK : 1;
uint64 VSMSKMSK : 1;
uint64 EDWMSKMSK : 1;
} f;
uint64 d;
} GsImr;
typedef union
{
struct {
uint64 DIR : 1;
} f;
uint64 d;
} GsBusdir;
typedef union
{
struct {
uint64 SIGID : 32;
uint64 LBLID : 32;
} f;
uint64 d;
} GsSiglblid;
typedef union
{
struct {
uint64 FBP : 9;
uint64 : 7;
uint64 FBW : 6;
uint64 : 2;
uint64 PSM : 6;
uint64 : 2;
uint64 FBMSK : 32;
} f;
uint64 d;
} GsFrame;
#define GS_MAKE_FRAME(FBP,FBW,PSM,FBMASK) \
(BIT64(FBP,0) | BIT64(FBW,16) | BIT64(PSM,24) | BIT64(FBMASK,32))
typedef union
{
struct {
uint64 ZBP : 9;
uint64 : 15;
uint64 PSM : 4;
uint64 : 4;
uint64 ZMSDK : 1;
} f;
uint64 d;
} GsZbuf;
#define GS_MAKE_ZBUF(ZBP,PSM,ZMSK) \
(BIT64(ZBP,0) | BIT64(PSM,24) | BIT64(ZMSK,32))
typedef union
{
struct {
uint64 OFX : 16;
uint64 : 16;
uint64 OFY : 16;
} f;
uint64 d;
} GsXyOffset;
#define GS_MAKE_XYOFFSET(OFX,OFY) \
(BIT64(OFX,0) | BIT64(OFY,32))
typedef union
{
struct {
uint64 SCAX0 : 11;
uint64 : 5;
uint64 SCAX1 : 11;
uint64 : 5;
uint64 SCAY0 : 11;
uint64 : 5;
uint64 SCAY1 : 11;
} f;
uint64 d;
} GsScissor;
#define GS_MAKE_SCISSOR(SCAX0,SCAX1,SCAY0,SCAY1) \
(BIT64(SCAX0,0) | BIT64(SCAX1,16) | BIT64(SCAY0,32) | BIT64(SCAY1,48))
#define GS_MAKE_TEST(ATE,ATST,AREF,AFAIL,DATE,DATM,ZTE,ZTST) \
(BIT64(ATE,0) | BIT64(ATST,1) | BIT64(AREF,4) | BIT64(AFAIL,12) | \
BIT64(DATE,14) | BIT64(DATM,15) | BIT64(ZTE,16) | BIT64(ZTST,17))
#define GS_MAKE_PRIM(PRIM,IIP,TME,FGE,ABE,AA1,FST,CTXT,FIX) \
(BIT64(PRIM,0) | BIT64(IIP,3) | BIT64(TME,4) | BIT64(FGE,5) | \
BIT64(ABE,6) | BIT64(AA1,7) | BIT64(FST,8) | BIT64(CTXT,9) | BIT64(FIX,10))
#define GS_MAKE_RGBAQ(R,G,B,A,Q) \
(BIT64(R,0) | BIT64(G,8) | BIT64(B,16) | BIT64(A,24) | BIT64(Q,32))
#define GS_MAKE_XYZ(X,Y,Z) \
(BIT64(X,0) | BIT64(Y,16) | BIT64(Z,32))
#define GIF_PACKED 0
#define GIF_REGLIST 1
#define GIF_IMAGE 2
#define GIF_MAKE_TAG(NLOOP,EOP,PRE,PRIM,FLG,NREG) \
(BIT64(NLOOP,0) | BIT64(EOP,15) | BIT64(PRE,46) | \
BIT64(PRIM,47) | BIT64(FLG,58) | BIT64(NREG,60))
/* This is global and not tied to a user context because
* it is set up by kernel functions and not really changed
* afterwards. */
typedef struct GsCrtState GsCrtState;
struct GsCrtState
{
short inter, mode, ff;
};
extern GsCrtState gsCrtState;
typedef struct GsDispCtx GsDispCtx;
struct GsDispCtx
{
// two circuits
GsPmode pmode;
GsDispfb dispfb1;
GsDispfb dispfb2;
GsDisplay display1;
GsDisplay display2;
GsBgcolor bgcolor;
};
typedef struct GsDrawCtx GsDrawCtx;
struct GsDrawCtx
{
//two contexts
uint128 gifTag;
GsFrame frame1;
uint64 ad_frame1;
GsFrame frame2;
uint64 ad_frame2;
GsZbuf zbuf1;
uint64 ad_zbuf1;
GsZbuf zbuf2;
uint64 ad_zbuf2;
GsXyOffset xyoffset1;
uint64 ad_xyoffset1;
GsXyOffset xyoffset2;
uint64 ad_xyoffset2;
GsScissor scissor1;
uint64 ad_scissor1;
GsScissor scissor2;
uint64 ad_scissor2;
};
typedef struct GsCtx GsCtx;
struct GsCtx
{
// display context; two buffers
GsDispCtx disp[2];
// draw context; two buffers
GsDrawCtx draw[2];
};

656
tools/ps2test/main.cpp Executable file
View File

@ -0,0 +1,656 @@
#include <cstdio>
#include <cassert>
#include <rw.h>
using rw::uint8;
using rw::uint16;
using rw::uint32;
using rw::uint64;
using rw::int8;
using rw::int16;
using rw::int32;
using rw::int64;
using rw::bool32;
using rw::float32;
typedef uint8 uchar;
typedef uint16 ushort;
typedef uint32 uint;
#define WIDTH 640
#define HEIGHT 448
#include "ps2.h"
// getting undefined references otherwise :/
int *__errno() { return &errno; }
// NONINTERLACED and FRAME have half of the FIELD vertical resolution!
// NONINTERLACED has half the vertical units
uint128 packetbuf[128];
uint128 chainbuf[128];
int frames;
void
printquad(uint128 p)
{
uint64 *lp;
lp = (uint64*)&p;
printf("%016lx %016lx\n", lp[1], lp[0]);
}
struct DmaChannel {
uint32 chcr; uint32 pad0[3];
uint32 madr; uint32 pad1[3];
uint32 qwc; uint32 pad2[3];
uint32 tadr; uint32 pad3[3];
uint32 asr0; uint32 pad4[3];
uint32 asr1; uint32 pad5[3];
uint32 pad6[8];
uint32 sadr;
};
static struct DmaChannel *dmaChannels[] = {
(struct DmaChannel *) &D0_CHCR,
(struct DmaChannel *) &D1_CHCR,
(struct DmaChannel *) &D2_CHCR,
(struct DmaChannel *) &D3_CHCR,
(struct DmaChannel *) &D4_CHCR,
(struct DmaChannel *) &D5_CHCR,
(struct DmaChannel *) &D6_CHCR,
(struct DmaChannel *) &D7_CHCR,
(struct DmaChannel *) &D8_CHCR,
(struct DmaChannel *) &D9_CHCR
};
void
dmaReset(void)
{
/* don't clear the SIF channels */
int doclear[] = { 1, 1, 1, 1, 1, 0, 0, 0, 1, 1 };
int i;
D_CTRL = 0;
for(i = 0; i < 10; i++)
if(doclear[i]){
dmaChannels[i]->chcr = 0;
dmaChannels[i]->madr = 0;
dmaChannels[i]->qwc = 0;
dmaChannels[i]->tadr = 0;
dmaChannels[i]->asr0 = 0;
dmaChannels[i]->asr1 = 0;
dmaChannels[i]->sadr = 0;
}
D_CTRL = 1;
}
void
waitDMA(volatile uint32 *chcr)
{
while(*chcr & (1<<8));
}
void
qwcpy(uint128 *dst, uint128 *src, int n)
{
while(n--) *dst++ = *src++;
}
void
toGIF(void *src, int n)
{
FlushCache(0);
D2_QWC = n;
D2_MADR = (uint32)src;
D2_CHCR = 1<<8;
waitDMA(&D2_CHCR);
}
void
toGIFchain(void *src)
{
FlushCache(0);
D2_QWC = 0;
D2_TADR = (uint32)src & 0x0FFFFFFF;
D2_CHCR = 1<<0 | 1<<2 | 1<<6 | 1<<8;
waitDMA(&D2_CHCR);
}
void
toVIF1chain(void *src)
{
FlushCache(0);
D1_QWC = 0;
D1_TADR = (uint32)src & 0x0FFFFFFF;
D1_CHCR = 1<<0 | 1<<2 | 1<<6 | 1<<8;
waitDMA(&D1_CHCR);
}
GsCrtState gsCrtState;
int psmsizemap[64] = {
4, // GS_PSMCT32
4, // GS_PSMCT24
2, // GS_PSMCT16
0, 0, 0, 0, 0, 0, 0,
2, // GS_PSMCT16S
0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4, // GS_PSMZ32
4, // GS_PSMZ24
2, // GS_PSMZ16
2, // GS_PSMZ16S
0, 0, 0, 0, 0
};
void
GsResetCrt(uchar inter, uchar mode, uchar ff)
{
gsCrtState.inter = inter;
gsCrtState.mode = mode;
gsCrtState.ff = ff;
GS_CSR = 1 << GS_CSR_RESET_O;
__asm__("sync.p; nop");
GsPutIMR(0xff00);
SetGsCrt(gsCrtState.inter, gsCrtState.mode, gsCrtState.ff);
}
uint gsAllocPtr = 0;
void
GsInitDispCtx(GsDispCtx *disp, int width, int height, int psm)
{
int magh, magv;
int dx, dy;
int dw, dh;
dx = gsCrtState.mode == GS_NTSC ? 636 : 656;
dy = gsCrtState.mode == GS_NTSC ? 25 : 36;
magh = 2560/width - 1;
magv = 0;
dw = 2560-1;
dh = height-1;
if(gsCrtState.inter == GS_INTERLACED){
dy *= 2;
if(gsCrtState.ff == GS_FRAME)
dh = (dh+1)*2-1;
}
disp->pmode.d = GS_MAKE_PMODE(0, 1, 1, 1, 0, 0x00);
disp->bgcolor.d = 0x404040;
disp->dispfb1.d = 0;
disp->dispfb2.d = GS_MAKE_DISPFB(0, width/64, psm, 0, 0);
disp->display1.d = 0;
disp->display2.d = GS_MAKE_DISPLAY(dx, dy, magh, magv, dw, dh);
}
void
GsPutDispCtx(GsDispCtx *disp)
{
GS_PMODE = disp->pmode.d;
GS_DISPFB1 = disp->dispfb1.d;
GS_DISPLAY1 = disp->display1.d;
GS_DISPFB2 = disp->dispfb2.d;
GS_DISPLAY2 = disp->display2.d;
GS_BGCOLOR = disp->bgcolor.d;
}
void
GsInitDrawCtx(GsDrawCtx *draw, int width, int height, int psm, int zpsm)
{
MAKE128(draw->gifTag, 0xe,
GIF_MAKE_TAG(8, 1, 0, 0, GIF_PACKED, 1));
draw->frame1.d = GS_MAKE_FRAME(0, width/64, psm, 0);
draw->ad_frame1 = GS_FRAME_1;
draw->frame2.d = draw->frame1.d;
draw->ad_frame2 = GS_FRAME_2;
draw->zbuf1.d = GS_MAKE_ZBUF(0, zpsm, 0);
draw->ad_zbuf1 = GS_ZBUF_1;
draw->zbuf2.d = draw->zbuf1.d;
draw->ad_zbuf2 = GS_ZBUF_2;
draw->xyoffset1.d = GS_MAKE_XYOFFSET(2048<<4, 2048<<4);
draw->ad_xyoffset1 = GS_XYOFFSET_1;
draw->xyoffset2.d = draw->xyoffset1.d;
draw->ad_xyoffset2 = GS_XYOFFSET_2;
draw->scissor1.d = GS_MAKE_SCISSOR(0, width-1, 0, height-1);
draw->ad_scissor1 = GS_SCISSOR_1;
draw->scissor2.d = draw->scissor1.d;
draw->ad_scissor2 = GS_SCISSOR_2;
}
void
GsPutDrawCtx(GsDrawCtx *draw)
{
printquad(*(uint128*)&draw->frame1);
toGIF(draw, 9);
}
void
GsInitCtx(GsCtx *ctx, int width, int height, int psm, int zpsm)
{
uint fbsz, zbsz;
uint fbp, zbp;
fbsz = (width*height*psmsizemap[psm] + 2047)/2048;
zbsz = (width*height*psmsizemap[0x30|zpsm] + 2047)/2048;
gsAllocPtr = 2*fbsz + zbsz;
fbp = fbsz;
zbp = fbsz*2;
GsInitDispCtx(&ctx->disp[0], width, height, psm);
GsInitDispCtx(&ctx->disp[1], width, height, psm);
GsInitDrawCtx(&ctx->draw[0], width, height, psm, zpsm);
GsInitDrawCtx(&ctx->draw[1], width, height, psm, zpsm);
ctx->disp[1].dispfb2.f.FBP = fbp/4;
ctx->draw[0].frame1.f.FBP = fbp/4;
ctx->draw[0].frame2.f.FBP = fbp/4;
ctx->draw[0].zbuf1.f.ZBP = zbp/4;
ctx->draw[0].zbuf2.f.ZBP = zbp/4;
ctx->draw[1].zbuf1.f.ZBP = zbp/4;
ctx->draw[1].zbuf2.f.ZBP = zbp/4;
}
void
initrender(void)
{
uint128 *p, tmp;
p = packetbuf;
MAKE128(tmp, 0xe, GIF_MAKE_TAG(2, 1, 0, 0, GIF_PACKED, 1));
*p++ = tmp;
MAKE128(tmp, GS_PRMODECONT, 1);
*p++ = tmp;
MAKE128(tmp, GS_COLCLAMP, 1);
*p++ = tmp;
toGIF(packetbuf, 3);
}
void
clearscreen(int r, int g, int b)
{
int x, y;
uint128 *p, tmp;
p = packetbuf;
x = (2048 + 640)<<4;
y = (2048 + 448)<<4;
MAKE128(tmp, 0xe, GIF_MAKE_TAG(5, 1, 0, 0, GIF_PACKED, 1));
*p++ = tmp;
MAKE128(tmp, GS_TEST_1, GS_MAKE_TEST(0, 0, 0, 0, 0, 0, 1, 1));
*p++ = tmp;
MAKE128(tmp, GS_PRIM, GS_MAKE_PRIM(GS_PRIM_SPRITE,0,0,0,0,0,0,0,0));
*p++ = tmp;
MAKE128(tmp, GS_RGBAQ, GS_MAKE_RGBAQ(r, g, b, 0, 0));
*p++ = tmp;
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(2048<<4, 2048<<4, 0));
*p++ = tmp;
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x, y, 0));
*p++ = tmp;
toGIF(packetbuf, 6);
}
void
drawtest(void)
{
int x0, x1, x2, x3;
int y0, y1, y2;
uint128 *p, tmp;
int n;
x0 = 2048<<4;
x1 = (2048 + 210)<<4;
x2 = (2048 + 430)<<4;
x3 = (2048 + 640)<<4;
y0 = 2048<<4;
y1 = (2048 + 224)<<4;
y2 = (2048 + 448)<<4;
n = 2 + 3*7;
p = packetbuf;
MAKEQ(tmp, 0x70000000 | n+1, 0, 0, 0);
*p++ = tmp;
MAKE128(tmp, 0xe, GIF_MAKE_TAG(n, 1, 0, 0, GIF_PACKED, 1));
*p++ = tmp;
MAKE128(tmp, GS_TEST_1, GS_MAKE_TEST(0, 0, 0, 0, 0, 0, 1, 1));
*p++ = tmp;
MAKE128(tmp, GS_PRIM, GS_MAKE_PRIM(GS_PRIM_SPRITE,0,0,0,0,0,0,0,0));
*p++ = tmp;
MAKE128(tmp, GS_RGBAQ, GS_MAKE_RGBAQ(255, 0, 0, 0, 0));
*p++ = tmp;
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x0, y0, 0));
*p++ = tmp;
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x1, y1, 0));
*p++ = tmp;
MAKE128(tmp, GS_RGBAQ, GS_MAKE_RGBAQ(0, 255, 0, 0, 0));
*p++ = tmp;
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x1, y0, 0));
*p++ = tmp;
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x2, y1, 0));
*p++ = tmp;
MAKE128(tmp, GS_RGBAQ, GS_MAKE_RGBAQ(0, 0, 255, 0, 0));
*p++ = tmp;
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x2, y0, 0));
*p++ = tmp;
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x3, y1, 0));
*p++ = tmp;
MAKE128(tmp, GS_RGBAQ, GS_MAKE_RGBAQ(0, 255, 255, 0, 0));
*p++ = tmp;
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x0, y1, 0));
*p++ = tmp;
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x1, y2, 0));
*p++ = tmp;
MAKE128(tmp, GS_RGBAQ, GS_MAKE_RGBAQ(255, 0, 255, 0, 0));
*p++ = tmp;
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x1, y1, 0));
*p++ = tmp;
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x2, y2, 0));
*p++ = tmp;
MAKE128(tmp, GS_RGBAQ, GS_MAKE_RGBAQ(255, 255, 0, 0, 0));
*p++ = tmp;
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x2, y1, 0));
*p++ = tmp;
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x3, y2, 0));
*p++ = tmp;
MAKE128(tmp, GS_RGBAQ, GS_MAKE_RGBAQ(255, 255, 255, 0, 0));
*p++ = tmp;
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ((2048+20)<<4, y0, 0));
*p++ = tmp;
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x3, (2048+20)<<4, 0));
*p++ = tmp;
toGIFchain(packetbuf);
}
void
drawtri(void)
{
uint128 *p, tmp;
uint32 *ip;
int nverts, n;
nverts = 3;
n = 2*nverts;
p = packetbuf;
MAKEQ(tmp, 0x70000000 | n+1, 0, 0, 0);
*p++ = tmp;
MAKE128(tmp, (0x5<<4) | 0x1,
GIF_MAKE_TAG(nverts, 1, 1, GS_MAKE_PRIM(GS_PRIM_TRI, 1, 0, 0, 0, 0, 0, 0, 0), GIF_PACKED, 2));
*p++ = tmp;
MAKEQ(tmp, 255, 0, 0, 0);
*p++ = tmp;
MAKEQ(tmp, (2048+85)<<4, (2048+70)<<4, 0, 0);
*p++ = tmp;
MAKEQ(tmp, 0, 255, 0, 0);
*p++ = tmp;
MAKEQ(tmp, (2048+260)<<4, (2048+200)<<4, 0, 0);
*p++ = tmp;
MAKEQ(tmp, 0, 0, 255, 0);
*p++ = tmp;
MAKEQ(tmp, (2048+180)<<4, (2048+350)<<4, 0, 0);
*p++ = tmp;
toGIFchain(packetbuf);
}
rw::Matrix projMat, viewMat, worldMat;
extern uint32 MyDmaPacket[];
extern rw::RawMatrix vuMat;
extern rw::RawMatrix vuLightMat;
extern float vuXYZScale[];
extern float vuXYZOffset[];
extern float vuOffset[];
extern uint64 vuGIFtag[];
extern float vuMatcolor[];
extern float vuSurfProps[];
extern float vuAmbLight[];
extern uint32 vuGeometry[];
extern uint32 mpgCall[];
extern uint32 textureCall[];
extern uint32 geometryCall[];
extern uint32 defaultPipe[];
extern uint32 skinPipe[];
rw::World *world;
rw::Camera *camera;
void
printMatrix(rw::Matrix *m)
{
rw::V3d *x = &m->right;
rw::V3d *y = &m->up;
rw::V3d *z = &m->at;
rw::V3d *w = &m->pos;
printf(
"[ [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"
" [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"
" [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"
" [ %8.4f, %8.4f, %8.4f, %8.4f ] ]\n"
" %08x == flags\n",
x->x, y->x, z->x, w->x,
x->y, y->y, z->y, w->y,
x->z, y->z, z->z, w->z,
0.0f, 0.0f, 0.0f, 1.0f,
m->flags);
}
void
drawAtomic(rw::Atomic *atomic)
{
using namespace rw;
int i;
Geometry *geo;
Matrix *vp;
printf("view matrix\n");
printMatrix(&camera->viewMatrix);
printf("camera matrix\n");
printMatrix(camera->getFrame()->getLTM());
printf("atomic ltm\n");
printMatrix(atomic->getFrame()->getLTM());
/*
RpAtomicPS2AllGetMeshHeaderMeshCache(atomic, ps2AllPipeData);
RpAtomicPS2AllGatherObjMetrics(atomic);
RpAtomicPS2AllMorphSetup(atomic, ps2AllPipeData);
RpAtomicPS2AllObjInstanceTest(atomic, ps2AllPipeData);
RpAtomicPS2AllClear(atomic);
RpAtomicPS2AllTransformSetup(atomic, transform);
RpAtomicPS2AllFrustumTest(atomic, &inFrustum);
RpAtomicPS2AllPrimTypeTransTypeSetup(ps2AllPipeData, inFrustum);
RpAtomicPS2AllMatModulateSetup(atomic, ps2AllPipeData);
RpAtomicPS2AllLightingSetup(ps2AllPipeData);
*/
// Transform Setup
Matrix::mult((Matrix*)&vuMat, atomic->getFrame()->getLTM(), &camera->viewMatrix);
vuMat.rightw = vuMat.right.z;
vuMat.upw = vuMat.up.z;
vuMat.atw = vuMat.at.z;
vuMat.posw = vuMat.pos.z;
*(Matrix*)&vuLightMat = *atomic->getFrame()->getLTM();
vuLightMat.rightw = 0.0f;
vuLightMat.upw = 0.0f;
vuLightMat.atw = 0.0f;
vuLightMat.posw = 1.0f;
geo = atomic->geometry;
if(!(geo->flags & Geometry::NATIVE)){
printf("not instanced!\n");
return;
}
vuAmbLight[0] = 80;
vuAmbLight[1] = 80;
vuAmbLight[2] = 80;
vuAmbLight[3] = 0;
assert(geo->instData != NULL);
rw::ps2::InstanceDataHeader *instData =
(rw::ps2::InstanceDataHeader*)geo->instData;
rw::MeshHeader *meshHeader = geo->meshHeader;
rw::Mesh *mesh;
for(i = 0; i < instData->numMeshes; i++){
geometryCall[1] = (uint32)instData->instanceMeshes[i].data;
vuMatcolor[0] = 1.0f;
vuMatcolor[1] = 1.0f;
vuMatcolor[2] = 1.0f;
vuMatcolor[3] = 1.0f;
vuGIFtag[0] = GIF_MAKE_TAG(0, 1, 1, GS_MAKE_PRIM(GS_PRIM_TRI_STRIP,1,0,0,0,0,0,0,0), GIF_PACKED, 3);
vuGIFtag[1] = 0x412;
geometryCall[3] = 0x020000DC;
mpgCall[1] = (uint32)skinPipe;
// geometryCall[3] = 0x02000114;
// mpgCall[1] = (uint32)defaultPipe;
toVIF1chain(MyDmaPacket);
}
}
void
beginCamera(void)
{
uint128 *p, tmp;
p = packetbuf;
MAKE128(tmp, 0xe, GIF_MAKE_TAG(2, 1, 0, 0, GIF_PACKED, 1));
*p++ = tmp;
MAKE128(tmp, GS_XYOFFSET_1, GS_MAKE_XYOFFSET(2048-WIDTH/2 <<4, 2048-HEIGHT/2 <<4));
*p++ = tmp;
MAKE128(tmp, GS_TEST_1, GS_MAKE_TEST(0, 0, 0, 0, 0, 0, 1, 2));
*p++ = tmp;
toGIF(packetbuf, 3);
vuXYZScale[0] = WIDTH;
vuXYZScale[1] = HEIGHT;
vuXYZScale[2] = camera->zScale;
vuXYZScale[3] = 0.0f;
vuXYZOffset[0] = 2048.0f;
vuXYZOffset[1] = 2048.0f;
vuXYZOffset[2] = camera->zShift;
vuXYZOffset[3] = 0.0f;
}
rw::EngineStartParams engineStartParams;
void
pluginattach(void)
{
rw::ps2::registerPDSPlugin(40);
rw::ps2::registerPluginPDSPipes();
rw::registerMeshPlugin();
rw::registerNativeDataPlugin();
rw::registerAtomicRightsPlugin();
rw::registerMaterialRightsPlugin();
rw::xbox::registerVertexFormatPlugin();
rw::registerSkinPlugin();
rw::registerHAnimPlugin();
rw::registerMatFXPlugin();
rw::registerUVAnimPlugin();
rw::ps2::registerADCPlugin();
}
bool32
initrw(void)
{
rw::version = 0x34000;
rw::platform = rw::PLATFORM_PS2;
if(!rw::Engine::init())
return 0;
pluginattach();
if(!rw::Engine::open())
return 0;
if(!rw::Engine::start(&engineStartParams))
return 0;
rw::engine->loadTextures = 0;
rw::TexDictionary::setCurrent(rw::TexDictionary::create());
rw::Image::setSearchPath(".");
world = rw::World::create();
camera = rw::Camera::create();
camera->setFrame(rw::Frame::create());
rw::V3d t = { 0.0f, 0.0f, -4.0f };
// rw::V3d t = { 0.0f, 0.0f, -40.0f };
camera->getFrame()->translate(&t, rw::COMBINEPOSTCONCAT);
rw::V3d axis = { 0.0f, 1.0f, 0.0f };
camera->getFrame()->rotate(&axis, 40.0f, rw::COMBINEPOSTCONCAT);
camera->setNearPlane(0.1f);
camera->setFarPlane(450.0f);
camera->setFOV(60.0f, 4.0f/3.0f);
world->addCamera(camera);
return 1;
}
int
vsynch(int id)
{
frames++;
ExitHandler();
return 0;
}
int
main()
{
FlushCache(0);
if(!initrw()){
printf("init failed!\n");
for(;;);
}
rw::uint32 len;
rw::uint8 *data = rw::getFileContents("host:player.DFF", &len);
// rw::uint8 *data = rw::getFileContents("host:od_newscafe_dy.dff", &len);
rw::StreamMemory in;
in.open(data, len);
rw::findChunk(&in, rw::ID_CLUMP, NULL, NULL);
rw::Clump *clump = rw::Clump::streamRead(&in);
in.close();
delete[] data;
GsCtx gsCtx;
dmaReset();
// GsResetCrt(GS_NONINTERLACED, GS_NTSC, 0);
// GsInitCtx(&gsCtx, 640, 224, GS_PSMCT32, GS_PSMZ32);
// GsResetCrt(GS_INTERLACED, GS_NTSC, GS_FRAME);
// GsInitCtx(&gsCtx, 640, 224, GS_PSMCT32, GS_PSMZ32);
GsResetCrt(GS_INTERLACED, GS_NTSC, GS_FIELD);
GsInitCtx(&gsCtx, WIDTH, HEIGHT, GS_PSMCT32, GS_PSMZ32);
initrender();
AddIntcHandler(2, vsynch, 0);
EnableIntc(2);
GsPutDrawCtx(&gsCtx.draw[0]);
GsPutDispCtx(&gsCtx.disp[1]);
// PCSX2 needs a delay for some reason
{ int i; for(i = 0; i < 1000000; i++); }
clearscreen(0, 0, 0);
drawtest();
drawtri();
vuOffset[0] = 0.0f;
vuOffset[1] = 0.0f;
camera->beginUpdate();
beginCamera();
FORLIST(lnk, clump->atomics)
drawAtomic(rw::Atomic::fromClump(lnk));
camera->endUpdate();
printf("hello %p\n", clump);
for(;;);
// printf("");
return 0;
}

95
tools/ps2test/mem.h Executable file
View File

@ -0,0 +1,95 @@
/* FIFOs */
#define VIF0_FIFO (*(volatile uint128*)0x10004000)
#define VIF1_FIFO (*(volatile uint128*)0x10005000)
#define GIF_FIFO (*(volatile uint128*)0x10006000)
#define IPU_out_FIFO (*(volatile uint128*)0x10007000)
#define IPU_in_FIFO (*(volatile uint128*)0x10007010)
/* DMA channels */
// to VIF0
#define D0_CHCR (*(volatile uint32*)0x10008000)
#define D0_MADR (*(volatile uint32*)0x10008010)
#define D0_QWC (*(volatile uint32*)0x10008020)
#define D0_TADR (*(volatile uint32*)0x10008030)
#define D0_ASR0 (*(volatile uint32*)0x10008040)
#define D0_ASR1 (*(volatile uint32*)0x10008050)
// VIF1
#define D1_CHCR (*(volatile uint32*)0x10009000)
#define D1_MADR (*(volatile uint32*)0x10009010)
#define D1_QWC (*(volatile uint32*)0x10009020)
#define D1_TADR (*(volatile uint32*)0x10009030)
#define D1_ASR0 (*(volatile uint32*)0x10009040)
#define D1_ASR1 (*(volatile uint32*)0x10009050)
// to GIF
#define D2_CHCR (*(volatile uint32*)0x1000a000)
#define D2_MADR (*(volatile uint32*)0x1000a010)
#define D2_QWC (*(volatile uint32*)0x1000a020)
#define D2_TADR (*(volatile uint32*)0x1000a030)
#define D2_ASR0 (*(volatile uint32*)0x1000a040)
#define D2_ASR1 (*(volatile uint32*)0x1000a050)
// fromIPU
#define D3_CHCR (*(volatile uint32*)0x1000b000)
#define D3_MADR (*(volatile uint32*)0x1000b010)
#define D3_QWC (*(volatile uint32*)0x1000b020)
// toIPU
#define D4_CHCR (*(volatile uint32*)0x1000b400)
#define D4_MADR (*(volatile uint32*)0x1000b410)
#define D4_QWC (*(volatile uint32*)0x1000b420)
#define D4_TADR (*(volatile uint32*)0x1000b430)
// from SIF0
#define D5_CHCR (*(volatile uint32*)0x1000c000)
#define D5_MADR (*(volatile uint32*)0x1000c010)
#define D5_QWC (*(volatile uint32*)0x1000c020)
// to SIF1
#define D6_CHCR (*(volatile uint32*)0x1000c400)
#define D6_MADR (*(volatile uint32*)0x1000c410)
#define D6_QWC (*(volatile uint32*)0x1000c420)
#define D6_TADR (*(volatile uint32*)0x1000c430)
// SIF2
#define D7_CHCR (*(volatile uint32*)0x1000c800)
#define D7_MADR (*(volatile uint32*)0x1000c810)
#define D7_QWC (*(volatile uint32*)0x1000c820)
// fromSPR
#define D8_CHCR (*(volatile uint32*)0x1000d000)
#define D8_MADR (*(volatile uint32*)0x1000d010)
#define D8_QWC (*(volatile uint32*)0x1000d020)
#define D8_SADR (*(volatile uint32*)0x1000d080)
// toSPR
#define D9_CHCR (*(volatile uint32*)0x1000d400)
#define D9_MADR (*(volatile uint32*)0x1000d410)
#define D9_QWC (*(volatile uint32*)0x1000d420)
#define D9_TADR (*(volatile uint32*)0x1000d430)
#define D9_SADR (*(volatile uint32*)0x1000d480)
/* DMA controller */
#define D_CTRL (*(volatile uint32*)0x1000e000)
#define D_STAT (*(volatile uint32*)0x1000e010)
#define D_PCR (*(volatile uint32*)0x1000e020)
#define D_SQWC (*(volatile uint32*)0x1000e030)
#define D_RBSR (*(volatile uint32*)0x1000e040)
#define D_RBOR (*(volatile uint32*)0x1000e050)
#define D_STADR (*(volatile uint32*)0x1000e060)
#define D_ENABLER (*(volatile uint32*)0x1000f520)
#define D_ENABLEW (*(volatile uint32*)0x1000f590)
/* GS privileged registers */
#define GS_PMODE (*(volatile uint64*)0x12000000)
#define GS_SMODE1 (*(volatile uint64*)0x12000010)
#define GS_SMODE2 (*(volatile uint64*)0x12000020)
#define GS_SRFSH (*(volatile uint64*)0x12000030)
#define GS_SYNCH1 (*(volatile uint64*)0x12000040)
#define GS_SYNCH2 (*(volatile uint64*)0x12000050)
#define GS_SYNCV (*(volatile uint64*)0x12000060)
#define GS_DISPFB1 (*(volatile uint64*)0x12000070)
#define GS_DISPLAY1 (*(volatile uint64*)0x12000080)
#define GS_DISPFB2 (*(volatile uint64*)0x12000090)
#define GS_DISPLAY2 (*(volatile uint64*)0x120000a0)
#define GS_EXTBUF (*(volatile uint64*)0x120000b0)
#define GS_EXTDATA (*(volatile uint64*)0x120000c0)
#define GS_EXTWRITE (*(volatile uint64*)0x120000d0)
#define GS_BGCOLOR (*(volatile uint64*)0x120000e0)
#define GS_CSR (*(volatile uint64*)0x12001000)
#define GS_IMR (*(volatile uint64*)0x12001010)
#define GS_BUSDIR (*(volatile uint64*)0x12001040)
#define GS_SIGLBLID (*(volatile uint64*)0x12001080)

23
tools/ps2test/ps2.h Executable file
View File

@ -0,0 +1,23 @@
#include <kernel.h>
typedef int quad __attribute__((mode(TI)));
typedef int int128 __attribute__((mode(TI)));
typedef unsigned int uquad __attribute__((mode(TI)));
typedef unsigned int uint128 __attribute__((mode(TI)));
#define MAKE128(RES,MSB,LSB) \
__asm__ ( "pcpyld %0, %1, %2" : "=r" (RES) : "r" ((uint64)MSB), "r" ((uint64)LSB))
#define UINT64(LOW,HIGH) ((uint64)HIGH<<32 | (uint64)LOW)
#define MAKEQ(RES,W0,W1,W2,W3) MAKE128(RES,UINT64(W2,W3),UINT64(W0,W1))
#define BIT64(v,s) ((uint64)(v) << (s))
#include "mem.h"
#include "gs.h"
extern uint128 packetbuf[128];
void waitDMA(volatile uint32 *chcr);
void toGIF(void *src, int n);
void drawcube(void);

128
tools/ps2test/vu/defaultpipe.dsm Executable file
View File

@ -0,0 +1,128 @@
.global defaultPipe
.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-2)/2)
.equ outBuf2, (outBuf1+outSize)
.equ lightMat, 0x3d0
.equ lightDir, 0x3d4
.equ matrix, 0x3f0
.equ XYZScale, 0x3f7
.equ XYZOffset, 0x3f8
.equ gifTag, 0x3fa
.equ matColor, 0x3fb
.equ ambientLight, 0x3fd
/* This is the the projection matrix we start with:
* 1/2w 0 ox/2w + 1/2 -ox/2w
* 0 -1/2h -oy/2h + 1/2 oy/2h
* 0 0 1 0
* 0 0 1 0
* To get rid of the +1/2 in the combined matrix we
* subtract the z-row/2 from the x- and y-rows.
*
* The z-row is then set to [0 0 0 1] such that multiplication
* by XYZscale gives [0 0 0 zScale]. After perspective division
* and addition of XYZoffset we then get zScale/w + zShift for z.
*
* XYZScale scales xy to the resolution and z by zScale.
* XYZOffset translates xy to the GS coordinate system (where
* [2048, 2048] is the center of the frame buffer) and add zShift to z.
*/
; constant:
; VF28-VF31 transformation matrix
; VF25 XYZ offset
.balign 16,0
defaultPipe:
DMAret *
MPG 0, *
.vu
Start:
SUB.z VF28, VF28, VF28 LOI 0.5 ; right.z = 0
SUB.z VF29, VF29, VF29 LQ VF28, matrix(VI00) ; up.z = 0 - load matrix
SUB.z VF30, VF30, VF30 LQ VF29, matrix+1(VI00) ; at.z = 0 - load matrix
ADDw.z VF31, VF00, VF00 LQ VF30, matrix+2(VI00) ; at.z = 1 - load matrix
NOP LQ VF31, matrix+3(VI00) ; - load matrix
MULi.w VF20, VF28, I LQ.xyz VF01, XYZScale(VI00) ; fix matrix - load scale
MULi.w VF21, VF29, I NOP ; fix matrix
MULi.w VF22, VF30, I NOP ; fix matrix
MULi.w VF23, VF31, I NOP ; fix matrix
SUBw.xy VF28, VF28, VF20 NOP ; fix matrix
SUBw.xy VF29, VF29, VF21 NOP ; fix matrix
SUBw.xy VF30, VF30, VF22 NOP ; fix matrix
SUBw.xy VF31, VF31, VF23 NOP ; fix matrix
MUL.xy VF28, VF28, VF01 LQ.xyz VF25, XYZOffset(VI00) ; scale matrix
MUL.xy VF29, VF29, VF01 IADDIU VI12, VI00, outBuf1 ; scale matrix
MUL.xy VF30, VF30, VF01 IADDIU VI13, VI00, outBuf2 ; scale matrix
MUL.xyz VF31, VF31, VF01 NOP ; scale matrix
Cnt:
NOP XTOP VI02 ; input pointer
NOP LQ VF01, gifTag(VI00)
NOP XITOP VI01 ; vertex count
NOP IADDIU VI05, VI00, 0x4000
NOP IADD VI05, VI05, VI05
NOP IOR VI05, VI05, VI01
NOP SQ VF01, 0(VI12)
NOP ISW.x VI05, 0(VI12)
NOP IADDIU VI03, VI12, 1 ; output pointer
NOP LQ VF18, lightMat(VI00)
NOP LQ VF19, lightMat+1(VI00)
NOP LQ VF20, lightMat+2(VI00)
Loop:
NOP LQI VF01, (VI02++) ; vertex
NOP LQI VF02, (VI02++) ; UV
NOP LQI VF03, (VI02++) ; color
NOP LQI VF04, (VI02++) ; normal
MULAw.xyzw ACC, VF31, VF00w NOP ; transform vertex
MADDAx.xyw ACC, VF28, VF01x NOP
MADDAy.xyw ACC, VF29, VF01y NOP
MADDz.xyzw VF01, VF30, VF01z NOP
ITOF0 VF03, VF03 NOP
ITOF0[I] VF04, VF04 LOI 0.0078125 ; - normal scale
NOP NOP
NOP DIV Q, VF00w, VF01w
NOP WAITQ
MULq VF01, VF01, Q NOP ; perspective division
MULi VF04, VF04, I NOP ; scale normal
NOP MR32.z VF02, VF00
NOP NOP
SUB.w VF01, VF01, VF01 NOP
MULAx.xyz ACC, VF18, VF04x NOP ; transform normal
MADDAy.xyz ACC, VF19, VF04y NOP
MADDz.xyz VF04, VF20, VF04z NOP
ADD.xyz VF01, VF01, VF25 NOP
MULq VF02, VF02, Q NOP
NOP NOP
FTOI0 VF03, VF03 NOP
FTOI4 VF01, VF01 NOP
NOP SQ VF04, -2(VI02) ; store normal
NOP IADDI VI01, VI01, -1
NOP SQI VF02, (VI03++) ; STQ
NOP SQI VF03, (VI03++) ; color
NOP SQI VF01, (VI03++) ; vertex
NOP IBNE VI01, VI00, Loop
NOP NOP
#include "light.vu"
NOP XGKICK VI12
NOP IADD VI15,VI00,VI12
NOP IADD VI12,VI00,VI13
NOP[E] IADD VI13,VI00,VI15
NOP NOP
NOP B Cnt
NOP NOP
.EndMPG
.EndDmaData

94
tools/ps2test/vu/light.vu Executable file
View File

@ -0,0 +1,94 @@
; Ambient light:
NOP LQ VF26, ambientLight(VI00)
NOP XITOP VI01
NOP IADDIU VI03, VI12, 2
Ambloop:
NOP LQ VF03, 0(VI03) ; output color
NOP NOP
NOP NOP
NOP NOP
ITOF0 VF03, VF03 NOP
NOP NOP
NOP NOP
NOP NOP
ADD VF03, VF03, VF26 NOP
NOP NOP
NOP NOP
NOP NOP
FTOI0 VF03, VF03 NOP
NOP IADDI VI01, VI01, -1
NOP IADDIU VI03, VI03, numOutAttribs
NOP IBNE VI01, VI00, Ambloop
NOP SQ VF03, -numOutAttribs(VI03)
; end amblight
; Direct Light
NOP LQ VF26, lightDir(VI00)
NOP XITOP VI01
NOP XTOP VI02
NOP IADDIU VI03, VI12, 2
SUB.xyz VF26, VF00, VF26 NOP
Dirloop:
NOP LQ VF01, 3(VI02); ; normal
NOP LQ VF02, 0(VI03); ; output color
NOP NOP
NOP NOP
MUL VF03, VF01, VF26 NOP
ITOF0 VF02, VF02 NOP
NOP NOP
NOP NOP
ADDy.x VF03, VF03, VF03y NOP
NOP NOP
NOP NOP
NOP NOP
ADDz.x VF03, VF03, VF03z NOP
NOP NOP
NOP NOP
NOP NOP
MAX.x VF03, VF00, VF03 NOP ; clamp to 0
NOP[I] LOI 255
NOP NOP
NOP NOP
MULi.x VF03, VF03, I NOP
NOP NOP
NOP NOP
NOP NOP
ADDx.xyz VF02, VF02, VF03x NOP
NOP NOP
NOP NOP
NOP NOP
FTOI0 VF02, VF02 NOP
NOP IADDI VI01, VI01, -1
NOP IADDIU VI02, VI02, numInAttribs
NOP IADDIU VI03, VI03, numOutAttribs
NOP IBNE VI01, VI00, Dirloop
NOP SQ VF02, -numOutAttribs(VI03)
; end dirlight
; Material color and clamp
NOP LQ VF27, matColor(VI00)
NOP XITOP VI01
NOP IADDIU VI03, VI12, 2
Colorloop:
NOP LQ VF03, 0(VI03)
NOP NOP
NOP NOP
NOP NOP
ITOF0 VF03, VF03 NOP
NOP NOP
NOP NOP
NOP NOP
;; MUL VF03, VF03, VF27 NOP
NOP[I] LOI 255
NOP NOP
NOP NOP
MINIi VF03, VF03, I NOP
NOP NOP
NOP NOP
NOP NOP
FTOI0 VF03, VF03 NOP
NOP IADDI VI01, VI01, -1
NOP IADDIU VI03, VI03, numOutAttribs
NOP IBNE VI01, VI00, Colorloop
NOP SQ VF03, -numOutAttribs(VI03)
; end material color

129
tools/ps2test/vu/skinpipe.dsm Executable file
View File

@ -0,0 +1,129 @@
.global skinPipe
.equ vertexTop, 0x2d0
.equ numInAttribs, 5
.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-2)/2)
.equ outBuf2, (outBuf1+outSize)
.equ lightMat, 0x3d0
.equ lightDir, 0x3d4
.equ matrix, 0x3f0
.equ XYZScale, 0x3f7
.equ XYZOffset, 0x3f8
.equ gifTag, 0x3fa
.equ matColor, 0x3fb
.equ ambientLight, 0x3fd
/* This is the the projection matrix we start with:
* 1/2w 0 ox/2w + 1/2 -ox/2w
* 0 -1/2h -oy/2h + 1/2 oy/2h
* 0 0 1 0
* 0 0 1 0
* To get rid of the +1/2 in the combined matrix we
* subtract the z-row/2 from the x- and y-rows.
*
* The z-row is then set to [0 0 0 1] such that multiplication
* by XYZscale gives [0 0 0 zScale]. After perspective division
* and addition of XYZoffset we then get zScale/w + zShift for z.
*
* XYZScale scales xy to the resolution and z by zScale.
* XYZOffset translates xy to the GS coordinate system (where
* [2048, 2048] is the center of the frame buffer) and add zShift to z.
*/
; constant:
; VF28-VF31 transformation matrix
; VF25 XYZ offset
.balign 16,0
skinPipe:
DMAret *
MPG 0, *
.vu
Start:
SUB.z VF28, VF28, VF28 LOI 0.5 ; right.z = 0
SUB.z VF29, VF29, VF29 LQ VF28, matrix(VI00) ; up.z = 0 - load matrix
SUB.z VF30, VF30, VF30 LQ VF29, matrix+1(VI00) ; at.z = 0 - load matrix
ADDw.z VF31, VF00, VF00 LQ VF30, matrix+2(VI00) ; at.z = 1 - load matrix
NOP LQ VF31, matrix+3(VI00) ; - load matrix
MULi.w VF20, VF28, I LQ.xyz VF01, XYZScale(VI00) ; fix matrix - load scale
MULi.w VF21, VF29, I NOP ; fix matrix
MULi.w VF22, VF30, I NOP ; fix matrix
MULi.w VF23, VF31, I NOP ; fix matrix
SUBw.xy VF28, VF28, VF20 NOP ; fix matrix
SUBw.xy VF29, VF29, VF21 NOP ; fix matrix
SUBw.xy VF30, VF30, VF22 NOP ; fix matrix
SUBw.xy VF31, VF31, VF23 NOP ; fix matrix
MUL.xy VF28, VF28, VF01 LQ.xyz VF25, XYZOffset(VI00) ; scale matrix
MUL.xy VF29, VF29, VF01 IADDIU VI12, VI00, outBuf1 ; scale matrix
MUL.xy VF30, VF30, VF01 IADDIU VI13, VI00, outBuf2 ; scale matrix
MUL.xyz VF31, VF31, VF01 NOP ; scale matrix
Cnt:
NOP XTOP VI02 ; input pointer
NOP LQ VF01, gifTag(VI00)
NOP XITOP VI01 ; vertex count
NOP IADDIU VI05, VI00, 0x4000
NOP IADD VI05, VI05, VI05
NOP IOR VI05, VI05, VI01
NOP SQ VF01, 0(VI12)
NOP ISW.x VI05, 0(VI12)
NOP IADDIU VI03, VI12, 1 ; output pointer
NOP LQ VF18, lightMat(VI00)
NOP LQ VF19, lightMat+1(VI00)
NOP LQ VF20, lightMat+2(VI00)
Loop:
NOP LQI VF01, (VI02++) ; vertex
NOP LQI VF02, (VI02++) ; UV
NOP LQI VF03, (VI02++) ; color
NOP LQI VF04, (VI02++) ; normal
NOP IADDIU VI02, VI02, 1 ; skip weights
MULAw.xyzw ACC, VF31, VF00w NOP ; transform vertex
MADDAx.xyw ACC, VF28, VF01x NOP
MADDAy.xyw ACC, VF29, VF01y NOP
MADDz.xyzw VF01, VF30, VF01z NOP
ITOF0 VF03, VF03 NOP
ITOF0[I] VF04, VF04 LOI 0.0078125 ; - normal scale
NOP NOP
NOP DIV Q, VF00w, VF01w
NOP WAITQ
MULq VF01, VF01, Q NOP ; perspective division
MULi VF04, VF04, I NOP ; scale normal
NOP MR32.z VF02, VF00
NOP NOP
SUB.w VF01, VF01, VF01 NOP
MULAx.xyz ACC, VF18, VF04x NOP ; transform normal
MADDAy.xyz ACC, VF19, VF04y NOP
MADDz.xyz VF04, VF20, VF04z NOP
ADD.xyz VF01, VF01, VF25 NOP
MULq VF02, VF02, Q NOP
NOP NOP
FTOI0 VF03, VF03 NOP
FTOI4 VF01, VF01 NOP
NOP SQ VF04, -2(VI02) ; store normal
NOP IADDI VI01, VI01, -1
NOP SQI VF02, (VI03++) ; STQ
NOP SQI VF03, (VI03++) ; color
NOP SQI VF01, (VI03++) ; vertex
NOP IBNE VI01, VI00, Loop
NOP NOP
#include "light.vu"
NOP XGKICK VI12
NOP IADD VI15,VI00,VI12
NOP IADD VI12,VI00,VI13
NOP[E] IADD VI13,VI00,VI15
NOP NOP
NOP B Cnt
NOP NOP
.EndMPG
.EndDmaData

98
tools/ps2test/vu/vu.dsm Executable file
View File

@ -0,0 +1,98 @@
.data
.global MyDmaPacket
.global vuLightMat
.global vuMat
.global vuXYZScale
.global vuXYZOffset
.global vuOffset
.global vuGIFtag
.global vuMatcolor
.global vuSurfProps
.global vuAmbLight
.global mpgCall
.global textureCall
.global geometryCall
.align 4
MyDmaPacket:
DMAcnt *
.EndDmaData
mpgCall:
DMAcall *, 0 ;vuProg
.EndDmaData
/*
#define vuSDLightOffset 0x3d0
#define vuSDBlockLow 0x3c3
#define vuSDBlockHigh 0x3f0
#define vuSDmat0 vuSDBlockHigh
#define vuSDmat1 vuSDBlockHigh+1
#define vuSDmat2 vuSDBlockHigh+2
#define vuSDmat3 vuSDBlockHigh+3
#define vuSDnearClip vuSDBlockHigh+4
#define vuSDfarClip vuSDBlockHigh+5
#define vuSDxMaxyMax vuSDBlockHigh+6
#define vuSDcamWcamHzScale vuSDBlockHigh+7
#define vuSDoffXoffYzShift vuSDBlockHigh+8
#define vuSDrealOffset vuSDBlockHigh+9
#define vuSDgifTag vuSDBlockHigh+10
#define vuSDcolScale vuSDBlockHigh+11
#define vuSDsurfProps vuSDBlockHigh+12
#define vuSDpingPongAddr vuSDBlockHigh+13
#define vuSDpingPongCount vuSDBlockHigh+14
#define vuSDClipvec1 vuSDBlockHigh+13
#define vuSDClipvec2 vuSDBlockHigh+14
#define vuSDVUSwitch vuSDBlockHigh+15
*/
DMAcnt *
UNPACK 4, 4, V4_32, 0x3d0, *
vuLightMat:
.float 1.0, 0.0, 0.0, 0.0
.float 0.0, 1.0, 0.0, 0.0
.float 0.0, 0.0, 1.0, 0.0
.float 0.0, 0.0, 0.0, 1.0
lightDir:
.float 0.5, -0.5, -0.70710, 0.0
.EndUnpack
UNPACK 4, 4, V4_32, 0x3f0, *
vuMat:
.float 0.0, 0.0, 0.0, 0.0
.float 0.0, 0.0, 0.0, 0.0
.float 0.0, 0.0, 0.0, 0.0
.float 0.0, 0.0, 0.0, 0.0
.EndUnpack
UNPACK 4, 4, V4_32, 0x3f7, *
vuXYZScale:
.float 0.0, 0.0, 0.0, 0.0
vuXYZOffset:
.float 0.0, 0.0, 0.0, 0.0
vuOffset:
.float 0.0, 0.0, 0.0, 0.0
vuGIFtag:
.int 0x00008000, 0x3005C000, 0x0000000412, 0x00000000
vuMatcolor:
.float 1.0, 1.0, 1.0, 0.5
vuSurfProps:
.float 1.0, 1.0, 1.0, 1.0
vuAmbLight:
.float 0, 0, 0, 0
.EndUnpack
.EndDmaData
;;textureCall:
;;DMAcall *, 0
;;.EndDmaData
geometryCall:
DMAcall *, 0 ;vuGeometry
BASE 0
OFFSET 0x0
.EndDmaData
DMAend