diff --git a/premake5.lua b/premake5.lua index 984fcab..4708dbb 100755 --- a/premake5.lua +++ b/premake5.lua @@ -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" } diff --git a/src/base.cpp b/src/base.cpp old mode 100644 new mode 100755 index b4d71ce..bd263d8 --- a/src/base.cpp +++ b/src/base.cpp @@ -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 diff --git a/src/camera.cpp b/src/camera.cpp old mode 100644 new mode 100755 index 966c43d..363c35f --- a/src/camera.cpp +++ b/src/camera.cpp @@ -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); } } diff --git a/src/d3d/d3ddriver.cpp b/src/d3d/d3ddevice.cpp old mode 100644 new mode 100755 similarity index 100% rename from src/d3d/d3ddriver.cpp rename to src/d3d/d3ddevice.cpp diff --git a/src/engine.cpp b/src/engine.cpp old mode 100644 new mode 100755 index d9d5043..0b7b53a --- a/src/engine.cpp +++ b/src/engine.cpp @@ -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 }; } diff --git a/src/gl/gl3driver.cpp b/src/gl/gl3device.cpp old mode 100644 new mode 100755 similarity index 100% rename from src/gl/gl3driver.cpp rename to src/gl/gl3device.cpp diff --git a/src/matfx.cpp b/src/matfx.cpp old mode 100644 new mode 100755 index 777c065..70bea42 --- a/src/matfx.cpp +++ b/src/matfx.cpp @@ -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++) diff --git a/src/pipeline.cpp b/src/pipeline.cpp old mode 100644 new mode 100755 index 0cd936b..dfe1c75 --- a/src/pipeline.cpp +++ b/src/pipeline.cpp @@ -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))) diff --git a/src/ps2/pds.cpp b/src/ps2/pds.cpp old mode 100644 new mode 100755 index 449a2f4..53d977d --- a/src/ps2/pds.cpp +++ b/src/ps2/pds.cpp @@ -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" diff --git a/src/ps2/ps2.cpp b/src/ps2/ps2.cpp old mode 100644 new mode 100755 index b4a22f6..bd444b3 --- a/src/ps2/ps2.cpp +++ b/src/ps2/ps2.cpp @@ -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) } } } +*/ } } diff --git a/src/ps2/ps2device.cpp b/src/ps2/ps2device.cpp new file mode 100755 index 0000000..f40a9b6 --- /dev/null +++ b/src/ps2/ps2device.cpp @@ -0,0 +1,41 @@ +#ifdef RW_PS2 + +#include +#include +#include +#include + +#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 diff --git a/src/ps2/rwps2.h b/src/ps2/rwps2.h old mode 100644 new mode 100755 index 9a2d930..57f7efc --- a/src/ps2/rwps2.h +++ b/src/ps2/rwps2.h @@ -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 { diff --git a/src/rwengine.h b/src/rwengine.h old mode 100644 new mode 100755 index a1c835c..dd8352d --- a/src/rwengine.h +++ b/src/rwengine.h @@ -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; } diff --git a/src/rwobjects.h b/src/rwobjects.h old mode 100644 new mode 100755 index e18fa70..421a823 --- a/src/rwobjects.h +++ b/src/rwobjects.h @@ -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); diff --git a/src/rwplugins.h b/src/rwplugins.h old mode 100644 new mode 100755 index 111c19d..d0edf9f --- a/src/rwplugins.h +++ b/src/rwplugins.h @@ -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); diff --git a/src/world.cpp b/src/world.cpp old mode 100644 new mode 100755 index 41bad9e..d17def9 --- a/src/world.cpp +++ b/src/world.cpp @@ -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(); } } diff --git a/tools/ps2test/gs.h b/tools/ps2test/gs.h new file mode 100755 index 0000000..361ad8c --- /dev/null +++ b/tools/ps2test/gs.h @@ -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]; +}; diff --git a/tools/ps2test/main.cpp b/tools/ps2test/main.cpp new file mode 100755 index 0000000..5ca95ff --- /dev/null +++ b/tools/ps2test/main.cpp @@ -0,0 +1,656 @@ +#include +#include + +#include +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; +} diff --git a/tools/ps2test/mem.h b/tools/ps2test/mem.h new file mode 100755 index 0000000..088c1d4 --- /dev/null +++ b/tools/ps2test/mem.h @@ -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) diff --git a/tools/ps2test/ps2.h b/tools/ps2test/ps2.h new file mode 100755 index 0000000..86122da --- /dev/null +++ b/tools/ps2test/ps2.h @@ -0,0 +1,23 @@ +#include + +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); diff --git a/tools/ps2test/vu/defaultpipe.dsm b/tools/ps2test/vu/defaultpipe.dsm new file mode 100755 index 0000000..bc971bf --- /dev/null +++ b/tools/ps2test/vu/defaultpipe.dsm @@ -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 diff --git a/tools/ps2test/vu/light.vu b/tools/ps2test/vu/light.vu new file mode 100755 index 0000000..cd941d6 --- /dev/null +++ b/tools/ps2test/vu/light.vu @@ -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 diff --git a/tools/ps2test/vu/skinpipe.dsm b/tools/ps2test/vu/skinpipe.dsm new file mode 100755 index 0000000..a3a8122 --- /dev/null +++ b/tools/ps2test/vu/skinpipe.dsm @@ -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 diff --git a/tools/ps2test/vu/vu.dsm b/tools/ps2test/vu/vu.dsm new file mode 100755 index 0000000..58c10d6 --- /dev/null +++ b/tools/ps2test/vu/vu.dsm @@ -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 +