librw/tools/ps2test/main.cpp

657 lines
15 KiB
C++
Raw Normal View History

2017-08-12 09:25:25 +01:00
#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;
}